storage/src/mozStorageStatementParams.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsMemory.h"
     8 #include "nsString.h"
    10 #include "jsapi.h"
    12 #include "mozStoragePrivateHelpers.h"
    13 #include "mozStorageStatementParams.h"
    14 #include "mozIStorageStatement.h"
    16 namespace mozilla {
    17 namespace storage {
    19 ////////////////////////////////////////////////////////////////////////////////
    20 //// StatementParams
    22 StatementParams::StatementParams(mozIStorageStatement *aStatement) :
    23     mStatement(aStatement)
    24 {
    25   NS_ASSERTION(mStatement != nullptr, "mStatement is null");
    26   (void)mStatement->GetParameterCount(&mParamCount);
    27 }
    29 NS_IMPL_ISUPPORTS(
    30   StatementParams,
    31   mozIStorageStatementParams,
    32   nsIXPCScriptable
    33 )
    35 ////////////////////////////////////////////////////////////////////////////////
    36 //// nsIXPCScriptable
    38 #define XPC_MAP_CLASSNAME StatementParams
    39 #define XPC_MAP_QUOTED_CLASSNAME "StatementParams"
    40 #define XPC_MAP_WANT_SETPROPERTY
    41 #define XPC_MAP_WANT_NEWENUMERATE
    42 #define XPC_MAP_WANT_NEWRESOLVE
    43 #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    44 #include "xpc_map_end.h"
    46 NS_IMETHODIMP
    47 StatementParams::SetProperty(nsIXPConnectWrappedNative *aWrapper,
    48                              JSContext *aCtx,
    49                              JSObject *aScopeObj,
    50                              jsid aId,
    51                              JS::Value *_vp,
    52                              bool *_retval)
    53 {
    54   NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
    56   if (JSID_IS_INT(aId)) {
    57     int idx = JSID_TO_INT(aId);
    59     nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
    60     NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
    61     nsresult rv = mStatement->BindByIndex(idx, variant);
    62     NS_ENSURE_SUCCESS(rv, rv);
    63   }
    64   else if (JSID_IS_STRING(aId)) {
    65     JSString *str = JSID_TO_STRING(aId);
    66     size_t length;
    67     const jschar *chars = JS_GetStringCharsAndLength(aCtx, str, &length);
    68     NS_ENSURE_TRUE(chars, NS_ERROR_UNEXPECTED);
    69     NS_ConvertUTF16toUTF8 name(chars, length);
    71     // check to see if there's a parameter with this name
    72     nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
    73     NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
    74     nsresult rv = mStatement->BindByName(name, variant);
    75     NS_ENSURE_SUCCESS(rv, rv);
    76   }
    77   else {
    78     return NS_ERROR_INVALID_ARG;
    79   }
    81   *_retval = true;
    82   return NS_OK;
    83 }
    85 NS_IMETHODIMP
    86 StatementParams::NewEnumerate(nsIXPConnectWrappedNative *aWrapper,
    87                               JSContext *aCtx,
    88                               JSObject *aScopeObj,
    89                               uint32_t aEnumOp,
    90                               jsval *_statep,
    91                               jsid *_idp,
    92                               bool *_retval)
    93 {
    94   NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
    96   switch (aEnumOp) {
    97     case JSENUMERATE_INIT:
    98     case JSENUMERATE_INIT_ALL:
    99     {
   100       // Start our internal index at zero.
   101       *_statep = JSVAL_ZERO;
   103       // And set our length, if needed.
   104       if (_idp)
   105         *_idp = INT_TO_JSID(mParamCount);
   107       break;
   108     }
   109     case JSENUMERATE_NEXT:
   110     {
   111       NS_ASSERTION(*_statep != JSVAL_NULL, "Internal state is null!");
   113       // Make sure we are in range first.
   114       uint32_t index = static_cast<uint32_t>(JSVAL_TO_INT(*_statep));
   115       if (index >= mParamCount) {
   116         *_statep = JSVAL_NULL;
   117         return NS_OK;
   118       }
   120       // Get the name of our parameter.
   121       nsAutoCString name;
   122       nsresult rv = mStatement->GetParameterName(index, name);
   123       NS_ENSURE_SUCCESS(rv, rv);
   125       // But drop the first character, which is going to be a ':'.
   126       JS::RootedString jsname(aCtx, ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
   127                                                         name.Length() - 1));
   128       NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY);
   130       // Set our name.
   131       JS::Rooted<jsid> id(aCtx);
   132       if (!::JS_StringToId(aCtx, jsname, &id)) {
   133         *_retval = false;
   134         return NS_OK;
   135       }
   136       *_idp = id;
   138       // And increment our index.
   139       *_statep = INT_TO_JSVAL(++index);
   141       break;
   142     }
   143     case JSENUMERATE_DESTROY:
   144     {
   145       // Clear our state.
   146       *_statep = JSVAL_NULL;
   148       break;
   149     }
   150   }
   152   return NS_OK;
   153 }
   155 NS_IMETHODIMP
   156 StatementParams::NewResolve(nsIXPConnectWrappedNative *aWrapper,
   157                             JSContext *aCtx,
   158                             JSObject *aScopeObj,
   159                             jsid aId,
   160                             JSObject **_objp,
   161                             bool *_retval)
   162 {
   163   NS_ENSURE_TRUE(mStatement, NS_ERROR_NOT_INITIALIZED);
   164   // We do not throw at any point after this unless our index is out of range
   165   // because we want to allow the prototype chain to be checked for the
   166   // property.
   168   JS::RootedObject scope(aCtx, aScopeObj);
   169   JS::RootedId id(aCtx, aId);
   170   bool resolved = false;
   171   bool ok = true;
   172   if (JSID_IS_INT(id)) {
   173     uint32_t idx = JSID_TO_INT(id);
   175     // Ensure that our index is within range.  We do not care about the
   176     // prototype chain being checked here.
   177     if (idx >= mParamCount)
   178       return NS_ERROR_INVALID_ARG;
   180     ok = ::JS_DefineElement(aCtx, scope, idx, JSVAL_VOID, nullptr,
   181                             nullptr, JSPROP_ENUMERATE);
   182     resolved = true;
   183   }
   184   else if (JSID_IS_STRING(id)) {
   185     JSString *str = JSID_TO_STRING(id);
   186     size_t nameLength;
   187     const jschar *nameChars = JS_GetStringCharsAndLength(aCtx, str, &nameLength);
   188     NS_ENSURE_TRUE(nameChars, NS_ERROR_UNEXPECTED);
   190     // Check to see if there's a parameter with this name, and if not, let
   191     // the rest of the prototype chain be checked.
   192     NS_ConvertUTF16toUTF8 name(nameChars, nameLength);
   193     uint32_t idx;
   194     nsresult rv = mStatement->GetParameterIndex(name, &idx);
   195     if (NS_SUCCEEDED(rv)) {
   196       ok = ::JS_DefinePropertyById(aCtx, scope, id, JSVAL_VOID, nullptr,
   197                                    nullptr, JSPROP_ENUMERATE);
   198       resolved = true;
   199     }
   200   }
   202   *_retval = ok;
   203   *_objp = resolved && ok ? scope.get() : nullptr;
   204   return NS_OK;
   205 }
   207 } // namespace storage
   208 } // namespace mozilla

mercurial