Index: branches/2018Q1/www/waterfox/Makefile =================================================================== --- branches/2018Q1/www/waterfox/Makefile (revision 459394) +++ branches/2018Q1/www/waterfox/Makefile (revision 459395) @@ -1,74 +1,74 @@ # $FreeBSD$ PORTNAME= waterfox DISTVERSION= 56.0.3 -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= www ipv6 MAINTAINER= jbeich@FreeBSD.org COMMENT= Distilled fork of Firefox DEPRECATED= Temporary experiment EXPIRATION_DATE=2018-01-30 BUILD_DEPENDS= nspr>=4.16:devel/nspr \ nss>=3.32.1:security/nss \ icu>=59.1,1:devel/icu \ libevent>=2.1.8:devel/libevent \ harfbuzz>=1.4.7:print/harfbuzz \ graphite2>=1.3.10:graphics/graphite2 \ png>=1.6.31:graphics/png \ libvorbis>=1.3.5,3:audio/libvorbis \ libvpx>=1.5.0:multimedia/libvpx \ sqlite3>=3.19.3:databases/sqlite3 \ ${PYTHON_PKGNAMEPREFIX}sqlite3>0:databases/py-sqlite3@${PY_FLAVOR} \ v4l_compat>0:multimedia/v4l_compat \ autoconf-2.13:devel/autoconf213 \ yasm:devel/yasm \ zip:archivers/zip # soundtouch>=1.9.0:audio/soundtouch \ LIB_DEPENDS= libv4l2.so:multimedia/libv4l USE_GITHUB= yes GH_ACCOUNT= MrAlex94 GH_PROJECT= Waterfox USE_GECKO= gecko MOZ_PKGCONFIG_FILES= # empty USE_MOZILLA= -soundtouch MOZILLA_NAME= Waterfox USE_GL= gl WATERFOX_ICON= ${MOZILLA}.png WATERFOX_ICON_SRC= ${PREFIX}/lib/${MOZILLA}/browser/chrome/icons/default/default256.png WATERFOX_DESKTOP= ${MOZSRC}/taskcluster/docker/firefox-snap/firefox.desktop MOZ_OPTIONS= --enable-application=browser \ --with-app-name=${MOZILLA} \ --with-app-basename=${MOZILLA_NAME} \ --with-distribution-id=org.${MOZILLA}project OPTIONS_DEFAULT= BUNDLED_CAIRO .include "${.CURDIR}/../../www/firefox/Makefile.options" post-patch: @${REINPLACE_CMD} -e 's/%u/%U/' -e '/X-MultipleArgs/d' \ -e 's/firefox/${MOZILLA}/' \ -e 's/Firefox/${MOZILLA_NAME}/' \ ${WATERFOX_DESKTOP} @${REINPLACE_CMD} -e 's|%%LOCALBASE%%|${LOCALBASE}|g' \ ${WRKSRC}/browser/app/nsBrowserApp.cpp pre-configure: (cd ${WRKSRC} && ${LOCALBASE}/bin/autoconf-2.13) (cd ${WRKSRC}/js/src/ && ${LOCALBASE}/bin/autoconf-2.13) post-install: ${INSTALL_DATA} ${WATERFOX_DESKTOP} \ ${STAGEDIR}${PREFIX}/share/applications/${MOZILLA}.desktop ${MKDIR} ${STAGEDIR}${PREFIX}/share/pixmaps ${LN} -sf ${WATERFOX_ICON_SRC} ${STAGEDIR}${PREFIX}/share/pixmaps/${WATERFOX_ICON} .include Index: branches/2018Q1/www/waterfox/files/patch-bug1331209 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1331209 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1331209 (revision 459395) @@ -0,0 +1,571 @@ +commit b7088851d6e8 +Author: Jan Varga +Date: Sat Nov 4 23:13:20 2017 +0100 + + Bug 1331209 - Part 2: Fix incorrect FailOnNonOwningThread() calls; r=asuth +--- + dom/asmjscache/AsmJSCache.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index 227bf80f2ac4..ec1e3531fb4f 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -560,13 +560,13 @@ private: + // If shutdown just started, the QuotaManager may have been deleted. + QuotaManager* qm = QuotaManager::Get(); + if (!qm) { +- FailOnNonOwningThread(); ++ Fail(); + return; + } + + nsresult rv = qm->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL); + if (NS_FAILED(rv)) { +- FailOnNonOwningThread(); ++ Fail(); + return; + } + } + +commit ea39dafe977a +Author: Jan Varga +Date: Sat Nov 4 23:13:41 2017 +0100 + + Bug 1331209 - Part 3: Allow sending of the __delete__ message in one direction only; r=asuth +--- + dom/asmjscache/AsmJSCache.cpp | 141 +++++++++++++++++++++++------------ + dom/asmjscache/PAsmJSCacheEntry.ipdl | 20 ++++- + 2 files changed, 111 insertions(+), 50 deletions(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index ec1e3531fb4f..2216149cd762 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -445,7 +445,6 @@ public: + mWriteParams(aWriteParams), + mState(eInitial), + mResult(JS::AsmJSCache_InternalError), +- mDeleteReceived(false), + mActorDestroyed(false), + mOpened(false) + { +@@ -493,12 +492,17 @@ private: + { + AssertIsOnOwningThread(); + MOZ_ASSERT(mState == eOpened); ++ MOZ_ASSERT(mResult == JS::AsmJSCache_Success); + + mState = eFinished; + + MOZ_ASSERT(mOpened); + + FinishOnOwningThread(); ++ ++ if (!mActorDestroyed) { ++ Unused << Send__delete__(this, mResult); ++ } + } + + // This method is called upon any failure that prevents the eventual opening +@@ -508,6 +512,7 @@ private: + { + AssertIsOnOwningThread(); + MOZ_ASSERT(mState != eFinished); ++ MOZ_ASSERT(mResult != JS::AsmJSCache_Success); + + mState = eFinished; + +@@ -515,7 +520,7 @@ private: + + FinishOnOwningThread(); + +- if (!mDeleteReceived && !mActorDestroyed) { ++ if (!mActorDestroyed) { + Unused << Send__delete__(this, mResult); + } + } +@@ -579,26 +584,6 @@ private: + DirectoryLockFailed() override; + + // IPDL methods. +- mozilla::ipc::IPCResult +- Recv__delete__(const JS::AsmJSCacheResult& aResult) override +- { +- AssertIsOnOwningThread(); +- MOZ_ASSERT(mState != eFinished); +- MOZ_ASSERT(!mDeleteReceived); +- +- mDeleteReceived = true; +- +- if (mOpened) { +- Close(); +- } else { +- Fail(); +- } +- +- MOZ_ASSERT(mState == eFinished); +- +- return IPC_OK(); +- } +- + void + ActorDestroy(ActorDestroyReason why) override + { +@@ -624,17 +609,59 @@ private: + } + + mozilla::ipc::IPCResult +- RecvSelectCacheFileToRead(const uint32_t& aModuleIndex) override ++ RecvSelectCacheFileToRead(const OpenMetadataForReadResponse& aResponse) ++ override + { + AssertIsOnOwningThread(); + MOZ_ASSERT(mState == eWaitingToOpenCacheFileForRead); + MOZ_ASSERT(mOpenMode == eOpenForRead); ++ MOZ_ASSERT(!mOpened); ++ ++ switch (aResponse.type()) { ++ case OpenMetadataForReadResponse::TAsmJSCacheResult: { ++ MOZ_ASSERT(aResponse.get_AsmJSCacheResult() != JS::AsmJSCache_Success); ++ ++ mResult = aResponse.get_AsmJSCacheResult(); ++ ++ // This ParentRunnable can only be held alive by the IPDL. Fail() ++ // clears that last reference. So we need to add a self reference here. ++ RefPtr kungFuDeathGrip = this; ++ ++ Fail(); ++ ++ break; ++ } ++ ++ case OpenMetadataForReadResponse::Tuint32_t: ++ // A cache entry has been selected to open. ++ mModuleIndex = aResponse.get_uint32_t(); ++ ++ mState = eReadyToOpenCacheFileForRead; ++ ++ DispatchToIOThread(); ++ ++ break; + +- // A cache entry has been selected to open. ++ default: ++ MOZ_CRASH("Should never get here!"); ++ } ++ ++ return IPC_OK(); ++ } ++ ++ mozilla::ipc::IPCResult ++ RecvClose() override ++ { ++ AssertIsOnOwningThread(); ++ MOZ_ASSERT(mState == eOpened); + +- mModuleIndex = aModuleIndex; +- mState = eReadyToOpenCacheFileForRead; +- DispatchToIOThread(); ++ // This ParentRunnable can only be held alive by the IPDL. Close() clears ++ // that last reference. So we need to add a self reference here. ++ RefPtr kungFuDeathGrip = this; ++ ++ Close(); ++ ++ MOZ_ASSERT(mState == eFinished); + + return IPC_OK(); + } +@@ -675,7 +702,6 @@ private: + State mState; + JS::AsmJSCacheResult mResult; + +- bool mDeleteReceived; + bool mActorDestroyed; + bool mOpened; + }; +@@ -1021,10 +1047,6 @@ ParentRunnable::Run() + + mState = eOpened; + +- // The entry is now open. +- MOZ_ASSERT(!mOpened); +- mOpened = true; +- + FileDescriptor::PlatformHandleType handle = + FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFileDesc)); + if (!SendOnOpenCacheFile(mFileSize, FileDescriptor(handle))) { +@@ -1032,6 +1054,12 @@ ParentRunnable::Run() + return NS_OK; + } + ++ // The entry is now open. ++ MOZ_ASSERT(!mOpened); ++ mOpened = true; ++ ++ mResult = JS::AsmJSCache_Success; ++ + return NS_OK; + } + +@@ -1291,15 +1319,16 @@ private: + MOZ_ASSERT(mState == eOpening); + + uint32_t moduleIndex; +- if (!FindHashMatch(aMetadata, mReadParams, &moduleIndex)) { +- Fail(JS::AsmJSCache_InternalError); +- Send__delete__(this, JS::AsmJSCache_InternalError); +- return IPC_OK(); ++ bool ok; ++ if (FindHashMatch(aMetadata, mReadParams, &moduleIndex)) { ++ ok = SendSelectCacheFileToRead(moduleIndex); ++ } else { ++ ok = SendSelectCacheFileToRead(JS::AsmJSCache_InternalError); + } +- +- if (!SendSelectCacheFileToRead(moduleIndex)) { ++ if (!ok) { + return IPC_FAIL_NO_REASON(this); + } ++ + return IPC_OK(); + } + +@@ -1327,9 +1356,20 @@ private: + Recv__delete__(const JS::AsmJSCacheResult& aResult) override + { + MOZ_ASSERT(NS_IsMainThread()); +- MOZ_ASSERT(mState == eOpening); ++ MOZ_ASSERT(mState == eOpening || mState == eFinishing); ++ MOZ_ASSERT_IF(mState == eOpening, aResult != JS::AsmJSCache_Success); ++ MOZ_ASSERT_IF(mState == eFinishing, aResult == JS::AsmJSCache_Success); + +- Fail(aResult); ++ if (mState == eOpening) { ++ Fail(aResult); ++ } else { ++ // Match the AddRef in BlockUntilOpen(). The IPDL still holds an ++ // outstanding ref which will keep 'this' alive until ActorDestroy() ++ // is executed. ++ Release(); ++ ++ mState = eFinished; ++ } + return IPC_OK(); + } + +@@ -1395,6 +1435,7 @@ private: + eOpening, // Waiting for the parent process to respond + eOpened, // Parent process opened the entry and sent it back + eClosing, // Waiting to be dispatched to the main thread to Send__delete__ ++ eFinishing, // Waiting for the parent process to close + eFinished // Terminal state + }; + State mState; +@@ -1454,28 +1495,32 @@ ChildRunnable::Run() + + // Per FileDescriptorHolder::Finish()'s comment, call before + // releasing the directory lock (which happens in the parent upon receipt +- // of the Send__delete__ message). ++ // of the Close message). + FileDescriptorHolder::Finish(); + + MOZ_ASSERT(mOpened); + mOpened = false; + +- // Match the AddRef in BlockUntilOpen(). The main thread event loop still +- // holds an outstanding ref which will keep 'this' alive until returning to +- // the event loop. +- Release(); ++ if (mActorDestroyed) { ++ // Match the AddRef in BlockUntilOpen(). The main thread event loop ++ // still holds an outstanding ref which will keep 'this' alive until ++ // returning to the event loop. ++ Release(); + +- if (!mActorDestroyed) { +- Unused << Send__delete__(this, JS::AsmJSCache_Success); ++ mState = eFinished; ++ } else { ++ Unused << SendClose(); ++ ++ mState = eFinishing; + } + +- mState = eFinished; + return NS_OK; + } + + case eBackgroundChildPending: + case eOpening: + case eOpened: ++ case eFinishing: + case eFinished: { + MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Shouldn't Run() in this state"); + } +diff --git dom/asmjscache/PAsmJSCacheEntry.ipdl dom/asmjscache/PAsmJSCacheEntry.ipdl +index d16c9284ff9d..bb88a25b5615 100644 +--- dom/asmjscache/PAsmJSCacheEntry.ipdl ++++ dom/asmjscache/PAsmJSCacheEntry.ipdl +@@ -11,6 +11,12 @@ namespace mozilla { + namespace dom { + namespace asmjscache { + ++union OpenMetadataForReadResponse ++{ ++ AsmJSCacheResult; ++ uint32_t; ++}; ++ + protocol PAsmJSCacheEntry + { + manager PBackground; +@@ -21,14 +27,24 @@ protocol PAsmJSCacheEntry + child: + async OnOpenMetadataForRead(Metadata metadata); + parent: +- async SelectCacheFileToRead(uint32_t moduleIndex); ++ async SelectCacheFileToRead(OpenMetadataForReadResponse response); + + child: + // Once the cache file has been opened, the child is notified and sent an + // open file descriptor. + async OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc); + +-both: ++parent: ++ // When the child process is done with the cache entry, the parent process ++ // is notified (via Close). ++ async Close(); ++ ++child: ++ // When there's an error during the opening phase, the child process is ++ // notified (via __delete__) and sent an error result. ++ // When the parent process receives the Close message, it closes the cache ++ // entry on the parent side and the child is notified (via __delete__). ++ // The protocol is destroyed in both cases. + async __delete__(AsmJSCacheResult result); + }; + + +commit 04d80fd8932a +Author: Jan Varga +Date: Sat Nov 4 23:13:51 2017 +0100 + + Bug 1331209 - Part 4: Prevent the state machine from continuing if QM is shutting down or the actor has been destroyed; r=asuth +--- + dom/asmjscache/AsmJSCache.cpp | 97 +++++++++++++++++++++++++++++++++++++------ + 1 file changed, 84 insertions(+), 13 deletions(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index 2216149cd762..7c96bc71ac0a 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -443,6 +443,7 @@ public: + mPrincipalInfo(aPrincipalInfo), + mOpenMode(aOpenMode), + mWriteParams(aWriteParams), ++ mOperationMayProceed(true), + mState(eInitial), + mResult(JS::AsmJSCache_InternalError), + mActorDestroyed(false), +@@ -485,6 +486,22 @@ private: + MOZ_ASSERT(!IsOnOwningThread()); + } + ++ bool ++ IsActorDestroyed() const ++ { ++ AssertIsOnOwningThread(); ++ ++ return mActorDestroyed; ++ } ++ ++ // May be called on any thread, but you should call IsActorDestroyed() if ++ // you know you're on the background thread because it is slightly faster. ++ bool ++ OperationMayProceed() const ++ { ++ return mOperationMayProceed; ++ } ++ + // This method is called on the owning thread when the JS engine is finished + // reading/writing the cache entry. + void +@@ -497,6 +514,7 @@ private: + mState = eFinished; + + MOZ_ASSERT(mOpened); ++ mOpened = false; + + FinishOnOwningThread(); + +@@ -562,13 +580,15 @@ private: + { + AssertIsOnOwningThread(); + +- // If shutdown just started, the QuotaManager may have been deleted. +- QuotaManager* qm = QuotaManager::Get(); +- if (!qm) { ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread()) || ++ IsActorDestroyed()) { + Fail(); + return; + } + ++ QuotaManager* qm = QuotaManager::Get(); ++ MOZ_ASSERT(qm); ++ + nsresult rv = qm->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL); + if (NS_FAILED(rv)) { + Fail(); +@@ -589,23 +609,30 @@ private: + { + AssertIsOnOwningThread(); + MOZ_ASSERT(!mActorDestroyed); ++ MOZ_ASSERT(mOperationMayProceed); + + mActorDestroyed = true; ++ mOperationMayProceed = false; + +- // Assume ActorDestroy can happen at any time, so probe the current state to +- // determine what needs to happen. +- +- if (mState == eFinished) { +- return; +- } ++ // Assume ActorDestroy can happen at any time, so we can't probe the ++ // current state since mState can be modified on any thread (only one ++ // thread at a time based on the state machine). ++ // However we can use mOpened which is only touched on the owning thread. ++ // If mOpened is true, we can also modify mState since we are guaranteed ++ // that there are no pending runnables which would probe mState to decide ++ // what code needs to run (there shouldn't be any running runnables on ++ // other threads either). + + if (mOpened) { + Close(); +- } else { +- Fail(); ++ ++ MOZ_ASSERT(mState == eFinished); + } + +- MOZ_ASSERT(mState == eFinished); ++ // We don't have to call Fail() if mOpened is not true since it means that ++ // either nothing has been initialized yet, so nothing to cleanup or there ++ // are pending runnables that will detect that the actor has been destroyed ++ // and call Fail(). + } + + mozilla::ipc::IPCResult +@@ -617,6 +644,11 @@ private: + MOZ_ASSERT(mOpenMode == eOpenForRead); + MOZ_ASSERT(!mOpened); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread())) { ++ Fail(); ++ return IPC_OK(); ++ } ++ + switch (aResponse.type()) { + case OpenMetadataForReadResponse::TAsmJSCacheResult: { + MOZ_ASSERT(aResponse.get_AsmJSCacheResult() != JS::AsmJSCache_Success); +@@ -682,6 +714,8 @@ private: + nsCOMPtr mMetadataFile; + Metadata mMetadata; + ++ Atomic mOperationMayProceed; ++ + // State initialized during eWaitingToOpenCacheFileForRead + unsigned mModuleIndex; + +@@ -942,6 +976,12 @@ ParentRunnable::Run() + case eInitial: { + MOZ_ASSERT(NS_IsMainThread()); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnNonBackgroundThread()) || ++ !OperationMayProceed()) { ++ FailOnNonOwningThread(); ++ return NS_OK; ++ } ++ + rv = InitOnMainThread(); + if (NS_FAILED(rv)) { + FailOnNonOwningThread(); +@@ -957,7 +997,8 @@ ParentRunnable::Run() + case eWaitingToFinishInit: { + AssertIsOnOwningThread(); + +- if (QuotaManager::IsShuttingDown()) { ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread()) || ++ IsActorDestroyed()) { + Fail(); + return NS_OK; + } +@@ -976,6 +1017,12 @@ ParentRunnable::Run() + case eWaitingToOpenDirectory: { + AssertIsOnOwningThread(); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread()) || ++ IsActorDestroyed()) { ++ Fail(); ++ return NS_OK; ++ } ++ + if (NS_WARN_IF(!QuotaManager::Get())) { + Fail(); + return NS_OK; +@@ -988,6 +1035,12 @@ ParentRunnable::Run() + case eReadyToReadMetadata: { + AssertIsOnIOThread(); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnNonBackgroundThread()) || ++ !OperationMayProceed()) { ++ FailOnNonOwningThread(); ++ return NS_OK; ++ } ++ + rv = ReadMetadata(); + if (NS_FAILED(rv)) { + FailOnNonOwningThread(); +@@ -1016,6 +1069,12 @@ ParentRunnable::Run() + AssertIsOnOwningThread(); + MOZ_ASSERT(mOpenMode == eOpenForRead); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread()) || ++ IsActorDestroyed()) { ++ Fail(); ++ return NS_OK; ++ } ++ + mState = eWaitingToOpenCacheFileForRead; + + // Metadata is now open. +@@ -1031,6 +1090,12 @@ ParentRunnable::Run() + AssertIsOnIOThread(); + MOZ_ASSERT(mOpenMode == eOpenForRead); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnNonBackgroundThread()) || ++ !OperationMayProceed()) { ++ FailOnNonOwningThread(); ++ return NS_OK; ++ } ++ + rv = OpenCacheFileForRead(); + if (NS_FAILED(rv)) { + FailOnNonOwningThread(); +@@ -1045,6 +1110,12 @@ ParentRunnable::Run() + case eSendingCacheFile: { + AssertIsOnOwningThread(); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread()) || ++ IsActorDestroyed()) { ++ Fail(); ++ return NS_OK; ++ } ++ + mState = eOpened; + + FileDescriptor::PlatformHandleType handle = Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1331209 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1389561 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1389561 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1389561 (revision 459395) @@ -0,0 +1,758 @@ +commit 06e22a681925 +Author: Shawn Huang +Date: Thu Oct 26 16:59:18 2017 +0800 + + Bug 1389561 - Part 1: Ensure origin initialized in Maintenance::DirectoryWork. r=janv + + Make sure origins had been initialized in Maintenance::DirectoryWork before getting + QuotaObject. It's possible that DatabaseMaintenance::Run before origins initialized. +--- + dom/indexedDB/ActorsParent.cpp | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git dom/indexedDB/ActorsParent.cpp dom/indexedDB/ActorsParent.cpp +index de613cc4eec0..06ffc9df84fa 100644 +--- dom/indexedDB/ActorsParent.cpp ++++ dom/indexedDB/ActorsParent.cpp +@@ -18602,6 +18602,7 @@ Maintenance::DirectoryWork() + continue; + } + ++ nsCString suffix; + nsCString group; + nsCString origin; + nsTArray databasePaths; +@@ -18659,17 +18660,17 @@ Maintenance::DirectoryWork() + + // Found a database. + if (databasePaths.IsEmpty()) { ++ MOZ_ASSERT(suffix.IsEmpty()); + MOZ_ASSERT(group.IsEmpty()); + MOZ_ASSERT(origin.IsEmpty()); + + int64_t dummyTimeStamp; + bool dummyPersisted; +- nsCString dummySuffix; + if (NS_WARN_IF(NS_FAILED( + quotaManager->GetDirectoryMetadata2(originDir, + &dummyTimeStamp, + &dummyPersisted, +- dummySuffix, ++ suffix, + group, + origin)))) { + // Not much we can do here... +@@ -18687,6 +18688,21 @@ Maintenance::DirectoryWork() + group, + origin, + Move(databasePaths))); ++ ++ nsCOMPtr directory; ++ ++ // Idle maintenance may occur before origin is initailized. ++ // Ensure origin is initialized first. It will initialize all origins ++ // for temporary storage including IDB origins. ++ rv = quotaManager->EnsureOriginIsInitialized(persistenceType, ++ suffix, ++ group, ++ origin, ++ getter_AddRefs(directory)); ++ ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + } + } + } +commit a9f850009e15 +Author: Shawn Huang +Date: Thu Nov 2 14:54:07 2017 +0800 + + Bug 1389561 - Part 2: Wait for idle maintenance releasing DirectoryLock when finished. r=janv +--- + dom/indexedDB/ActorsParent.cpp | 68 +++++++++++++++++++++++++++++++----------- + 1 file changed, 51 insertions(+), 17 deletions(-) + +diff --git dom/indexedDB/ActorsParent.cpp dom/indexedDB/ActorsParent.cpp +index 47d621909119..cf3d32ef8fff 100644 +--- dom/indexedDB/ActorsParent.cpp ++++ dom/indexedDB/ActorsParent.cpp +@@ -17984,11 +17984,22 @@ QuotaClient::ShutdownWorkThreads() + + mShutdownRequested = true; + ++ // Shutdown maintenance thread pool (this spins the event loop until all ++ // threads are gone). This should release any maintenance related quota ++ // objects. + if (mMaintenanceThreadPool) { + mMaintenanceThreadPool->Shutdown(); + mMaintenanceThreadPool = nullptr; + } + ++ // Let any runnables dispatched from dying maintenance threads to be ++ // processed. This should release any maintenance related directory locks. ++ if (mCurrentMaintenance) { ++ MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { ++ return !mCurrentMaintenance; ++ })); ++ } ++ + RefPtr connectionPool = gConnectionPool.get(); + if (connectionPool) { + connectionPool->Shutdown(); +@@ -18312,7 +18323,8 @@ Maintenance::Start() + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mState == State::Initial); + +- if (IsAborted()) { ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || ++ IsAborted()) { + return NS_ERROR_ABORT; + } + +@@ -18336,7 +18348,8 @@ Maintenance::CreateIndexedDatabaseManager() + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager); + +- if (IsAborted()) { ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ IsAborted()) { + return NS_ERROR_ABORT; + } + +@@ -18361,7 +18374,8 @@ Maintenance::OpenDirectory() + MOZ_ASSERT(!mDirectoryLock); + MOZ_ASSERT(QuotaManager::Get()); + +- if (IsAborted()) { ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || ++ IsAborted()) { + return NS_ERROR_ABORT; + } + +@@ -18385,7 +18399,8 @@ Maintenance::DirectoryOpen() + MOZ_ASSERT(mState == State::DirectoryOpenPending); + MOZ_ASSERT(mDirectoryLock); + +- if (IsAborted()) { ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || ++ IsAborted()) { + return NS_ERROR_ABORT; + } + +@@ -18415,7 +18430,8 @@ Maintenance::DirectoryWork() + // We have to find all database files that match any persistence type and any + // origin. We ignore anything out of the ordinary for now. + +- if (IsAborted()) { ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ IsAborted()) { + return NS_ERROR_ABORT; + } + +@@ -18754,6 +18770,11 @@ Maintenance::BeginDatabaseMaintenance() + } + }; + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) || ++ IsAborted()) { ++ return NS_ERROR_ABORT; ++ } ++ + RefPtr threadPool; + + for (DirectoryInfo& directoryInfo : mDirectoryInfos) { +@@ -18940,6 +18961,11 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() + } + }; + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ mMaintenance->IsAborted()) { ++ return; ++ } ++ + nsCOMPtr databaseFile = GetFileForPath(mDatabasePath); + MOZ_ASSERT(databaseFile); + +@@ -18956,10 +18982,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() + + AutoClose autoClose(connection); + +- if (mMaintenance->IsAborted()) { +- return; +- } +- + AutoProgressHandler progressHandler(mMaintenance); + if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) { + return; +@@ -18978,20 +19000,12 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase() + return; + } + +- if (mMaintenance->IsAborted()) { +- return; +- } +- + MaintenanceAction maintenanceAction; + rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + +- if (mMaintenance->IsAborted()) { +- return; +- } +- + switch (maintenanceAction) { + case MaintenanceAction::Nothing: + break; +@@ -19018,6 +19032,11 @@ DatabaseMaintenance::CheckIntegrity(mozIStorageConnection* aConnection, + MOZ_ASSERT(aConnection); + MOZ_ASSERT(aOk); + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ mMaintenance->IsAborted()) { ++ return NS_ERROR_ABORT; ++ } ++ + nsresult rv; + + // First do a full integrity_check. Scope statements tightly here because +@@ -19135,6 +19154,11 @@ DatabaseMaintenance::DetermineMaintenanceAction( + MOZ_ASSERT(aDatabaseFile); + MOZ_ASSERT(aMaintenanceAction); + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ mMaintenance->IsAborted()) { ++ return NS_ERROR_ABORT; ++ } ++ + int32_t schemaVersion; + nsresult rv = aConnection->GetSchemaVersion(&schemaVersion); + if (NS_WARN_IF(NS_FAILED(rv))) { +@@ -19344,6 +19368,11 @@ DatabaseMaintenance::IncrementalVacuum(mozIStorageConnection* aConnection) + MOZ_ASSERT(!IsOnBackgroundThread()); + MOZ_ASSERT(aConnection); + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ mMaintenance->IsAborted()) { ++ return; ++ } ++ + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( + "PRAGMA incremental_vacuum;" + )); +@@ -19361,6 +19390,11 @@ DatabaseMaintenance::FullVacuum(mozIStorageConnection* aConnection, + MOZ_ASSERT(aConnection); + MOZ_ASSERT(aDatabaseFile); + ++ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || ++ mMaintenance->IsAborted()) { ++ return; ++ } ++ + nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( + "VACUUM;" + )); +commit 5d30f2130fd9 +Author: Shawn Huang +Date: Wed Nov 1 11:14:20 2017 +0800 + + Bug 1389561 - Part 3: Wait for releasing all AsmJSCache parent actors in Client::ShutdownWorkThreads(). r=janv + + This patch implements Client::ShutdownWorkThreads for taking care of unreleased DirectoryLock and QuotaObject objects. +--- + dom/asmjscache/AsmJSCache.cpp | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index 22ab3dbf0136..49a7d6974134 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -67,6 +67,8 @@ namespace asmjscache { + + namespace { + ++class ParentRunnable; ++ + // Anything smaller should compile fast enough that caching will just add + // overhead. + static const size_t sMinCachedModuleLength = 10000; +@@ -74,6 +76,10 @@ static const size_t sMinCachedModuleLength = 10000; + // The number of characters to hash into the Metadata::Entry::mFastHash. + static const unsigned sNumFastHashChars = 4096; + ++// Track all live parent actors. ++typedef nsTArray ParentActorArray; ++StaticAutoPtr sLiveParentActors; ++ + nsresult + WriteMetadataFile(nsIFile* aMetadataFile, const Metadata& aMetadata) + { +@@ -802,6 +808,13 @@ ParentRunnable::FinishOnOwningThread() + FileDescriptorHolder::Finish(); + + mDirectoryLock = nullptr; ++ ++ MOZ_ASSERT(sLiveParentActors); ++ sLiveParentActors->RemoveElement(this); ++ ++ if (sLiveParentActors->IsEmpty()) { ++ sLiveParentActors = nullptr; ++ } + } + + NS_IMETHODIMP +@@ -1039,6 +1052,12 @@ AllocEntryParent(OpenMode aOpenMode, + RefPtr runnable = + new ParentRunnable(aPrincipalInfo, aOpenMode, aWriteParams); + ++ if (!sLiveParentActors) { ++ sLiveParentActors = new ParentActorArray(); ++ } ++ ++ sLiveParentActors->AppendElement(runnable); ++ + nsresult rv = NS_DispatchToMainThread(runnable); + NS_ENSURE_SUCCESS(rv, nullptr); + +@@ -1687,7 +1706,15 @@ public: + + void + ShutdownWorkThreads() override +- { } ++ { ++ AssertIsOnBackgroundThread(); ++ ++ if (sLiveParentActors) { ++ MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { ++ return !sLiveParentActors; ++ })); ++ } ++ } + + private: + nsAutoRefCnt mRefCnt; +commit 0693fefe1317 +Author: Jan Varga +Date: Thu Nov 2 14:54:18 2017 +0800 + + Bug 1389561 - Part 4: Split AsmJSCache's Client implementation into declaration and definition; r=luke +--- + dom/asmjscache/AsmJSCache.cpp | 271 +++++++++++++++++++++++++----------------- + 1 file changed, 165 insertions(+), 106 deletions(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index 49a7d6974134..1ba4f66085a1 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -240,6 +240,60 @@ EvictEntries(nsIFile* aDirectory, const nsACString& aGroup, + } + } + ++/******************************************************************************* ++ * Client ++ ******************************************************************************/ ++ ++class Client ++ : public quota::Client ++{ ++public: ++ NS_INLINE_DECL_REFCOUNTING(Client, override) ++ ++ Type ++ GetType() override; ++ ++ nsresult ++ InitOrigin(PersistenceType aPersistenceType, ++ const nsACString& aGroup, ++ const nsACString& aOrigin, ++ const AtomicBool& aCanceled, ++ UsageInfo* aUsageInfo) override; ++ ++ nsresult ++ GetUsageForOrigin(PersistenceType aPersistenceType, ++ const nsACString& aGroup, ++ const nsACString& aOrigin, ++ const AtomicBool& aCanceled, ++ UsageInfo* aUsageInfo) override; ++ ++ void ++ OnOriginClearCompleted(PersistenceType aPersistenceType, ++ const nsACString& aOrigin) ++ override; ++ ++ void ++ ReleaseIOThreadObjects() override; ++ ++ void ++ AbortOperations(const nsACString& aOrigin) override; ++ ++ void ++ AbortOperationsForProcess(ContentParentId aContentParentId) override; ++ ++ void ++ StartIdleMaintenance() override; ++ ++ void ++ StopIdleMaintenance() override; ++ ++ void ++ ShutdownWorkThreads() override; ++ ++private: ++ ~Client() override = default; ++}; ++ + // FileDescriptorHolder owns a file descriptor and its memory mapping. + // FileDescriptorHolder is derived by two runnable classes (that is, + // (Parent|Child)Runnable. +@@ -1593,136 +1647,141 @@ CloseEntryForWrite(size_t aSize, + } + } + +-class Client : public quota::Client +-{ +- ~Client() override = default; ++/******************************************************************************* ++ * Client ++ ******************************************************************************/ + +-public: +- NS_IMETHOD_(MozExternalRefCountType) +- AddRef() override; +- +- NS_IMETHOD_(MozExternalRefCountType) +- Release() override; +- +- Type +- GetType() override +- { +- return ASMJS; +- } ++Client::Type ++Client::GetType() ++{ ++ return ASMJS; ++} + +- nsresult +- InitOrigin(PersistenceType aPersistenceType, +- const nsACString& aGroup, +- const nsACString& aOrigin, +- const AtomicBool& aCanceled, +- UsageInfo* aUsageInfo) override +- { +- if (!aUsageInfo) { +- return NS_OK; +- } +- return GetUsageForOrigin(aPersistenceType, +- aGroup, +- aOrigin, +- aCanceled, +- aUsageInfo); ++nsresult ++Client::InitOrigin(PersistenceType aPersistenceType, ++ const nsACString& aGroup, ++ const nsACString& aOrigin, ++ const AtomicBool& aCanceled, ++ UsageInfo* aUsageInfo) ++{ ++ if (!aUsageInfo) { ++ return NS_OK; + } ++ return GetUsageForOrigin(aPersistenceType, ++ aGroup, ++ aOrigin, ++ aCanceled, ++ aUsageInfo); ++} + +- nsresult +- GetUsageForOrigin(PersistenceType aPersistenceType, +- const nsACString& aGroup, +- const nsACString& aOrigin, +- const AtomicBool& aCanceled, +- UsageInfo* aUsageInfo) override +- { +- QuotaManager* qm = QuotaManager::Get(); +- MOZ_ASSERT(qm, "We were being called by the QuotaManager"); +- +- nsCOMPtr directory; +- nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin, +- getter_AddRefs(directory)); +- NS_ENSURE_SUCCESS(rv, rv); +- MOZ_ASSERT(directory, "We're here because the origin directory exists"); ++nsresult ++Client::GetUsageForOrigin(PersistenceType aPersistenceType, ++ const nsACString& aGroup, ++ const nsACString& aOrigin, ++ const AtomicBool& aCanceled, ++ UsageInfo* aUsageInfo) ++{ ++ QuotaManager* qm = QuotaManager::Get(); ++ MOZ_ASSERT(qm, "We were being called by the QuotaManager"); + +- rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME)); +- NS_ENSURE_SUCCESS(rv, rv); ++ nsCOMPtr directory; ++ nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin, ++ getter_AddRefs(directory)); ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + +- DebugOnly exists; +- MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists); ++ MOZ_ASSERT(directory, "We're here because the origin directory exists"); + +- nsCOMPtr entries; +- rv = directory->GetDirectoryEntries(getter_AddRefs(entries)); +- NS_ENSURE_SUCCESS(rv, rv); ++ rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME)); ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + +- bool hasMore; +- while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) && +- hasMore && !aCanceled) { +- nsCOMPtr entry; +- rv = entries->GetNext(getter_AddRefs(entry)); +- NS_ENSURE_SUCCESS(rv, rv); ++ DebugOnly exists; ++ MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists); + +- nsCOMPtr file = do_QueryInterface(entry); +- NS_ENSURE_TRUE(file, NS_NOINTERFACE); ++ nsCOMPtr entries; ++ rv = directory->GetDirectoryEntries(getter_AddRefs(entries)); ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + +- int64_t fileSize; +- rv = file->GetFileSize(&fileSize); +- NS_ENSURE_SUCCESS(rv, rv); ++ bool hasMore; ++ while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) && ++ hasMore && !aCanceled) { ++ nsCOMPtr entry; ++ rv = entries->GetNext(getter_AddRefs(entry)); ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + +- MOZ_ASSERT(fileSize >= 0, "Negative size?!"); ++ nsCOMPtr file = do_QueryInterface(entry); ++ if (NS_WARN_IF(!file)) { ++ return NS_NOINTERFACE; ++ } + +- // Since the client is not explicitly storing files, append to database +- // usage which represents implicit storage allocation. +- aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize)); ++ int64_t fileSize; ++ rv = file->GetFileSize(&fileSize); ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; + } +- NS_ENSURE_SUCCESS(rv, rv); + +- return NS_OK; +- } ++ MOZ_ASSERT(fileSize >= 0, "Negative size?!"); + +- void +- OnOriginClearCompleted(PersistenceType aPersistenceType, +- const nsACString& aOrigin) +- override +- { } ++ // Since the client is not explicitly storing files, append to database ++ // usage which represents implicit storage allocation. ++ aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize)); ++ } ++ if (NS_WARN_IF(NS_FAILED(rv))) { ++ return rv; ++ } + +- void +- ReleaseIOThreadObjects() override +- { } ++ return NS_OK; ++} + +- void +- AbortOperations(const nsACString& aOrigin) override +- { } ++void ++Client::OnOriginClearCompleted(PersistenceType aPersistenceType, ++ const nsACString& aOrigin) ++{ ++} + +- void +- AbortOperationsForProcess(ContentParentId aContentParentId) override +- { } ++void ++Client::ReleaseIOThreadObjects() ++{ ++} + +- void +- StartIdleMaintenance() override +- { } ++void ++Client::AbortOperations(const nsACString& aOrigin) ++{ ++} + +- void +- StopIdleMaintenance() override +- { } ++void ++Client::AbortOperationsForProcess(ContentParentId aContentParentId) ++{ ++} + +- void +- ShutdownWorkThreads() override +- { +- AssertIsOnBackgroundThread(); ++void ++Client::StartIdleMaintenance() ++{ ++} + +- if (sLiveParentActors) { +- MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { +- return !sLiveParentActors; +- })); +- } +- } ++void ++Client::StopIdleMaintenance() ++{ ++} + +-private: +- nsAutoRefCnt mRefCnt; +- NS_DECL_OWNINGTHREAD +-}; ++void ++Client::ShutdownWorkThreads() ++{ ++ AssertIsOnBackgroundThread(); + +-NS_IMPL_ADDREF(asmjscache::Client) +-NS_IMPL_RELEASE(asmjscache::Client) ++ if (sLiveParentActors) { ++ MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { ++ return !sLiveParentActors; ++ })); ++ } ++} + + quota::Client* + CreateClient() +commit 58e99f59ab54 +Author: Jan Varga +Date: Thu Nov 2 14:54:29 2017 +0800 + + Bug 1389561 - Part 5: Prevent allocation of parent actors if quota manager is shutting down; r=luke +--- + dom/asmjscache/AsmJSCache.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 58 insertions(+), 1 deletion(-) + +diff --git dom/asmjscache/AsmJSCache.cpp dom/asmjscache/AsmJSCache.cpp +index 1ba4f66085a1..1d73c1c9546c 100644 +--- dom/asmjscache/AsmJSCache.cpp ++++ dom/asmjscache/AsmJSCache.cpp +@@ -247,7 +247,41 @@ EvictEntries(nsIFile* aDirectory, const nsACString& aGroup, + class Client + : public quota::Client + { ++ static Client* sInstance; ++ ++ bool mShutdownRequested; ++ + public: ++ Client(); ++ ++ static bool ++ IsShuttingDownOnBackgroundThread() ++ { ++ AssertIsOnBackgroundThread(); ++ ++ if (sInstance) { ++ return sInstance->IsShuttingDown(); ++ } ++ ++ return QuotaManager::IsShuttingDown(); ++ } ++ ++ static bool ++ IsShuttingDownOnNonBackgroundThread() ++ { ++ MOZ_ASSERT(!IsOnBackgroundThread()); ++ ++ return QuotaManager::IsShuttingDown(); ++ } ++ ++ bool ++ IsShuttingDown() const ++ { ++ AssertIsOnBackgroundThread(); ++ ++ return mShutdownRequested; ++ } ++ + NS_INLINE_DECL_REFCOUNTING(Client, override) + + Type +@@ -291,7 +325,7 @@ public: + ShutdownWorkThreads() override; + + private: +- ~Client() override = default; ++ ~Client() override; + }; + + // FileDescriptorHolder owns a file descriptor and its memory mapping. +@@ -1098,6 +1132,10 @@ AllocEntryParent(OpenMode aOpenMode, + { + AssertIsOnBackgroundThread(); + ++ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread())) { ++ return nullptr; ++ } ++ + if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) { + MOZ_ASSERT(false); + return nullptr; +@@ -1651,6 +1689,25 @@ CloseEntryForWrite(size_t aSize, + * Client + ******************************************************************************/ + ++Client* Client::sInstance = nullptr; ++ ++Client::Client() ++ : mShutdownRequested(false) ++{ ++ AssertIsOnBackgroundThread(); ++ MOZ_ASSERT(!sInstance, "We expect this to be a singleton!"); ++ ++ sInstance = this; ++} ++ ++Client::~Client() ++{ ++ AssertIsOnBackgroundThread(); ++ MOZ_ASSERT(sInstance == this, "We expect this to be a singleton!"); ++ ++ sInstance = nullptr; ++} ++ + Client::Type + Client::GetType() + { Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1389561 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1425612 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1425612 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1425612 (revision 459395) @@ -0,0 +1,85 @@ +commit 64e13f47e70c +Author: Jason Orendorff +Date: Wed Jan 10 20:45:39 2018 -0600 + + Bug 1425612 - Better error messages for invalid structured clone data. r=sfink, a=gchang. + + --HG-- + extra : source : 462f41ca6771fa573e6550509e78dddc8bd8d102 + extra : intermediate-source : a2cf3f843d0b5d99c9603d6d4c83146719634a4a + extra : histedit_source : d6a121b9aaa78c385a368667606126b4aaa6d8b2 +--- + js/src/vm/StructuredClone.cpp | 32 +++++++++++++++++++++++++++++--- + 1 file changed, 29 insertions(+), 3 deletions(-) + +diff --git js/src/vm/StructuredClone.cpp js/src/vm/StructuredClone.cpp +index e6623058459f..8d5f22a0f90b 100644 +--- js/src/vm/StructuredClone.cpp ++++ js/src/vm/StructuredClone.cpp +@@ -1873,6 +1873,12 @@ JSStructuredCloneReader::readTypedArray(uint32_t arrayType, uint32_t nelems, Mut + return false; + byteOffset = n; + } ++ if (!v.isObject() || !v.toObject().is()) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, ++ "typed array must be backed by an ArrayBuffer"); ++ return false; ++ } ++ + RootedObject buffer(context(), &v.toObject()); + RootedObject obj(context(), nullptr); + +@@ -1930,6 +1936,11 @@ JSStructuredCloneReader::readDataView(uint32_t byteLength, MutableHandleValue vp + RootedValue v(context()); + if (!startRead(&v)) + return false; ++ if (!v.isObject() || !v.toObject().is()) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, ++ "DataView must be backed by an ArrayBuffer"); ++ return false; ++ } + + // Read byteOffset. + uint64_t n; +@@ -1980,8 +1991,11 @@ JSStructuredCloneReader::readSharedArrayBuffer(uint32_t nbytes, MutableHandleVal + + // We must not transfer buffer pointers cross-process. The cloneDataPolicy + // in the sender should guard against this; check that it does. +- +- MOZ_RELEASE_ASSERT(storedScope <= JS::StructuredCloneScope::SameProcessDifferentThread); ++ if (storedScope > JS::StructuredCloneScope::SameProcessDifferentThread) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, ++ "can't transfer SharedArrayBuffer cross-process"); ++ return false; ++ } + + // The new object will have a new reference to the rawbuf. + +@@ -2009,7 +2023,11 @@ bool + JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, + MutableHandleValue vp) + { +- MOZ_ASSERT(arrayType <= Scalar::Uint8Clamped); ++ if (arrayType > Scalar::Uint8Clamped) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, ++ "invalid TypedArray type"); ++ return false; ++ } + + mozilla::CheckedInt nbytes = + mozilla::CheckedInt(nelems) * +@@ -2276,6 +2294,14 @@ JSStructuredCloneReader::readHeader() + } + + MOZ_ALWAYS_TRUE(in.readPair(&tag, &data)); ++ if (data != uint32_t(JS::StructuredCloneScope::SameProcessSameThread) && ++ data != uint32_t(JS::StructuredCloneScope::SameProcessDifferentThread) && ++ data != uint32_t(JS::StructuredCloneScope::DifferentProcess)) ++ { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, ++ "invalid structured clone scope"); ++ return false; ++ } + storedScope = JS::StructuredCloneScope(data); + if (storedScope < allowedScope) { + JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA, Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1425612 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1426783 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1426783 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1426783 (revision 459395) @@ -0,0 +1,38 @@ +commit bd6f4255ac32 +Author: Jason Orendorff +Date: Fri Jan 5 15:17:35 2018 -0600 + + Bug 1426783 - Fix error handling in deserialization of invalid typed arrays. r=sfink, a=gchang. + + --HG-- + extra : source : f10263c3babef5f70e1e8fdb9e52c2de15cf22e1 + extra : intermediate-source : 3bda6eb9e8469ac4347bb9738d720ea81c358aea + extra : histedit_source : 9d203779ff057ed4e857fe31ba5b51d38f1547e5 +--- + js/src/vm/StructuredClone.cpp | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git js/src/vm/StructuredClone.cpp js/src/vm/StructuredClone.cpp +index c18cd232a192..e6623058459f 100644 +--- js/src/vm/StructuredClone.cpp ++++ js/src/vm/StructuredClone.cpp +@@ -2011,8 +2011,17 @@ JSStructuredCloneReader::readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, + { + MOZ_ASSERT(arrayType <= Scalar::Uint8Clamped); + +- uint32_t nbytes = nelems << TypedArrayShift(static_cast(arrayType)); +- JSObject* obj = ArrayBufferObject::create(context(), nbytes); ++ mozilla::CheckedInt nbytes = ++ mozilla::CheckedInt(nelems) * ++ TypedArrayElemSize(static_cast(arrayType)); ++ if (!nbytes.isValid() || nbytes.value() > UINT32_MAX) { ++ JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, ++ JSMSG_SC_BAD_SERIALIZED_DATA, ++ "invalid typed array size"); ++ return false; ++ } ++ ++ JSObject* obj = ArrayBufferObject::create(context(), nbytes.value()); + if (!obj) + return false; + vp.setObject(*obj); Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1426783 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1429764 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1429764 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1429764 (revision 459395) @@ -0,0 +1,207 @@ +commit 6a927d435699 +Author: Tom Ritter +Date: Fri Jan 12 13:36:04 2018 -0600 + + Bug 1429764 - Do not call ReduceTimerPrecision twice for DOM Navigation timers. r=bkelly, r=timhuang, a=jcristau + + Bug 1429764 details a test failure that was asserting that the performance navigation + timers were strictly increasing (or equal). fetchStart should have a timestamp before + domainLookupStart. But it didn't. + + The problem is two-fold. This corrects the test and the issue by addressing one part + of the problem, the second part of the problem needs to be written up in a new bug + and addressed there. (That bug is not yet filed at writing, but see dependencies of + 1429764 in the future to find it.) + + The second, and underlying, problem is that calling ReduceTimerPrecision with the + same value multiple times may continually reduce it. Meaning that the first you call + it with, say, .75, (and a precision of .20), it will be reduced to .6. The second time + you call it (with .6), instead of staying at .6 it will be reduced to .4. This is + because floats are fuzzy. Inside ReduceTimerPrecision we are multiplying a decimal by + a decimal, so while floor(.6 / .20) should equal 3, sometimes it's actually 2.999... + which gets floors to 2, gets multiplied again by .2, and which results in .4 + + If that's the underlying problem, the first, and surface, problem is - why are we + calling ReduceTimerPrecision multiple times? We shouldn't be. That's what this + patch fixes. + + TimeStampToDOMHighResOrFetchStart will return either TimeStampToDOMHighRes() or + FetchStartHighRes(). FetchStartHighRes() internally calls TimeStampToDOMHighRes + and then ReduceTimerPrecision - this is where (some of) the two reduction calls + happen - because TimeStampToDOMHighRes itself calls ReduceTimerPrecision also. + + I remove the ReduceTimerPrecision from TimeStampToDOMHighRes. FetchStartHighRes + will now only call ReduceTimerPrecision once, at the end of the return. + + But we have to fix places we call TimeStampToDOMHighResOrFetchStart, because the + callers of that function also call ReduceTimerPrecision. So if + TimeStampToDOMHighResOrFetchStart returned FetchStartHighRes, we'd be calling + ReduceTimerPrecision twice for those callers. + + So inside first off, we remove the outer call to ReduceTimerPrecision. that + surrounds the 5 or so callsites of TimeStampToDOMHighResOrFetchStart. Then + inside of TimeStampToDOMHighResOrFetchStart we return either FetchStartHighRes + (which is has already called ReduceTimerPrecision) or we call + ReduceTimerPrecision with the value. + + Now. TimeStampToDOMHighRes was used in more places than just FetchStartHighRes - + there were several other places where we were doing double rounding, and this + fixed those as well. AsyncOpenHighRes, WorkerStartHighRes, DomainLookupEndHighRes, + ConnectStartHighRes, SecureConnectionStartHighRes, ConnectEndHighRes, and + ResponseEndHighRes. + + MozReview-Commit-ID: K5nHql135rb + + --HG-- + extra : source : 17bf5819b42fa3b656f2d3c565bc4fb0ca050066 +--- + dom/performance/PerformanceTiming.cpp | 15 +++------ + dom/performance/PerformanceTiming.h | 7 ++-- + .../resistfingerprinting/nsRFPService.cpp | 38 +++++++++++++++++++--- + 3 files changed, 42 insertions(+), 18 deletions(-) + +diff --git dom/performance/PerformanceTiming.cpp dom/performance/PerformanceTiming.cpp +index 3d7e55a0c80f..f80d7f509a40 100644 +--- dom/performance/PerformanceTiming.cpp ++++ dom/performance/PerformanceTiming.cpp +@@ -222,7 +222,7 @@ PerformanceTiming::RedirectStartHighRes() + nsContentUtils::ShouldResistFingerprinting()) { + return mZeroTime; + } +- return TimeStampToDOMHighResOrFetchStart(mRedirectStart); ++ return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart); + } + + DOMTimeMilliSec +@@ -256,7 +256,7 @@ PerformanceTiming::RedirectEndHighRes() + nsContentUtils::ShouldResistFingerprinting()) { + return mZeroTime; + } +- return TimeStampToDOMHighResOrFetchStart(mRedirectEnd); ++ return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd); + } + + DOMTimeMilliSec +@@ -280,7 +280,7 @@ PerformanceTiming::DomainLookupStartHighRes() + nsContentUtils::ShouldResistFingerprinting()) { + return mZeroTime; + } +- return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart); ++ return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart); + } + + DOMTimeMilliSec +@@ -366,7 +366,7 @@ PerformanceTiming::RequestStartHighRes() + nsContentUtils::ShouldResistFingerprinting()) { + return mZeroTime; + } +- return TimeStampToDOMHighResOrFetchStart(mRequestStart); ++ return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart); + } + + DOMTimeMilliSec +@@ -386,7 +386,7 @@ PerformanceTiming::ResponseStartHighRes() + (!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) { + mResponseStart = mCacheReadStart; + } +- return TimeStampToDOMHighResOrFetchStart(mResponseStart); ++ return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart); + } + + DOMTimeMilliSec +diff --git dom/performance/PerformanceTiming.h dom/performance/PerformanceTiming.h +index 0558fc11d64e..9fba3210ef1d 100644 +--- dom/performance/PerformanceTiming.h ++++ dom/performance/PerformanceTiming.h +@@ -68,10 +68,10 @@ public: + * page), if the given TimeStamp is valid. Otherwise, it will return + * the FetchStart timing value. + */ +- inline DOMHighResTimeStamp TimeStampToDOMHighResOrFetchStart(TimeStamp aStamp) ++ inline DOMHighResTimeStamp TimeStampToReducedDOMHighResOrFetchStart(TimeStamp aStamp) + { + return (!aStamp.IsNull()) +- ? TimeStampToDOMHighRes(aStamp) ++ ? nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(aStamp)) + : FetchStartHighRes(); + } + +diff --git toolkit/components/resistfingerprinting/nsRFPService.cpp toolkit/components/resistfingerprinting/nsRFPService.cpp +index 51552da69923..98857a764721 100644 +--- toolkit/components/resistfingerprinting/nsRFPService.cpp ++++ toolkit/components/resistfingerprinting/nsRFPService.cpp +@@ -8,6 +8,7 @@ + #include + + #include "mozilla/ClearOnShutdown.h" ++#include "mozilla/Logging.h" + #include "mozilla/Preferences.h" + #include "mozilla/Services.h" + #include "mozilla/StaticPtr.h" +@@ -28,6 +29,10 @@ + + using namespace mozilla; + ++#ifdef DEBUG ++static mozilla::LazyLogModule gResistFingerprintingLog("nsResistFingerprinting"); ++#endif ++ + #define RESIST_FINGERPRINTING_PREF "privacy.resistFingerprinting" + #define PROFILE_INITIALIZED_TOPIC "profile-initial-state" + +@@ -66,7 +71,13 @@ nsRFPService::ReduceTimePrecisionAsMSecs(double aTime) + return aTime; + } + const double resolutionMSec = kResolutionUSec / 1000.0; +- return floor(aTime / resolutionMSec) * resolutionMSec; ++ double ret = floor(aTime / resolutionMSec) * resolutionMSec; ++#if defined(DEBUG) ++ MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose, ++ ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f", ++ DBL_DIG-1, aTime, DBL_DIG-1, resolutionMSec, DBL_DIG-1, floor(aTime / resolutionMSec), DBL_DIG-1, ret)); ++#endif ++ return ret; + } + + /* static */ +@@ -76,7 +87,14 @@ nsRFPService::ReduceTimePrecisionAsUSecs(double aTime) + if (!IsResistFingerprintingEnabled()) { + return aTime; + } +- return floor(aTime / kResolutionUSec) * kResolutionUSec; ++ double ret = floor(aTime / kResolutionUSec) * kResolutionUSec; ++#if defined(DEBUG) ++ double tmp_kResolutionUSec = kResolutionUSec; ++ MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose, ++ ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f", ++ DBL_DIG-1, aTime, DBL_DIG-1, tmp_kResolutionUSec, DBL_DIG-1, floor(aTime / tmp_kResolutionUSec), DBL_DIG-1, ret)); ++#endif ++ return ret; + } + + /* static */ +@@ -90,10 +108,22 @@ nsRFPService::ReduceTimePrecisionAsSecs(double aTime) + // The resolution is smaller than one sec. Use the reciprocal to avoid + // floating point error. + const double resolutionSecReciprocal = 1000000.0 / kResolutionUSec; +- return floor(aTime * resolutionSecReciprocal) / resolutionSecReciprocal; ++ double ret = floor(aTime * resolutionSecReciprocal) / resolutionSecReciprocal; ++#if defined(DEBUG) ++ MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose, ++ ("Given: %.*f, Reciprocal Rounding with %.*f, Intermediate: %.*f, Got: %.*f", ++ DBL_DIG-1, aTime, DBL_DIG-1, resolutionSecReciprocal, DBL_DIG-1, floor(aTime * resolutionSecReciprocal), DBL_DIG-1, ret)); ++#endif ++ return ret; + } + const double resolutionSec = kResolutionUSec / 1000000.0; +- return floor(aTime / resolutionSec) * resolutionSec; ++ double ret = floor(aTime / resolutionSec) * resolutionSec; ++#if defined(DEBUG) ++ MOZ_LOG(gResistFingerprintingLog, LogLevel::Verbose, ++ ("Given: %.*f, Rounding with %.*f, Intermediate: %.*f, Got: %.*f", ++ DBL_DIG-1, aTime, DBL_DIG-1, resolutionSec, DBL_DIG-1, floor(aTime / resolutionSec), DBL_DIG-1, ret)); ++#endif ++ return ret; + } + + nsresult Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1429764 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1/www/waterfox/files/patch-bug1430508 =================================================================== --- branches/2018Q1/www/waterfox/files/patch-bug1430508 (nonexistent) +++ branches/2018Q1/www/waterfox/files/patch-bug1430508 (revision 459395) @@ -0,0 +1,56 @@ +commit 47e68af6bce1 +Author: Kris Maglione +Date: Sun Jan 14 17:40:09 2018 -0800 + + Bug 1430508 - Return 0 for ProcessId() when channel IPC is closed. r=dragana, a=jcristau + + There are some corner cases where we try to attach StreamFilter endpoints to a + channel after its IPC has been closed from from the other side, but request + listeners haven't been notified. This causes crashes in any of several places. + + This patch changes nsHttpChannel::ProcessId to return 0 when IPC is closed, so + callers can detect that it's no longer possible to attach endpoints to it. + + MozReview-Commit-ID: BZTOqezih0P + + --HG-- + extra : source : 06f766e7640a3cd180f7da7c092823e500a3d674 +--- + netwerk/protocol/http/HttpChannelParent.cpp | 9 +++++++++ + netwerk/protocol/http/HttpChannelParent.h | 2 ++ + toolkit/components/extensions/webrequest/StreamFilterParent.cpp | 5 ++++- + 3 files changed, 15 insertions(+), 1 deletion(-) + +diff --git netwerk/protocol/http/HttpChannelParent.cpp netwerk/protocol/http/HttpChannelParent.cpp +index db5f441e53c1..ab332ca1a587 100644 +--- netwerk/protocol/http/HttpChannelParent.cpp ++++ netwerk/protocol/http/HttpChannelParent.cpp +@@ -265,6 +265,15 @@ HttpChannelParent::CleanupBackgroundChannel() + } + } + ++base::ProcessId ++HttpChannelParent::OtherPid() const ++{ ++ if (mIPCClosed) { ++ return 0; ++ } ++ return Manager()->OtherPid(); ++} ++ + //----------------------------------------------------------------------------- + // HttpChannelParent::nsISupports + //----------------------------------------------------------------------------- +diff --git netwerk/protocol/http/HttpChannelParent.h netwerk/protocol/http/HttpChannelParent.h +index 19e6fca40bff..fbbad6c2f994 100644 +--- netwerk/protocol/http/HttpChannelParent.h ++++ netwerk/protocol/http/HttpChannelParent.h +@@ -120,6 +120,8 @@ public: + // Callback while background channel is destroyed. + void OnBackgroundParentDestroyed(); + ++ base::ProcessId OtherPid() const override; ++ + protected: + // used to connect redirected-to channel in parent with just created + // ChildChannel. Used during redirects. Property changes on: branches/2018Q1/www/waterfox/files/patch-bug1430508 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: branches/2018Q1 =================================================================== --- branches/2018Q1 (revision 459394) +++ branches/2018Q1 (revision 459395) Property changes on: branches/2018Q1 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r459394