/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef DEBUG // We want to try and test for LIKE and that consumers are using // escapeStringForLIKE instead of just trusting user input. The idea to // check to see if they are binding a parameter after like instead of just // using a string. We only do this in debug builds because it's expensive! auto c = nsCaseInsensitiveCStringComparator;
nsACString::const_iterator start, end, e;
aSQLStatement.BeginReading(start);
aSQLStatement.EndReading(end);
e = end; while (::FindInReadable(" LIKE"_ns, start, e, c)) { // We have a LIKE in here, so we perform our tests // FindInReadable moves the iterator, so we have to get a new one for // each test we perform.
nsACString::const_iterator s1, s2, s3;
s1 = s2 = s3 = start;
if (!(::FindInReadable(" LIKE ?"_ns, s1, end, c) ||
::FindInReadable(" LIKE :"_ns, s2, end, c) ||
::FindInReadable(" LIKE @"_ns, s3, end, c))) { // At this point, we didn't find a LIKE statement followed by ?, :, // or @, all of which are valid characters for binding a parameter. // We will warn the consumer that they may not be safely using LIKE.
NS_WARNING( "Unsafe use of LIKE detected! Please ensure that you " "are using mozIStorageAsyncStatement::escapeStringForLIKE " "and that you are binding that result to the statement " "to prevent SQL injection attacks.");
}
// resetting start and e
start = e;
e = end;
} #endif
// If we do not have an array object yet, make it. if (!mParamsArray) {
nsCOMPtr<mozIStorageBindingParamsArray> array;
rv = NewBindingParamsArray(getter_AddRefs(array));
NS_ENSURE_SUCCESS(rv, nullptr);
// If there isn't already any rows added, we'll have to add one to use. if (mParamsArray->length() == 0) {
RefPtr<AsyncBindingParams> params(new AsyncBindingParams(mParamsArray));
NS_ENSURE_TRUE(params, nullptr);
// We have to unlock our params because AddParams locks them. This is safe // because no reference to the params object was, or ever will be given out.
params->unlock(nullptr);
// We also want to lock our array at this point - we don't want anything to // be added to it.
mParamsArray->lock();
}
return *mParamsArray->begin();
}
/** * If we are here then we know there are no pending async executions relying on * us (StatementData holds a reference to us; this also goes for our own * AsyncStatementFinalizer which proxies its release to the calling event * target) and so it is always safe to destroy our sqlite3_stmt if one exists. * We can be destroyed on the caller event target by * garbage-collection/reference counting or on the async event target by the * last execution of a statement that already lost its main-thread refs.
*/
AsyncStatement::~AsyncStatement() {
destructorAsyncFinalize();
// If we are getting destroyed on the wrong event target, proxy the connection // release to the right one. if (!IsOnCurrentSerialEventTarget(mDBConnection->eventTargetOpenedOn)) { // NS_ProxyRelase only magic forgets for us if mDBConnection is an // nsCOMPtr. Which it is not; it's a RefPtr.
nsCOMPtr<nsIEventTarget> target(mDBConnection->eventTargetOpenedOn);
NS_ProxyRelease("AsyncStatement::mDBConnection", target,
mDBConnection.forget());
}
}
int AsyncStatement::getAsyncStatement(sqlite3_stmt** _stmt) { #ifdef DEBUG // Make sure we are never called on the connection's owning event target.
NS_ASSERTION(
!IsOnCurrentSerialEventTarget(mDBConnection->eventTargetOpenedOn), "We should only be called on the async event target!"); #endif
nsresult AsyncStatement::getAsynchronousStatementData(StatementData& _data) { if (mFinalized) return NS_ERROR_UNEXPECTED;
// Pass null for the sqlite3_stmt; it will be requested on demand from the // async event target.
_data = StatementData(nullptr, bindingParamsArray(), this);
return NS_OK;
}
already_AddRefed<mozIStorageBindingParams> AsyncStatement::newBindingParams(
mozIStorageBindingParamsArray* aOwner) { if (mFinalized) return nullptr;
// proxy to StorageBaseStatementInternal using its define helper.
MIXIN_IMPL_STORAGEBASESTATEMENTINTERNAL(
AsyncStatement, if (mFinalized) return NS_ERROR_UNEXPECTED;)
NS_IMETHODIMP
AsyncStatement::Finalize() { if (mFinalized) return NS_OK;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.