From f3cbbe998521f4bffdc810d5dea92b70cb8c5bcd Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 18 Jan 2018 13:19:06 +0100 Subject: [PATCH] Bug 1422335 - Using a sandbox on main-thread when deserializing data for IDB - part 1 - Deserialize on main-thread using a sandbox, r=asuth --- dom/indexedDB/ActorsParent.cpp | 141 +---------- dom/indexedDB/FileInfo.cpp | 18 ++ dom/indexedDB/FileInfo.h | 3 + dom/indexedDB/IDBObjectStore.cpp | 390 +++++++++++++++++++------------ dom/indexedDB/IDBObjectStore.h | 14 +- 5 files changed, 285 insertions(+), 281 deletions(-) diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index f16dd6f512d7..380d86ce7b6d 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -8028,14 +8028,8 @@ class CreateIndexOp final { friend class VersionChangeTransaction; - class ThreadLocalJSContext; class UpdateIndexDataValuesFunction; - static const unsigned int kBadThreadLocalIndex = - static_cast(-1); - - static unsigned int sThreadLocalIndex; - const IndexMetadata mMetadata; Maybe mMaybeUniqueIndexTable; RefPtr mFileManager; @@ -8110,47 +8104,21 @@ protected: Init(); }; -class CreateIndexOp::ThreadLocalJSContext final - : public NormalJSContext -{ - friend class CreateIndexOp; - friend class nsAutoPtr; - -public: - static ThreadLocalJSContext* - GetOrCreate(); - -private: - ThreadLocalJSContext() - { - MOZ_COUNT_CTOR(CreateIndexOp::ThreadLocalJSContext); - } - - ~ThreadLocalJSContext() - { - MOZ_COUNT_DTOR(CreateIndexOp::ThreadLocalJSContext); - } -}; - class CreateIndexOp::UpdateIndexDataValuesFunction final : public mozIStorageFunction { RefPtr mOp; RefPtr mConnection; - JSContext* mCx; public: UpdateIndexDataValuesFunction(CreateIndexOp* aOp, - DatabaseConnection* aConnection, - JSContext* aCx) + DatabaseConnection* aConnection) : mOp(aOp) , mConnection(aConnection) - , mCx(aCx) { MOZ_ASSERT(aOp); MOZ_ASSERT(aConnection); aConnection->AssertIsOnConnectionThread(); - MOZ_ASSERT(aCx); } NS_DECL_ISUPPORTS @@ -10154,24 +10122,6 @@ SerializeStructuredCloneFiles( return NS_OK; } -already_AddRefed -GetFileForFileInfo(FileInfo* aFileInfo) -{ - FileManager* fileManager = aFileInfo->Manager(); - nsCOMPtr directory = fileManager->GetDirectory(); - if (NS_WARN_IF(!directory)) { - return nullptr; - } - - nsCOMPtr file = fileManager->GetFileForId(directory, - aFileInfo->Id()); - if (NS_WARN_IF(!file)) { - return nullptr; - } - - return file.forget(); -} - /******************************************************************************* * Globals ******************************************************************************/ @@ -19880,7 +19830,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob( MOZ_ASSERT(file.mFileInfo); MOZ_ASSERT(file.mType == StructuredCloneFile::eStructuredClone); - nsCOMPtr nativeFile = GetFileForFileInfo(file.mFileInfo); + nsCOMPtr nativeFile = FileInfo::GetFileForFileInfo(file.mFileInfo); if (NS_WARN_IF(!nativeFile)) { return NS_ERROR_FAILURE; } @@ -24243,7 +24193,7 @@ CreateFileOp::CreateFileOp(Database* aDatabase, nsresult CreateFileOp::CreateMutableFile(MutableFile** aMutableFile) { - nsCOMPtr file = GetFileForFileInfo(mFileInfo); + nsCOMPtr file = FileInfo::GetFileForFileInfo(mFileInfo); if (NS_WARN_IF(!file)) { IDB_REPORT_INTERNAL_ERR(); return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; @@ -24830,8 +24780,6 @@ CreateIndexOp::CreateIndexOp(VersionChangeTransaction* aTransaction, MOZ_ASSERT(!mDatabaseId.IsEmpty()); } -unsigned int CreateIndexOp::sThreadLocalIndex = kBadThreadLocalIndex; - nsresult CreateIndexOp::InsertDataFromObjectStore(DatabaseConnection* aConnection) { @@ -24846,18 +24794,8 @@ CreateIndexOp::InsertDataFromObjectStore(DatabaseConnection* aConnection) aConnection->GetStorageConnection(); MOZ_ASSERT(storageConnection); - ThreadLocalJSContext* context = ThreadLocalJSContext::GetOrCreate(); - if (NS_WARN_IF(!context)) { - IDB_REPORT_INTERNAL_ERR(); - return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; - } - - JSContext* cx = context->Context(); - JSAutoRequest ar(cx); - JSAutoCompartment ac(cx, context->Global()); - RefPtr updateFunction = - new UpdateIndexDataValuesFunction(this, aConnection, cx); + new UpdateIndexDataValuesFunction(this, aConnection); NS_NAMED_LITERAL_CSTRING(updateFunctionName, "update_index_data_values"); @@ -24923,25 +24861,6 @@ CreateIndexOp::Init(TransactionBase* aTransaction) AssertIsOnBackgroundThread(); MOZ_ASSERT(aTransaction); - struct MOZ_STACK_CLASS Helper final - { - static void - Destroy(void* aThreadLocal) - { - delete static_cast(aThreadLocal); - } - }; - - if (sThreadLocalIndex == kBadThreadLocalIndex) { - if (NS_WARN_IF(PR_SUCCESS != - PR_NewThreadPrivateIndex(&sThreadLocalIndex, - &Helper::Destroy))) { - return false; - } - } - - MOZ_ASSERT(sThreadLocalIndex != kBadThreadLocalIndex); - nsresult rv = GetUniqueIndexTableForObjectStore(aTransaction, mObjectStoreId, @@ -25154,34 +25073,6 @@ NormalJSContext::Create() return newContext.forget(); } -// static -auto -CreateIndexOp:: -ThreadLocalJSContext::GetOrCreate() -> ThreadLocalJSContext* -{ - MOZ_ASSERT(!IsOnBackgroundThread()); - MOZ_ASSERT(CreateIndexOp::kBadThreadLocalIndex != - CreateIndexOp::sThreadLocalIndex); - - auto* context = static_cast( - PR_GetThreadPrivate(CreateIndexOp::sThreadLocalIndex)); - if (context) { - return context; - } - - nsAutoPtr newContext(new ThreadLocalJSContext()); - - if (NS_WARN_IF(!newContext->Init())) { - return nullptr; - } - - DebugOnly status = - PR_SetThreadPrivate(CreateIndexOp::sThreadLocalIndex, newContext); - MOZ_ASSERT(status == PR_SUCCESS); - - return newContext.forget(); -} - NS_IMPL_ISUPPORTS(CreateIndexOp::UpdateIndexDataValuesFunction, mozIStorageFunction); @@ -25195,7 +25086,6 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues, MOZ_ASSERT(mConnection); mConnection->AssertIsOnConnectionThread(); MOZ_ASSERT(mOp); - MOZ_ASSERT(mCx); AUTO_PROFILER_LABEL( "CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall", STORAGE); @@ -25235,25 +25125,18 @@ UpdateIndexDataValuesFunction::OnFunctionCall(mozIStorageValueArray* aValues, return rv; } - JS::Rooted clone(mCx); - if (NS_WARN_IF(!IDBObjectStore::DeserializeIndexValue(mCx, - cloneInfo, - &clone))) { - return NS_ERROR_DOM_DATA_CLONE_ERR; - } - const IndexMetadata& metadata = mOp->mMetadata; const int64_t& objectStoreId = mOp->mObjectStoreId; AutoTArray updateInfos; - rv = IDBObjectStore::AppendIndexUpdateInfo(metadata.id(), - metadata.keyPath(), - metadata.unique(), - metadata.multiEntry(), - metadata.locale(), - mCx, - clone, - updateInfos); + rv = IDBObjectStore::DeserializeIndexValueToUpdateInfos( + metadata.id(), + metadata.keyPath(), + metadata.unique(), + metadata.multiEntry(), + metadata.locale(), + cloneInfo, + updateInfos); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/indexedDB/FileInfo.cpp b/dom/indexedDB/FileInfo.cpp index f4f515c20ae6..0e28f6be0803 100644 --- a/dom/indexedDB/FileInfo.cpp +++ b/dom/indexedDB/FileInfo.cpp @@ -256,6 +256,24 @@ CleanupFileRunnable::Run() return NS_OK; } +/* static */ already_AddRefed +FileInfo::GetFileForFileInfo(FileInfo* aFileInfo) +{ + FileManager* fileManager = aFileInfo->Manager(); + nsCOMPtr directory = fileManager->GetDirectory(); + if (NS_WARN_IF(!directory)) { + return nullptr; + } + + nsCOMPtr file = fileManager->GetFileForId(directory, + aFileInfo->Id()); + if (NS_WARN_IF(!file)) { + return nullptr; + } + + return file.forget(); +} + } // namespace indexedDB } // namespace dom } // namespace mozilla diff --git a/dom/indexedDB/FileInfo.h b/dom/indexedDB/FileInfo.h index e228d4ad7234..571994deffb4 100644 --- a/dom/indexedDB/FileInfo.h +++ b/dom/indexedDB/FileInfo.h @@ -69,6 +69,9 @@ public: virtual int64_t Id() const = 0; + static already_AddRefed + GetFileForFileInfo(FileInfo* aFileInfo); + protected: virtual ~FileInfo(); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 6e4bad914b60..246f3bd12443 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -23,14 +23,18 @@ #include "js/Date.h" #include "js/StructuredClone.h" #include "KeyPath.h" +#include "NullPrincipal.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/EndianUtils.h" #include "mozilla/ErrorResult.h" +#include "mozilla/JSObjectHolder.h" #include "mozilla/Move.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/DOMStringList.h" #include "mozilla/dom/File.h" +#include "mozilla/dom/FileBlobImpl.h" #include "mozilla/dom/IDBMutableFileBinding.h" #include "mozilla/dom/BlobBinding.h" #include "mozilla/dom/IDBObjectStoreBinding.h" @@ -41,6 +45,7 @@ #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h" #include "mozilla/ipc/BackgroundChild.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "mozilla/SystemGroup.h" #include "nsCOMPtr.h" #include "nsQueryObject.h" #include "nsStreamUtils.h" @@ -900,7 +905,26 @@ public: aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE || aData.tag == SCTAG_DOM_BLOB); MOZ_ASSERT(aFile.mType == StructuredCloneFile::eBlob); - MOZ_ASSERT(aFile.mBlob); + + RefPtr blob = aFile.mBlob; + + /* If we are creating an index, we do not have an mBlob but do have an + * mInfo. Unlike other index or upgrade cases, we do need a real-looking + * Blob/File instance because the index's key path can reference their + * properties. Rather than create a fake-looking object, create a real + * Blob. */ + if (!blob) { + MOZ_ASSERT(aFile.mFileInfo); + nsCOMPtr file = FileInfo::GetFileForFileInfo(aFile.mFileInfo); + if (!file) { + return false; + } + + + RefPtr impl = new FileBlobImpl(file); + impl->SetFileId(aFile.mFileInfo->Id()); + blob = File::Create(nullptr, impl); + } // It can happen that this IDB is chrome code, so there is no parent, but // still we want to set a correct parent for the new File object. @@ -924,22 +948,22 @@ public: MOZ_ASSERT(parent); if (aData.tag == SCTAG_DOM_BLOB) { - aFile.mBlob->Impl()->SetLazyData( + blob->Impl()->SetLazyData( VoidString(), aData.type, aData.size, INT64_MAX); - MOZ_ASSERT(!aFile.mBlob->IsFile()); + MOZ_ASSERT(!blob->IsFile()); // ActorsParent sends here a kind of half blob and half file wrapped into // a DOM File object. DOM File and DOM Blob are a WebIDL wrapper around a // BlobImpl object. SetLazyData() has just changed the BlobImpl to be a - // Blob (see the previous assert), but 'aFile.mBlob' still has the WebIDL - // DOM File wrapping. + // Blob (see the previous assert), but 'blob' still has the WebIDL DOM + // File wrapping. // Before exposing it to content, we must recreate a DOM Blob object. - RefPtr blob = - Blob::Create(aFile.mBlob->GetParentObject(), aFile.mBlob->Impl()); - MOZ_ASSERT(blob); + RefPtr exposedBlob = + Blob::Create(blob->GetParentObject(), blob->Impl()); + MOZ_ASSERT(exposedBlob); JS::Rooted wrappedBlob(aCx); - if (!ToJSValue(aCx, blob, &wrappedBlob)) { + if (!ToJSValue(aCx, exposedBlob, &wrappedBlob)) { return false; } @@ -947,12 +971,12 @@ public: return true; } - aFile.mBlob->Impl()->SetLazyData( + blob->Impl()->SetLazyData( aData.name, aData.type, aData.size, aData.lastModifiedDate * PR_USEC_PER_MSEC); - MOZ_ASSERT(aFile.mBlob->IsFile()); - RefPtr file = aFile.mBlob->ToFile(); + MOZ_ASSERT(blob->IsFile()); + RefPtr file = blob->ToFile(); MOZ_ASSERT(file); JS::Rooted wrappedFile(aCx); @@ -985,114 +1009,6 @@ public: } }; -class IndexDeserializationHelper -{ -public: - static bool - CreateAndWrapMutableFile(JSContext* aCx, - StructuredCloneFile& aFile, - const MutableFileData& aData, - JS::MutableHandle aResult) - { - // MutableFile can't be used in index creation, so just make a dummy object. - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (NS_WARN_IF(!obj)) { - return false; - } - - aResult.set(obj); - return true; - } - - static bool - CreateAndWrapBlobOrFile(JSContext* aCx, - IDBDatabase* aDatabase, - StructuredCloneFile& aFile, - const BlobOrFileData& aData, - JS::MutableHandle aResult) - { - MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE || - aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE || - aData.tag == SCTAG_DOM_BLOB); - - // The following properties are available for use in index creation - // Blob.size - // Blob.type - // File.name - // File.lastModifiedDate - - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (NS_WARN_IF(!obj)) { - return false; - } - - // Technically these props go on the proto, but this detail won't change - // the results of index creation. - - JS::Rooted type(aCx, - JS_NewUCStringCopyN(aCx, aData.type.get(), aData.type.Length())); - if (NS_WARN_IF(!type)) { - return false; - } - - if (NS_WARN_IF(!JS_DefineProperty(aCx, - obj, - "size", - double(aData.size), - 0))) { - return false; - } - - if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "type", type, 0))) { - return false; - } - - if (aData.tag == SCTAG_DOM_BLOB) { - aResult.set(obj); - return true; - } - - JS::Rooted name(aCx, - JS_NewUCStringCopyN(aCx, aData.name.get(), aData.name.Length())); - if (NS_WARN_IF(!name)) { - return false; - } - - JS::ClippedTime time = JS::TimeClip(aData.lastModifiedDate); - JS::Rooted date(aCx, JS::NewDateObject(aCx, time)); - if (NS_WARN_IF(!date)) { - return false; - } - - if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "name", name, 0))) { - return false; - } - - if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "lastModifiedDate", date, 0))) { - return false; - } - - aResult.set(obj); - return true; - } - - static bool - CreateAndWrapWasmModule(JSContext* aCx, - StructuredCloneFile& aFile, - const WasmModuleData& aData, - JS::MutableHandle aResult) - { - // Wasm module can't be used in index creation, so just make a dummy object. - JS::Rooted obj(aCx, JS_NewPlainObject(aCx)); - if (NS_WARN_IF(!obj)) { - return false; - } - - aResult.set(obj); - return true; - } -}; - // We don't need to upgrade database on B2G. See the comment in ActorsParent.cpp, // UpgradeSchemaFrom18_0To19_0() class UpgradeDeserializationHelper @@ -1460,37 +1376,217 @@ IDBObjectStore::DeserializeValue(JSContext* aCx, return true; } +namespace { + +// This class helps to create only 1 sandbox. +class SandboxHolder final +{ +public: + NS_INLINE_DECL_REFCOUNTING(SandboxHolder) + + static JSObject* + GetSandbox(JSContext* aCx) + { + SandboxHolder* holder = GetOrCreate(); + return holder->GetSandboxInternal(aCx); + } + +private: + ~SandboxHolder() = default; + + static SandboxHolder* + GetOrCreate() + { + MOZ_ASSERT(XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); + + static StaticRefPtr sHolder; + if (!sHolder) { + sHolder = new SandboxHolder(); + ClearOnShutdown(&sHolder); + } + return sHolder; + } + + JSObject* + GetSandboxInternal(JSContext* aCx) + { + if (!mSandbox) { + nsIXPConnect* xpc = nsContentUtils::XPConnect(); + MOZ_ASSERT(xpc, "This should never be null!"); + + // Let's use a null principal. + nsCOMPtr principal = NullPrincipal::Create(); + + JS::Rooted sandbox(aCx); + nsresult rv = xpc->CreateSandbox(aCx, principal, sandbox.address()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + mSandbox = new JSObjectHolder(aCx, sandbox); + } + + return mSandbox->GetJSObject(); + } + + RefPtr mSandbox; +}; + +class DeserializeIndexValueHelper final : public Runnable +{ +public: + DeserializeIndexValueHelper(int64_t aIndexID, + const KeyPath& aKeyPath, + bool aUnique, + bool aMultiEntry, + const nsCString& aLocale, + StructuredCloneReadInfo& aCloneReadInfo, + nsTArray& aUpdateInfoArray) + : Runnable("DeserializeIndexValueHelper") + , mMonitor("DeserializeIndexValueHelper::mMonitor") + , mIndexID(aIndexID) + , mKeyPath(aKeyPath) + , mUnique(aUnique) + , mMultiEntry(aMultiEntry) + , mLocale(aLocale) + , mCloneReadInfo(aCloneReadInfo) + , mUpdateInfoArray(aUpdateInfoArray) + , mStatus(NS_ERROR_FAILURE) + {} + + nsresult + DispatchAndWait() + { + // We don't need to go to the main-thread and use the sandbox. Let's create + // the updateInfo data here. + if (!mCloneReadInfo.mData.Size()) { + AutoJSAPI jsapi; + jsapi.Init(); + + JS::Rooted value(jsapi.cx()); + value.setUndefined(); + + return IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mUnique, + mMultiEntry, mLocale, + jsapi.cx(), value, + mUpdateInfoArray); + } + + // The operation will continue on the main-thread. + + MOZ_ASSERT(!(mCloneReadInfo.mData.Size() % sizeof(uint64_t))); + + MonitorAutoLock lock(mMonitor); + + RefPtr self = this; + nsresult rv = SystemGroup::Dispatch(TaskCategory::Other, self.forget()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + lock.Wait(); + return mStatus; + } + + NS_IMETHOD + Run() override + { + MOZ_ASSERT(NS_IsMainThread()); + + AutoJSAPI jsapi; + jsapi.Init(); + JSContext* cx = jsapi.cx(); + + JS::Rooted global(cx, SandboxHolder::GetSandbox(cx)); + if (NS_WARN_IF(!global)) { + OperationCompleted(NS_ERROR_FAILURE); + return NS_OK; + } + + JSAutoCompartment ac(cx, global); + + JS::Rooted value(cx); + nsresult rv = DeserializeIndexValue(cx, &value); + if (NS_WARN_IF(NS_FAILED(rv))) { + OperationCompleted(rv); + return NS_OK; + } + + rv = IDBObjectStore::AppendIndexUpdateInfo(mIndexID, mKeyPath, mUnique, + mMultiEntry, mLocale, cx, + value, mUpdateInfoArray); + if (NS_WARN_IF(NS_FAILED(rv))) { + OperationCompleted(rv); + return NS_OK; + } + + OperationCompleted(NS_OK); + return NS_OK; + } + +private: + nsresult + DeserializeIndexValue(JSContext* aCx, JS::MutableHandle aValue) + { + static const JSStructuredCloneCallbacks callbacks = { + CommonStructuredCloneReadCallback, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr + }; + + if (!JS_ReadStructuredClone(aCx, mCloneReadInfo.mData, + JS_STRUCTURED_CLONE_VERSION, + JS::StructuredCloneScope::SameProcessSameThread, + aValue, &callbacks, &mCloneReadInfo)) { + return NS_ERROR_DOM_DATA_CLONE_ERR; + } + + return NS_OK; + } + + void + OperationCompleted(nsresult aStatus) + { + mStatus = aStatus; + + MonitorAutoLock lock(mMonitor); + lock.Notify(); + } + + Monitor mMonitor; + + int64_t mIndexID; + const KeyPath& mKeyPath; + bool mUnique; + bool mMultiEntry; + const nsCString mLocale; + StructuredCloneReadInfo& mCloneReadInfo; + nsTArray& mUpdateInfoArray; + nsresult mStatus; +}; + +} // anonymous + // static -bool -IDBObjectStore::DeserializeIndexValue(JSContext* aCx, - StructuredCloneReadInfo& aCloneReadInfo, - JS::MutableHandle aValue) +nsresult +IDBObjectStore::DeserializeIndexValueToUpdateInfos(int64_t aIndexID, + const KeyPath& aKeyPath, + bool aUnique, + bool aMultiEntry, + const nsCString& aLocale, + StructuredCloneReadInfo& aCloneReadInfo, + nsTArray& aUpdateInfoArray) { MOZ_ASSERT(!NS_IsMainThread()); - MOZ_ASSERT(aCx); - if (!aCloneReadInfo.mData.Size()) { - aValue.setUndefined(); - return true; - } - - MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t))); - - JSAutoRequest ar(aCx); - - static const JSStructuredCloneCallbacks callbacks = { - CommonStructuredCloneReadCallback, - nullptr, - nullptr - }; - - if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION, - JS::StructuredCloneScope::SameProcessSameThread, - aValue, &callbacks, &aCloneReadInfo)) { - return false; - } - - return true; + RefPtr helper = + new DeserializeIndexValueHelper(aIndexID, aKeyPath, aUnique, aMultiEntry, + aLocale, aCloneReadInfo, aUpdateInfoArray); + return helper->DispatchAndWait(); } // static diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index 994931afa5e6..272d4b4aa4e5 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -88,6 +88,15 @@ public: JS::Handle aObject, nsTArray& aUpdateInfoArray); + static nsresult + DeserializeIndexValueToUpdateInfos(int64_t aIndexID, + const KeyPath& aKeyPath, + bool aUnique, + bool aMultiEntry, + const nsCString& aLocale, + StructuredCloneReadInfo& aCloneInfo, + nsTArray& aUpdateInfoArray); + static void ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo); @@ -96,11 +105,6 @@ public: StructuredCloneReadInfo& aCloneReadInfo, JS::MutableHandle aValue); - static bool - DeserializeIndexValue(JSContext* aCx, - StructuredCloneReadInfo& aCloneReadInfo, - JS::MutableHandle aValue); - static bool DeserializeUpgradeValue(JSContext* aCx, StructuredCloneReadInfo& aCloneReadInfo,