diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 9721732d4055..16aca4570449 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -2092,6 +2092,7 @@ class TransactionDatabaseOperationBase : public DatabaseOperationBase { class Factory final : public PBackgroundIDBFactoryParent, public AtomicSafeRefCounted { + nsCString mSystemLocale; RefPtr mLoggingInfo; #ifdef DEBUG @@ -2103,7 +2104,7 @@ class Factory final : public PBackgroundIDBFactoryParent, public: [[nodiscard]] static SafeRefPtr Create( - const LoggingInfo& aLoggingInfo); + const LoggingInfo& aLoggingInfo, const nsACString& aSystemLocale); DatabaseLoggingInfo* GetLoggingInfo() const { AssertIsOnBackgroundThread(); @@ -2112,11 +2113,14 @@ class Factory final : public PBackgroundIDBFactoryParent, return mLoggingInfo; } + const nsCString& GetSystemLocale() const { return mSystemLocale; } + MOZ_DECLARE_REFCOUNTED_TYPENAME(mozilla::dom::indexedDB::Factory) MOZ_INLINE_DECL_SAFEREFCOUNTING_INHERITED(Factory, AtomicSafeRefCounted) // Only constructed in Create(). - explicit Factory(RefPtr aLoggingInfo); + Factory(RefPtr aLoggingInfo, + const nsACString& aSystemLocale); // IPDL methods are only called by IPDL. void ActorDestroy(ActorDestroyReason aWhy) override; @@ -6545,7 +6549,7 @@ already_AddRefed MakeConnectionIOTarget() { ******************************************************************************/ already_AddRefed AllocPBackgroundIDBFactoryParent( - const LoggingInfo& aLoggingInfo) { + const LoggingInfo& aLoggingInfo, const nsACString& aSystemLocale) { AssertIsOnBackgroundThread(); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread())) { @@ -6559,15 +6563,15 @@ already_AddRefed AllocPBackgroundIDBFactoryParent( return nullptr; } - SafeRefPtr actor = Factory::Create(aLoggingInfo); + SafeRefPtr actor = Factory::Create(aLoggingInfo, aSystemLocale); MOZ_ASSERT(actor); return actor.forget(); } bool RecvPBackgroundIDBFactoryConstructor( - PBackgroundIDBFactoryParent* aActor, - const LoggingInfo& /* aLoggingInfo */) { + PBackgroundIDBFactoryParent* aActor, const LoggingInfo& /* aLoggingInfo */, + const nsACString& /* aSystemLocale */) { AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread()); @@ -8976,8 +8980,10 @@ DatabaseLoggingInfo::~DatabaseLoggingInfo() { * Factory ******************************************************************************/ -Factory::Factory(RefPtr aLoggingInfo) - : mLoggingInfo(std::move(aLoggingInfo)) +Factory::Factory(RefPtr aLoggingInfo, + const nsACString& aSystemLocale) + : mSystemLocale(aSystemLocale), + mLoggingInfo(std::move(aLoggingInfo)) #ifdef DEBUG , mActorDestroyed(false) @@ -8990,7 +8996,8 @@ Factory::Factory(RefPtr aLoggingInfo) Factory::~Factory() { MOZ_ASSERT(mActorDestroyed); } // static -SafeRefPtr Factory::Create(const LoggingInfo& aLoggingInfo) { +SafeRefPtr Factory::Create(const LoggingInfo& aLoggingInfo, + const nsACString& aSystemLocale) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread()); @@ -9027,7 +9034,7 @@ SafeRefPtr Factory::Create(const LoggingInfo& aLoggingInfo) { return do_AddRef(entry.Data()); }); - return MakeSafeRefPtr(std::move(loggingInfo)); + return MakeSafeRefPtr(std::move(loggingInfo), aSystemLocale); } void Factory::ActorDestroy(ActorDestroyReason aWhy) { @@ -15348,7 +15355,7 @@ nsresult OpenDatabaseOp::LoadDatabaseInformation( QM_TRY_INSPECT( const auto& lastIndexId, - ([&aConnection, + ([this, &aConnection, &objectStores]() -> mozilla::Result { // Load index information QM_TRY_INSPECT( @@ -15365,7 +15372,7 @@ nsresult OpenDatabaseOp::LoadDatabaseInformation( QM_TRY(CollectWhileHasResult( *stmt, - [&lastIndexId, &objectStores, &aConnection, + [this, &lastIndexId, &objectStores, &aConnection, usedIds = Maybe>{}, usedNames = Maybe>{}]( auto& stmt) mutable -> mozilla::Result { @@ -15456,8 +15463,7 @@ nsresult OpenDatabaseOp::LoadDatabaseInformation( indexMetadata->mCommonMetadata.locale(); const bool& isAutoLocale = indexMetadata->mCommonMetadata.autoLocale(); - const nsCString& systemLocale = - IndexedDatabaseManager::GetLocale(); + const nsCString& systemLocale = mFactory->GetSystemLocale(); if (!systemLocale.IsEmpty() && isAutoLocale && !indexedLocale.Equals(systemLocale)) { QM_TRY(MOZ_TO_RESULT(UpdateLocaleAwareIndex( diff --git a/dom/indexedDB/ActorsParent.h b/dom/indexedDB/ActorsParent.h index ab6c6c142ff7..45c0bf8688ef 100644 --- a/dom/indexedDB/ActorsParent.h +++ b/dom/indexedDB/ActorsParent.h @@ -38,10 +38,11 @@ class PBackgroundIDBFactoryParent; class PBackgroundIndexedDBUtilsParent; already_AddRefed AllocPBackgroundIDBFactoryParent( - const LoggingInfo& aLoggingInfo); + const LoggingInfo& aLoggingInfo, const nsACString& aSystemLocale); bool RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor, - const LoggingInfo& aLoggingInfo); + const LoggingInfo& aLoggingInfo, + const nsACString& aSystemLocale); bool DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor); diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index be34e1914da0..5c392393364c 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -242,6 +242,12 @@ Result, nsresult> IDBFactory::CreateForMainThreadJSInternal( return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); } + nsresult rv = mgr->EnsureLocale(); + if (NS_WARN_IF(NS_FAILED(rv))) { + IDB_REPORT_INTERNAL_ERR(); + return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + }; + return CreateInternal(aGlobal, std::move(aPrincipalInfo), /* aInnerWindowID */ 0); } @@ -283,10 +289,17 @@ nsresult IDBFactory::AllowedForWindowInternal( MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); - if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) { + IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate(); + if (NS_WARN_IF(!mgr)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } + nsresult rv = mgr->EnsureLocale(); + if (NS_WARN_IF(NS_FAILED(rv))) { + IDB_REPORT_INTERNAL_ERR(); + return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + }; + StorageAccess access = StorageAllowedForWindow(aWindow); // the factory callsite records whether the browser is in private browsing. @@ -341,10 +354,16 @@ bool IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal, MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aPrincipal); - if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) { + IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate(); + if (NS_WARN_IF(!mgr)) { return false; } + nsresult rv = mgr->EnsureLocale(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + }; + if (aPrincipal->IsSystemPrincipal()) { if (aIsSystemPrincipal) { *aIsSystemPrincipal = true; @@ -641,7 +660,8 @@ RefPtr IDBFactory::OpenInternal( mBackgroundActor = static_cast( backgroundActor->SendPBackgroundIDBFactoryConstructor( - actor, idbThreadLocal->GetLoggingInfo())); + actor, idbThreadLocal->GetLoggingInfo(), + IndexedDatabaseManager::GetLocale())); if (NS_WARN_IF(!mBackgroundActor)) { mBackgroundActorFailed = true; diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 5ee16ec5e924..0558c388263e 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -296,25 +296,6 @@ nsresult IndexedDatabaseManager::Init() { Preferences::RegisterCallbackAndCall(MaxPreloadExtraRecordsPrefChangeCallback, kPrefMaxPreloadExtraRecords); - nsAutoCString acceptLang; - Preferences::GetLocalizedCString("intl.accept_languages", acceptLang); - - // Split values on commas. - for (const auto& lang : - nsCCharSeparatedTokenizer(acceptLang, ',').ToRange()) { - mozilla::intl::LocaleCanonicalizer::Vector asciiString{}; - auto result = mozilla::intl::LocaleCanonicalizer::CanonicalizeICULevel1( - PromiseFlatCString(lang).get(), asciiString); - if (result.isOk()) { - mLocale.AssignASCII(asciiString); - break; - } - } - - if (mLocale.IsEmpty()) { - mLocale.AssignLiteral("en_US"); - } - return NS_OK; } @@ -652,11 +633,37 @@ void IndexedDatabaseManager::LoggingModePrefChangedCallback( } } +nsresult IndexedDatabaseManager::EnsureLocale() { + MOZ_ASSERT(NS_IsMainThread()); + + nsAutoCString acceptLang; + Preferences::GetLocalizedCString("intl.accept_languages", acceptLang); + + // Split values on commas. + for (const auto& lang : + nsCCharSeparatedTokenizer(acceptLang, ',').ToRange()) { + mozilla::intl::LocaleCanonicalizer::Vector asciiString{}; + auto result = mozilla::intl::LocaleCanonicalizer::CanonicalizeICULevel1( + PromiseFlatCString(lang).get(), asciiString); + if (result.isOk()) { + mLocale.AssignASCII(asciiString); + break; + } + } + + if (mLocale.IsEmpty()) { + mLocale.AssignLiteral("en_US"); + } + + return NS_OK; +} + // static const nsCString& IndexedDatabaseManager::GetLocale() { IndexedDatabaseManager* idbManager = Get(); MOZ_ASSERT(idbManager, "IDBManager is not ready!"); + MOZ_ASSERT(!idbManager->mLocale.IsEmpty()); return idbManager->mLocale; } diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 5bf6485aff27..0766143dd605 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -123,6 +123,9 @@ class IndexedDatabaseManager final { nsresult FlushPendingFileDeletions(); + // XXX This extra explicit initialization should go away with bug 1730706. + nsresult EnsureLocale(); + static const nsCString& GetLocale(); static bool ResolveSandboxBinding(JSContext* aCx); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 8f0ddae68b1e..02efb1205382 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -1419,10 +1419,16 @@ nsresult RuntimeService::Init() { Preferences::GetInt(PREF_WORKERS_MAX_PER_DOMAIN, MAX_WORKERS_PER_DOMAIN); gMaxWorkersPerDomain = std::max(0, maxPerDomain); - if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) { + IndexedDatabaseManager* idm = IndexedDatabaseManager::GetOrCreate(); + if (NS_WARN_IF(!idm)) { return NS_ERROR_UNEXPECTED; } + rv = idm->EnsureLocale(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + // PerformanceService must be initialized on the main-thread. PerformanceService::GetOrCreate(); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 78de4adc3a29..a8643981aa96 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -2804,7 +2804,12 @@ nsresult WorkerPrivate::GetLoadInfo( AssertIsOnMainThread(); // Make sure that the IndexedDatabaseManager is set up - Unused << NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate()); + IndexedDatabaseManager* idm = IndexedDatabaseManager::GetOrCreate(); + if (idm) { + Unused << NS_WARN_IF(NS_FAILED(idm->EnsureLocale())); + } else { + NS_WARNING("Failed to get IndexedDatabaseManager!"); + } nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); MOZ_ASSERT(ssm); diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerChild.cpp index a644439a8dd2..feb294f3fc2b 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp @@ -232,7 +232,12 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) { // Ensure that the IndexedDatabaseManager is initialized so that if any // workers do any IndexedDB calls that all of IDB's prefs/etc. are // initialized. - Unused << NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate()); + IndexedDatabaseManager* idm = IndexedDatabaseManager::GetOrCreate(); + if (idm) { + Unused << NS_WARN_IF(NS_FAILED(idm->EnsureLocale())); + } else { + NS_WARNING("Failed to get IndexedDatabaseManager!"); + } auto scopeExit = MakeScopeExit([&] { ExceptionalErrorTransitionDuringExecWorker(); }); diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp index e9d0adbb94ce..140715b84c57 100644 --- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -191,26 +191,28 @@ bool BackgroundParentImpl::DeallocPBackgroundTestParent( } auto BackgroundParentImpl::AllocPBackgroundIDBFactoryParent( - const LoggingInfo& aLoggingInfo) + const LoggingInfo& aLoggingInfo, const nsACString& aSystemLocale) -> already_AddRefed { using mozilla::dom::indexedDB::AllocPBackgroundIDBFactoryParent; AssertIsInMainProcess(); AssertIsOnBackgroundThread(); - return AllocPBackgroundIDBFactoryParent(aLoggingInfo); + return AllocPBackgroundIDBFactoryParent(aLoggingInfo, aSystemLocale); } mozilla::ipc::IPCResult BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor( - PBackgroundIDBFactoryParent* aActor, const LoggingInfo& aLoggingInfo) { + PBackgroundIDBFactoryParent* aActor, const LoggingInfo& aLoggingInfo, + const nsACString& aSystemLocale) { using mozilla::dom::indexedDB::RecvPBackgroundIDBFactoryConstructor; AssertIsInMainProcess(); AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); - if (!RecvPBackgroundIDBFactoryConstructor(aActor, aLoggingInfo)) { + if (!RecvPBackgroundIDBFactoryConstructor(aActor, aLoggingInfo, + aSystemLocale)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK(); diff --git a/ipc/glue/BackgroundParentImpl.h b/ipc/glue/BackgroundParentImpl.h index 42f40a1a2b1f..c36a8c83af4c 100644 --- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -31,11 +31,12 @@ class BackgroundParentImpl : public PBackgroundParent { bool DeallocPBackgroundTestParent(PBackgroundTestParent* aActor) override; already_AddRefed - AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo) override; + AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo, + const nsACString& aSystemLocale) override; mozilla::ipc::IPCResult RecvPBackgroundIDBFactoryConstructor( - PBackgroundIDBFactoryParent* aActor, - const LoggingInfo& aLoggingInfo) override; + PBackgroundIDBFactoryParent* aActor, const LoggingInfo& aLoggingInfo, + const nsACString& aSystemLocale) override; PBackgroundIndexedDBUtilsParent* AllocPBackgroundIndexedDBUtilsParent() override; diff --git a/ipc/glue/PBackground.ipdl b/ipc/glue/PBackground.ipdl index 94b0079ff7fe..d0fe4b173146 100644 --- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -129,7 +129,8 @@ parent: // Only called at startup during mochitests to check the basic infrastructure. async PBackgroundTest(nsCString testArg); - async PBackgroundIDBFactory(LoggingInfo loggingInfo); + async PBackgroundIDBFactory(LoggingInfo loggingInfo, + nsCString systemLocale); async PBackgroundIndexedDBUtils();