1
0
mirror of https://git.FreeBSD.org/ports.git synced 2025-01-15 07:56:36 +00:00

www/waterfox: apply some FF58 fixes

Security:	a891c5b4-3d7a-4de9-9c71-eef3fd698c77
This commit is contained in:
Jan Beich 2017-12-26 21:47:13 +00:00
parent c463b1d3d4
commit 0857284d50
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=457317
24 changed files with 2415 additions and 1 deletions

View File

@ -2,7 +2,7 @@
PORTNAME= waterfox
DISTVERSION= 56.0.1.s20171212
PORTREVISION= 1
PORTREVISION= 2
CATEGORIES= www ipv6
MAINTAINER= jbeich@FreeBSD.org

View File

@ -0,0 +1,146 @@
commit 94f55f3a6124
Author: Lee Salzman <lsalzman@mozilla.com>
Date: Wed Nov 22 12:19:29 2017 -0500
Bug 1224396 - Skia path allocation cleanups. r=msreckovic a=gchang
MozReview-Commit-ID: GAf2vC1Fucv
--HG--
extra : source : db4543ce21ce1e8a1c81b685a16e61f71db2f602
---
gfx/skia/skia/include/core/SkPathRef.h | 24 ++++++++++++++----------
gfx/skia/skia/src/core/SkArenaAlloc.cpp | 23 ++++++++++++++++++-----
gfx/skia/skia/src/core/SkArenaAlloc.h | 5 ++++-
3 files changed, 36 insertions(+), 16 deletions(-)
diff --git gfx/skia/skia/include/core/SkPathRef.h gfx/skia/skia/include/core/SkPathRef.h
index 5e6fda7d85b2..24870c64fbc0 100644
--- gfx/skia/skia/include/core/SkPathRef.h
+++ gfx/skia/skia/include/core/SkPathRef.h
@@ -16,7 +16,7 @@
#include "SkRRect.h"
#include "SkRect.h"
#include "SkRefCnt.h"
-#include <stddef.h> // ptrdiff_t
+#include "../private/SkTemplates.h"
class SkRBuffer;
class SkWBuffer;
@@ -433,31 +433,35 @@ private:
*/
void makeSpace(size_t size) {
SkDEBUGCODE(this->validate();)
- ptrdiff_t growSize = size - fFreeSpace;
- if (growSize <= 0) {
+ if (size <= fFreeSpace) {
return;
}
+ size_t growSize = size - fFreeSpace;
size_t oldSize = this->currSize();
// round to next multiple of 8 bytes
growSize = (growSize + 7) & ~static_cast<size_t>(7);
// we always at least double the allocation
- if (static_cast<size_t>(growSize) < oldSize) {
+ if (growSize < oldSize) {
growSize = oldSize;
}
if (growSize < kMinSize) {
growSize = kMinSize;
}
- size_t newSize = oldSize + growSize;
+ constexpr size_t maxSize = std::numeric_limits<size_t>::max();
+ size_t newSize;
+ if (growSize <= maxSize - oldSize) {
+ newSize = oldSize + growSize;
+ } else {
+ SK_ABORT("Path too big.");
+ }
// Note that realloc could memcpy more than we need. It seems to be a win anyway. TODO:
// encapsulate this.
fPoints = reinterpret_cast<SkPoint*>(sk_realloc_throw(fPoints, newSize));
size_t oldVerbSize = fVerbCnt * sizeof(uint8_t);
- void* newVerbsDst = reinterpret_cast<void*>(
- reinterpret_cast<intptr_t>(fPoints) + newSize - oldVerbSize);
- void* oldVerbsSrc = reinterpret_cast<void*>(
- reinterpret_cast<intptr_t>(fPoints) + oldSize - oldVerbSize);
+ void* newVerbsDst = SkTAddOffset<void>(fPoints, newSize - oldVerbSize);
+ void* oldVerbsSrc = SkTAddOffset<void>(fPoints, oldSize - oldVerbSize);
memmove(newVerbsDst, oldVerbsSrc, oldVerbSize);
- fVerbs = reinterpret_cast<uint8_t*>(reinterpret_cast<intptr_t>(fPoints) + newSize);
+ fVerbs = SkTAddOffset<uint8_t>(fPoints, newSize);
fFreeSpace += growSize;
SkDEBUGCODE(this->validate();)
}
diff --git gfx/skia/skia/src/core/SkArenaAlloc.cpp gfx/skia/skia/src/core/SkArenaAlloc.cpp
index eca3aa97d761..57a19093d065 100644
--- gfx/skia/skia/src/core/SkArenaAlloc.cpp
+++ gfx/skia/skia/src/core/SkArenaAlloc.cpp
@@ -8,6 +8,7 @@
#include <algorithm>
#include <cstddef>
#include "SkArenaAlloc.h"
+#include "SkTypes.h"
static char* end_chain(char*) { return nullptr; }
@@ -95,19 +96,31 @@ void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) {
// This must be conservative to add the right amount of extra memory to handle the alignment
// padding.
constexpr uint32_t alignof_max_align_t = 8;
- uint32_t objSizeAndOverhead = size + headerSize + sizeof(Footer);
+ constexpr uint32_t maxSize = std::numeric_limits<uint32_t>::max();
+ constexpr uint32_t overhead = headerSize + sizeof(Footer);
+ SkASSERT_RELEASE(size <= maxSize - overhead);
+ uint32_t objSizeAndOverhead = size + overhead;
if (alignment > alignof_max_align_t) {
- objSizeAndOverhead += alignment - 1;
+ uint32_t alignmentOverhead = alignment - 1;
+ SkASSERT_RELEASE(objSizeAndOverhead <= maxSize - alignmentOverhead);
+ objSizeAndOverhead += alignmentOverhead;
}
- uint32_t allocationSize = std::max(objSizeAndOverhead, fExtraSize * fFib0);
- fFib0 += fFib1;
- std::swap(fFib0, fFib1);
+ uint32_t minAllocationSize;
+ if (fExtraSize <= maxSize / fFib0) {
+ minAllocationSize = fExtraSize * fFib0;
+ fFib0 += fFib1;
+ std::swap(fFib0, fFib1);
+ } else {
+ minAllocationSize = maxSize;
+ }
+ uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize);
// Round up to a nice size. If > 32K align to 4K boundary else up to max_align_t. The > 32K
// heuristic is from the JEMalloc behavior.
{
uint32_t mask = allocationSize > (1 << 15) ? (1 << 12) - 1 : 16 - 1;
+ SkASSERT_RELEASE(allocationSize <= maxSize - mask);
allocationSize = (allocationSize + mask) & ~mask;
}
diff --git gfx/skia/skia/src/core/SkArenaAlloc.h gfx/skia/skia/src/core/SkArenaAlloc.h
index 494696ce768d..05d3336684e9 100644
--- gfx/skia/skia/src/core/SkArenaAlloc.h
+++ gfx/skia/skia/src/core/SkArenaAlloc.h
@@ -157,6 +157,7 @@ private:
template <typename T>
char* commonArrayAlloc(uint32_t count) {
char* objStart;
+ SkASSERT_RELEASE(count <= std::numeric_limits<uint32_t>::max() / sizeof(T));
uint32_t arraySize = SkTo<uint32_t>(count * sizeof(T));
uint32_t alignment = SkTo<uint32_t>(alignof(T));
@@ -164,7 +165,9 @@ private:
objStart = this->allocObject(arraySize, alignment);
fCursor = objStart + arraySize;
} else {
- uint32_t totalSize = arraySize + sizeof(Footer) + sizeof(uint32_t);
+ constexpr uint32_t overhead = sizeof(Footer) + sizeof(uint32_t);
+ SkASSERT_RELEASE(arraySize <= std::numeric_limits<uint32_t>::max() - overhead);
+ uint32_t totalSize = arraySize + overhead;
objStart = this->allocObjectWithFooter(totalSize, alignment);
// Can never be UB because max value is alignof(T).

View File

@ -0,0 +1,39 @@
commit 7c15d03b1e83
Author: Blake Kaplan <mrbkap@gmail.com>
Date: Mon Dec 18 19:39:45 2017 -0500
Bug 1399400 - Use a strong reference when handling mTextField. r=bz a=jcristau
MozReview-Commit-ID: IqzGDM4ezeW
--HG--
extra : rebase_source : 8f9a1f72360fcabdc6e57fec3dbdda1bd705fd03
extra : source : 02d457ace9bb8430e25cfb3a1fb6b0303c9d01c5
---
layout/forms/nsNumberControlFrame.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git layout/forms/nsNumberControlFrame.cpp layout/forms/nsNumberControlFrame.cpp
index 00b4492f23f1..68819267c906 100644
--- layout/forms/nsNumberControlFrame.cpp
+++ layout/forms/nsNumberControlFrame.cpp
@@ -592,15 +592,17 @@ nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
{
if (aEvent->mOriginalTarget != mTextField) {
// Move focus to our text field
+ RefPtr<HTMLInputElement> textField = HTMLInputElement::FromContent(mTextField);
IgnoredErrorResult ignored;
- HTMLInputElement::FromContent(mTextField)->Focus(ignored);
+ textField->Focus(ignored);
}
}
void
nsNumberControlFrame::HandleSelectCall()
{
- HTMLInputElement::FromContent(mTextField)->Select();
+ RefPtr<HTMLInputElement> textField = HTMLInputElement::FromContent(mTextField);
+ textField->Select();
}
#define STYLES_DISABLING_NATIVE_THEMING \

View File

@ -0,0 +1,93 @@
commit b4603106d015
Author: Liang-Heng Chen <xeonchen@gmail.com>
Date: Thu Oct 19 22:29:41 2017 -0400
Bug 1399520 - Avoid race condition. r=dragana
MozReview-Commit-ID: 6Pd2HXqBgX4
---
modules/libjar/nsJAR.cpp | 26 ++++++++++++++++++--------
modules/libjar/nsJAR.h | 8 +++++---
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git modules/libjar/nsJAR.cpp modules/libjar/nsJAR.cpp
index 80589e03f92b..b3121d99ef0a 100644
--- modules/libjar/nsJAR.cpp
+++ modules/libjar/nsJAR.cpp
@@ -43,11 +43,27 @@ NS_IMPL_QUERY_INTERFACE(nsJAR, nsIZipReader)
NS_IMPL_ADDREF(nsJAR)
// Custom Release method works with nsZipReaderCache...
+// Release might be called from multi-thread, we have to
+// take this function carefully to avoid delete-after-use.
MozExternalRefCountType nsJAR::Release(void)
{
nsrefcnt count;
NS_PRECONDITION(0 != mRefCnt, "dup release");
- count = --mRefCnt;
+
+ RefPtr<nsZipReaderCache> cache;
+ if (mRefCnt == 2) { // don't use a lock too frequently
+ // Use a mutex here to guarantee mCache is not racing and the target instance
+ // is still valid to increase ref-count.
+ MutexAutoLock lock(mLock);
+ cache = mCache;
+ mCache = nullptr;
+ }
+ if (cache) {
+ DebugOnly<nsresult> rv = cache->ReleaseZip(this);
+ MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to release zip file");
+ }
+
+ count = --mRefCnt; // don't access any member variable after this line
NS_LOG_RELEASE(this, count, "nsJAR");
if (0 == count) {
mRefCnt = 1; /* stabilize */
@@ -56,13 +72,7 @@ MozExternalRefCountType nsJAR::Release(void)
delete this;
return 0;
}
- if (1 == count && mCache) {
-#ifdef DEBUG
- nsresult rv =
-#endif
- mCache->ReleaseZip(this);
- NS_ASSERTION(NS_SUCCEEDED(rv), "failed to release zip file");
- }
+
return count;
}
diff --git modules/libjar/nsJAR.h modules/libjar/nsJAR.h
index 7f675c93003b..4fe948680fbf 100644
--- modules/libjar/nsJAR.h
+++ modules/libjar/nsJAR.h
@@ -12,6 +12,7 @@
#include "mozilla/Logging.h"
#include "prinrval.h"
+#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "nsIComponentManager.h"
#include "nsCOMPtr.h"
@@ -75,8 +76,9 @@ class nsJAR final : public nsIZipReader
mReleaseTime = PR_INTERVAL_NO_TIMEOUT;
}
- void SetZipReaderCache(nsZipReaderCache* cache) {
- mCache = cache;
+ void SetZipReaderCache(nsZipReaderCache* aCache) {
+ mozilla::MutexAutoLock lock(mLock);
+ mCache = aCache;
}
nsresult GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc);
@@ -89,7 +91,7 @@ class nsJAR final : public nsIZipReader
RefPtr<nsZipArchive> mZip; // The underlying zip archive
PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries
nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in
- mozilla::Mutex mLock;
+ mozilla::Mutex mLock; // protect mCache and mZip
int64_t mMtime;
bool mOpened;
bool mIsOmnijar;

View File

@ -0,0 +1,170 @@
commit a9bc6108422a
Author: Karl Tomlinson <karlt+@karlt.net>
Date: Tue Oct 17 18:14:43 2017 +1300
Bug 1408276 - Move to LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP at end of iteration. r=padenot, a=gchang
MozReview-Commit-ID: GbfIOPZPuGu
--HG--
extra : rebase_source : acc2bcee9a36d2b8f18826f08825895de5df0c1e
---
dom/media/GraphDriver.cpp | 27 +++++++++++++++++----------
dom/media/MediaStreamGraph.cpp | 32 +++++++++++++++++++++-----------
dom/media/MediaStreamGraphImpl.h | 12 +++++++++++-
3 files changed, 49 insertions(+), 22 deletions(-)
diff --git dom/media/GraphDriver.cpp dom/media/GraphDriver.cpp
index 7f6f386fdaca..13944338e3d7 100644
--- dom/media/GraphDriver.cpp
+++ dom/media/GraphDriver.cpp
@@ -284,8 +284,7 @@ SystemClockDriver::IsFallback()
void
ThreadedDriver::RunThread()
{
- bool stillProcessing = true;
- while (stillProcessing) {
+ while (true) {
mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration();
@@ -324,10 +323,16 @@ ThreadedDriver::RunThread()
(long)stateComputedTime,
(long)nextStateComputedTime));
- stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
+ bool stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
+ if (!stillProcessing) {
+ // Enter shutdown mode. The stable-state handler will detect this
+ // and complete shutdown if the graph does not get restarted.
+ mGraphImpl->SignalMainThreadCleanup();
+ return;
+ }
MonitorAutoLock lock(GraphImpl()->GetMonitor());
- if (NextDriver() && stillProcessing) {
+ if (NextDriver()) {
LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
RemoveCallback();
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
@@ -1009,13 +1014,20 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
mGraphImpl->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mOutputChannels);
+ if (!stillProcessing) {
+ // Enter shutdown mode. The stable-state handler will detect this
+ // and complete shutdown if the graph does not get restarted.
+ mGraphImpl->SignalMainThreadCleanup();
+ return aFrames - 1;
+ }
+
bool switching = false;
{
MonitorAutoLock mon(mGraphImpl->GetMonitor());
switching = !!NextDriver();
}
- if (switching && stillProcessing) {
+ if (switching) {
// If the audio stream has not been started by the previous driver or
// the graph itself, keep it alive.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
@@ -1032,11 +1044,6 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
return aFrames - 1;
}
- if (!stillProcessing) {
- LOG(LogLevel::Debug,
- ("Stopping audio thread for MediaStreamGraph %p", this));
- return aFrames - 1;
- }
return aFrames;
}
diff --git dom/media/MediaStreamGraph.cpp dom/media/MediaStreamGraph.cpp
index 3a742aafe9b2..6420e038a8fe 100644
--- dom/media/MediaStreamGraph.cpp
+++ dom/media/MediaStreamGraph.cpp
@@ -1193,11 +1193,13 @@ MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
}
}
- // Don't send the message to the main thread if it's not going to have
- // any work to do.
- if (aFinalUpdate ||
- !mUpdateRunnables.IsEmpty() ||
- !mStreamUpdates.IsEmpty()) {
+ // If this is the final update, then a stable state event will soon be
+ // posted just before this thread finishes, and so there is no need to also
+ // post here.
+ if (!aFinalUpdate &&
+ // Don't send the message to the main thread if it's not going to have
+ // any work to do.
+ !(mUpdateRunnables.IsEmpty() && mStreamUpdates.IsEmpty())) {
EnsureStableStateEventPosted();
}
}
@@ -1430,12 +1432,7 @@ MediaStreamGraphImpl::UpdateMainThreadState()
(IsEmpty() && mBackMessageQueue.IsEmpty());
PrepareUpdatesToMainThreadState(finalUpdate);
if (finalUpdate) {
- // Enter shutdown mode. The stable-state handler will detect this
- // and complete shutdown. Destroy any streams immediately.
- LOG(LogLevel::Debug,
- ("MediaStreamGraph %p waiting for main thread cleanup", this));
- // We'll shut down this graph object if it does not get restarted.
- mLifecycleState = LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
+ // Enter shutdown mode when this iteration is completed.
// No need to Destroy streams here. The main-thread owner of each
// stream is responsible for calling Destroy on them.
return false;
@@ -1861,6 +1858,19 @@ MediaStreamGraphImpl::EnsureStableStateEventPosted()
mAbstractMainThread->Dispatch(event.forget());
}
+void
+MediaStreamGraphImpl::SignalMainThreadCleanup()
+{
+ MOZ_ASSERT(mDriver->OnThread());
+
+ MonitorAutoLock lock(mMonitor);
+ LOG(LogLevel::Debug,
+ ("MediaStreamGraph %p waiting for main thread cleanup", this));
+ mLifecycleState =
+ MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
+ EnsureStableStateEventPosted();
+}
+
void
MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
{
diff --git dom/media/MediaStreamGraphImpl.h dom/media/MediaStreamGraphImpl.h
index dfea12bca3a8..dce49da39166 100644
--- dom/media/MediaStreamGraphImpl.h
+++ dom/media/MediaStreamGraphImpl.h
@@ -197,6 +197,14 @@ public:
*/
bool OneIteration(GraphTime aStateEnd);
+ /**
+ * Called from the driver, when the graph thread is about to stop, to tell
+ * the main thread to attempt to begin cleanup. The main thread may either
+ * shutdown or revive the graph depending on whether it receives new
+ * messages.
+ */
+ void SignalMainThreadCleanup();
+
bool Running() const
{
mMonitor.AssertCurrentThreadOwns();
@@ -720,7 +728,9 @@ public:
LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
};
/**
- * Modified only on the main thread in mMonitor.
+ * Modified only in mMonitor. Transitions to
+ * LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP occur on the graph thread at
+ * the end of an iteration. All other transitions occur on the main thread.
*/
LifecycleState mLifecycleState;
/**

View File

@ -0,0 +1,177 @@
commit d5562dbcfd63
Author: Henri Sivonen <hsivonen@hsivonen.fi>
Date: Fri Dec 1 10:45:25 2017 -0500
Bug 1409951 - Use a stack to end serializer contexts instead of recomputing them. r=smaug, a=gchang
MozReview-Commit-ID: FOd8AUmtYyA
--HG--
extra : rebase_source : 1f02ebc32fe80591d617f27ec70094a109ead2b0
extra : source : b0a3a621f5c85b5e9a4eb97de77fcb2558ac17c6
---
dom/base/nsDocumentEncoder.cpp | 56 +++++++++++++++++++-------------------
dom/base/nsPlainTextSerializer.cpp | 1 +
2 files changed, 29 insertions(+), 28 deletions(-)
diff --git dom/base/nsDocumentEncoder.cpp dom/base/nsDocumentEncoder.cpp
index 5912d67da86e..2fb488750366 100644
--- dom/base/nsDocumentEncoder.cpp
+++ dom/base/nsDocumentEncoder.cpp
@@ -49,6 +49,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ShadowRoot.h"
#include "nsLayoutUtils.h"
+#include "mozilla/ScopeExit.h"
using namespace mozilla;
using namespace mozilla::dom;
@@ -92,8 +93,8 @@ protected:
int32_t aDepth);
nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
nsAString& aString);
- nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
- nsAString& aString);
+ nsresult SerializeRangeContextEnd(nsAString& aString);
+
virtual int32_t
GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray)
{
@@ -185,6 +186,7 @@ protected:
AutoTArray<int32_t, 8> mStartOffsets;
AutoTArray<nsIContent*, 8> mEndNodes;
AutoTArray<int32_t, 8> mEndOffsets;
+ AutoTArray<AutoTArray<nsINode*, 8>, 8> mRangeContexts;
// Whether the serializer cares about being notified to scan elements to
// keep track of whether they are preformatted. This stores the out
// argument of nsIContentSerializer::Init().
@@ -874,6 +876,9 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
if (mDisableContextSerialize) {
return NS_OK;
}
+
+ AutoTArray<nsINode*, 8>* serializedContext = mRangeContexts.AppendElement();
+
int32_t i = aAncestorArray.Length(), j;
nsresult rv = NS_OK;
@@ -889,7 +894,7 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
// Either a general inclusion or as immediate context
if (IncludeInContext(node) || i < j) {
rv = SerializeNodeStart(node, 0, -1, aString);
-
+ serializedContext->AppendElement(node);
if (NS_FAILED(rv))
break;
}
@@ -899,34 +904,24 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
}
nsresult
-nsDocumentEncoder::SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
- nsAString& aString)
+nsDocumentEncoder::SerializeRangeContextEnd(nsAString& aString)
{
if (mDisableContextSerialize) {
return NS_OK;
}
- int32_t i = 0, j;
- int32_t count = aAncestorArray.Length();
- nsresult rv = NS_OK;
- // currently only for table-related elements
- j = GetImmediateContextCount(aAncestorArray);
+ MOZ_RELEASE_ASSERT(!mRangeContexts.IsEmpty(), "Tried to end context without starting one.");
+ AutoTArray<nsINode*, 8>& serializedContext = mRangeContexts.LastElement();
- while (i < count) {
- nsINode *node = aAncestorArray.ElementAt(i++);
+ nsresult rv = NS_OK;
+ for (nsINode* node : Reversed(serializedContext)) {
+ rv = SerializeNodeEnd(node, aString);
- if (!node)
+ if (NS_FAILED(rv))
break;
-
- // Either a general inclusion or as immediate context
- if (IncludeInContext(node) || i - 1 < j) {
- rv = SerializeNodeEnd(node, aString);
-
- if (NS_FAILED(rv))
- break;
- }
}
+ mRangeContexts.RemoveElementAt(mRangeContexts.Length() - 1);
return rv;
}
@@ -992,7 +987,7 @@ nsDocumentEncoder::SerializeRangeToString(nsRange *aRange,
rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
NS_ENSURE_SUCCESS(rv, rv);
}
- rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
+ rv = SerializeRangeContextEnd(aOutputString);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
@@ -1029,6 +1024,11 @@ NS_IMETHODIMP
nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
nsAString& aOutputString)
{
+ MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
+ auto rangeContextGuard = MakeScopeExit([&] {
+ mRangeContexts.Clear();
+ });
+
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
@@ -1112,10 +1112,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
prevNode = node;
} else if (prevNode) {
// Went from a <tr> to a non-<tr>
- mCommonAncestors.Clear();
- nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
mDisableContextSerialize = false;
- rv = SerializeRangeContextEnd(mCommonAncestors, output);
+ rv = SerializeRangeContextEnd(output);
NS_ENSURE_SUCCESS(rv, rv);
prevNode = nullptr;
}
@@ -1134,10 +1132,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
rv = SerializeNodeEnd(p, output);
NS_ENSURE_SUCCESS(rv, rv);
- mCommonAncestors.Clear();
- nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
mDisableContextSerialize = false;
- rv = SerializeRangeContextEnd(mCommonAncestors, output);
+ rv = SerializeRangeContextEnd(output);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -1196,6 +1192,10 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
NS_IMETHODIMP
nsDocumentEncoder::EncodeToStream(nsIOutputStream* aStream)
{
+ MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
+ auto rangeContextGuard = MakeScopeExit([&] {
+ mRangeContexts.Clear();
+ });
nsresult rv = NS_OK;
if (!mDocument)
diff --git dom/base/nsPlainTextSerializer.cpp dom/base/nsPlainTextSerializer.cpp
index 189469f73bb6..d7ddb0274be5 100644
--- dom/base/nsPlainTextSerializer.cpp
+++ dom/base/nsPlainTextSerializer.cpp
@@ -388,6 +388,7 @@ nsPlainTextSerializer::ScanElementForPreformat(Element* aElement)
NS_IMETHODIMP
nsPlainTextSerializer::ForgetElementForPreformat(Element* aElement)
{
+ MOZ_RELEASE_ASSERT(!mPreformatStack.empty(), "Tried to pop without previous push.");
mPreformatStack.pop();
return NS_OK;
}

View File

@ -0,0 +1,52 @@
commit 2d5001acfa08
Author: Tim Huang <tihuang@mozilla.com>
Date: Tue Nov 28 14:56:55 2017 -0500
Bug 1410134 - Fix the remove-while-iterating for RemoveCookiesWithOriginAttributes. r=jdm, a=gchang
MozReview-Commit-ID: u56N4084lL
--HG--
extra : source : ffab26e34d92c1fc2e5103d2bad3625e180963bb
---
netwerk/cookie/nsCookieService.cpp | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git netwerk/cookie/nsCookieService.cpp netwerk/cookie/nsCookieService.cpp
index 7d939da101e2..0692b7088751 100644
--- netwerk/cookie/nsCookieService.cpp
+++ netwerk/cookie/nsCookieService.cpp
@@ -4899,23 +4899,19 @@ nsCookieService::RemoveCookiesWithOriginAttributes(
}
// Pattern matches. Delete all cookies within this nsCookieEntry.
- const nsCookieEntry::ArrayType& cookies = entry->GetCookies();
+ uint32_t cookiesCount = entry->GetCookies().Length();
- while (!cookies.IsEmpty()) {
- nsCookie *cookie = cookies.LastElement();
-
- nsAutoCString host;
- cookie->GetHost(host);
-
- nsAutoCString name;
- cookie->GetName(name);
-
- nsAutoCString path;
- cookie->GetPath(path);
+ for (nsCookieEntry::IndexType i = 0 ; i < cookiesCount; ++i) {
+ // Remove the first cookie from the list.
+ nsListIter iter(entry, 0);
+ RefPtr<nsCookie> cookie = iter.Cookie();
// Remove the cookie.
- nsresult rv = Remove(host, entry->mOriginAttributes, name, path, false);
- NS_ENSURE_SUCCESS(rv, rv);
+ RemoveCookieFromList(iter);
+
+ if (cookie) {
+ NotifyChanged(cookie, u"deleted");
+ }
}
}
DebugOnly<nsresult> rv = transaction.Commit();

View File

@ -0,0 +1,286 @@
commit d83a24ce6fb3
Author: Xidorn Quan <me@upsuper.org>
Date: Tue Nov 28 17:06:51 2017 -0600
Bug 1412145 - Drop more backpointers of CSSOM objects in dtor and unlink. r=bz, a=gchang
MozReview-Commit-ID: Ftg3WMBBNlO
---
layout/style/GroupRule.cpp | 7 +++++++
layout/style/GroupRule.h | 1 +
layout/style/MediaList.h | 4 +++-
layout/style/ServoCSSRuleList.cpp | 2 ++
layout/style/ServoKeyframeRule.cpp | 12 ++++++++++--
layout/style/ServoKeyframesRule.cpp | 23 ++++++++++++++++-------
layout/style/ServoMediaRule.cpp | 17 +++++++++++++++--
layout/style/ServoPageRule.cpp | 2 ++
layout/style/ServoStyleRule.cpp | 1 +
layout/style/nsCSSRules.cpp | 31 +++++++++++++++++++++++++++----
10 files changed, 84 insertions(+), 16 deletions(-)
diff --git layout/style/GroupRule.cpp layout/style/GroupRule.cpp
index 28739e1818eb..32bd8c83e43a 100644
--- layout/style/GroupRule.cpp
+++ layout/style/GroupRule.cpp
@@ -198,6 +198,13 @@ GeckoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
// ServoGroupRuleRules
//
+ServoGroupRuleRules::~ServoGroupRuleRules()
+{
+ if (mRuleList) {
+ mRuleList->DropReference();
+ }
+}
+
#ifdef DEBUG
void
ServoGroupRuleRules::List(FILE* out, int32_t aIndent) const
diff --git layout/style/GroupRule.h layout/style/GroupRule.h
index ac9e26921f0b..5c336e5c3611 100644
--- layout/style/GroupRule.h
+++ layout/style/GroupRule.h
@@ -87,6 +87,7 @@ struct ServoGroupRuleRules
// Do we ever clone Servo rules?
MOZ_ASSERT_UNREACHABLE("stylo: Cloning GroupRule not implemented");
}
+ ~ServoGroupRuleRules();
void SetParentRule(GroupRule* aParentRule) {
if (mRuleList) {
diff --git layout/style/MediaList.h layout/style/MediaList.h
index 4e8c12a2461a..b95e6ec26895 100644
--- layout/style/MediaList.h
+++ layout/style/MediaList.h
@@ -84,7 +84,9 @@ protected:
virtual nsresult Delete(const nsAString& aOldMedium) = 0;
virtual nsresult Append(const nsAString& aNewMedium) = 0;
- virtual ~MediaList() {}
+ virtual ~MediaList() {
+ MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
+ }
// not refcounted; sheet will let us know when it goes away
// mStyleSheet is the sheet that needs to be dirtied when this
diff --git layout/style/ServoCSSRuleList.cpp layout/style/ServoCSSRuleList.cpp
index 37ce9be9f337..31f481899964 100644
--- layout/style/ServoCSSRuleList.cpp
+++ layout/style/ServoCSSRuleList.cpp
@@ -234,6 +234,8 @@ ServoCSSRuleList::GetDOMCSSRuleType(uint32_t aIndex) const
ServoCSSRuleList::~ServoCSSRuleList()
{
+ MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
+ MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
DropAllRules();
}
diff --git layout/style/ServoKeyframeRule.cpp layout/style/ServoKeyframeRule.cpp
index 1be82c3100c5..6ca8a1815f8c 100644
--- layout/style/ServoKeyframeRule.cpp
+++ layout/style/ServoKeyframeRule.cpp
@@ -35,7 +35,10 @@ public:
return NS_OK;
}
- void DropReference() { mRule = nullptr; }
+ void DropReference() {
+ mRule = nullptr;
+ mDecls->SetOwningRule(nullptr);
+ }
DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
{
@@ -81,7 +84,9 @@ public:
}
private:
- virtual ~ServoKeyframeDeclaration() {}
+ virtual ~ServoKeyframeDeclaration() {
+ MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
+ }
ServoKeyframeRule* mRule;
RefPtr<ServoDeclarationBlock> mDecls;
@@ -102,6 +107,9 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
ServoKeyframeRule::~ServoKeyframeRule()
{
+ if (mDeclaration) {
+ mDeclaration->DropReference();
+ }
}
NS_IMPL_ADDREF_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
diff --git layout/style/ServoKeyframesRule.cpp layout/style/ServoKeyframesRule.cpp
index 9a7252a5a639..7341b954ec60 100644
--- layout/style/ServoKeyframesRule.cpp
+++ layout/style/ServoKeyframesRule.cpp
@@ -90,7 +90,12 @@ public:
{
mStyleSheet = nullptr;
mParentRule = nullptr;
- DropAllRules();
+ for (css::Rule* rule : mRules) {
+ if (rule) {
+ rule->SetStyleSheet(nullptr);
+ rule->SetParentRule(nullptr);
+ }
+ }
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
@@ -103,15 +108,16 @@ public:
}
private:
- virtual ~ServoKeyframeList() {}
+ virtual ~ServoKeyframeList() {
+ MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
+ MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
+ DropAllRules();
+ }
void DropAllRules()
{
- for (css::Rule* rule : mRules) {
- if (rule) {
- rule->SetStyleSheet(nullptr);
- rule->SetParentRule(nullptr);
- }
+ if (mParentRule || mStyleSheet) {
+ DropReference();
}
mRules.Clear();
mRawRule = nullptr;
@@ -163,6 +169,9 @@ ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
ServoKeyframesRule::~ServoKeyframesRule()
{
+ if (mKeyframeList) {
+ mKeyframeList->DropReference();
+ }
}
NS_IMPL_ADDREF_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
diff --git layout/style/ServoMediaRule.cpp layout/style/ServoMediaRule.cpp
index 002ae20ffd0b..fbda581a377f 100644
--- layout/style/ServoMediaRule.cpp
+++ layout/style/ServoMediaRule.cpp
@@ -24,6 +24,9 @@ ServoMediaRule::ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule,
ServoMediaRule::~ServoMediaRule()
{
+ if (mMediaList) {
+ mMediaList->SetStyleSheet(nullptr);
+ }
}
NS_IMPL_ADDREF_INHERITED(ServoMediaRule, CSSMediaRule)
@@ -33,8 +36,18 @@ NS_IMPL_RELEASE_INHERITED(ServoMediaRule, CSSMediaRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoMediaRule)
NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
-NS_IMPL_CYCLE_COLLECTION_INHERITED(ServoMediaRule, CSSMediaRule,
- mMediaList)
+NS_IMPL_CYCLE_COLLECTION_CLASS(ServoMediaRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
+ if (tmp->mMediaList) {
+ tmp->mMediaList->SetStyleSheet(nullptr);
+ tmp->mMediaList = nullptr;
+ }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
/* virtual */ already_AddRefed<css::Rule>
ServoMediaRule::Clone() const
diff --git layout/style/ServoPageRule.cpp layout/style/ServoPageRule.cpp
index 97c718ed1ba9..93e8ff334122 100644
--- layout/style/ServoPageRule.cpp
+++ layout/style/ServoPageRule.cpp
@@ -26,6 +26,7 @@ ServoPageRuleDeclaration::ServoPageRuleDeclaration(
ServoPageRuleDeclaration::~ServoPageRuleDeclaration()
{
+ mDecls->SetOwningRule(nullptr);
}
// QueryInterface implementation for ServoPageRuleDeclaration
@@ -141,6 +142,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
// NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
// directly because the wrapper is on the declaration, not on us.
tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
+ tmp->mDecls.mDecls->SetOwningRule(nullptr);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
diff --git layout/style/ServoStyleRule.cpp layout/style/ServoStyleRule.cpp
index 1d7470eef037..855e643515f9 100644
--- layout/style/ServoStyleRule.cpp
+++ layout/style/ServoStyleRule.cpp
@@ -28,6 +28,7 @@ ServoStyleRuleDeclaration::ServoStyleRuleDeclaration(
ServoStyleRuleDeclaration::~ServoStyleRuleDeclaration()
{
+ mDecls->SetOwningRule(nullptr);
}
// QueryInterface implementation for ServoStyleRuleDeclaration
diff --git layout/style/nsCSSRules.cpp layout/style/nsCSSRules.cpp
index 5081244c6a53..0bdedc4a3b03 100644
--- layout/style/nsCSSRules.cpp
+++ layout/style/nsCSSRules.cpp
@@ -212,12 +212,25 @@ ImportRule::~ImportRule()
NS_IMPL_ADDREF_INHERITED(ImportRule, CSSImportRule)
NS_IMPL_RELEASE_INHERITED(ImportRule, CSSImportRule)
-NS_IMPL_CYCLE_COLLECTION_INHERITED(ImportRule, CSSImportRule, mMedia, mChildSheet)
-
// QueryInterface implementation for ImportRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ImportRule)
NS_INTERFACE_MAP_END_INHERITING(CSSImportRule)
+NS_IMPL_CYCLE_COLLECTION_CLASS(ImportRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ImportRule, CSSImportRule)
+ if (tmp->mChildSheet) {
+ tmp->mChildSheet->SetOwnerRule(nullptr);
+ tmp->mChildSheet = nullptr;
+ }
+ tmp->mMedia = nullptr;
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ImportRule, CSSImportRule)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMedia)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildSheet)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
#ifdef DEBUG
/* virtual */ void
ImportRule::List(FILE* out, int32_t aIndent) const
@@ -342,8 +355,18 @@ NS_IMPL_RELEASE_INHERITED(MediaRule, CSSMediaRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaRule)
NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaRule, CSSMediaRule,
- mMedia)
+NS_IMPL_CYCLE_COLLECTION_CLASS(MediaRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRule, CSSMediaRule)
+ if (tmp->mMedia) {
+ tmp->mMedia->SetStyleSheet(nullptr);
+ tmp->mMedia = nullptr;
+ }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRule, CSSMediaRule)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMedia)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
/* virtual */ void
MediaRule::SetStyleSheet(StyleSheet* aSheet)

View File

@ -0,0 +1,25 @@
commit bd17df85baf4
Author: Andrea Marchesini <amarchesini@mozilla.com>
Date: Tue Nov 14 08:18:41 2017 +0100
Bug 1413741 - Improve the use of XHR.mProxy in workers after the dispatching of sync OpenRunnable, r=smaug a=gchang
--HG--
extra : source : 063022b93ec40d00601a21b92525a4285f984484
---
dom/xhr/XMLHttpRequestWorker.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git dom/xhr/XMLHttpRequestWorker.cpp dom/xhr/XMLHttpRequestWorker.cpp
index c337bb258767..9954da23493f 100644
--- dom/xhr/XMLHttpRequestWorker.cpp
+++ dom/xhr/XMLHttpRequestWorker.cpp
@@ -1895,7 +1895,7 @@ XMLHttpRequestWorker::Open(const nsACString& aMethod,
++mProxy->mOpenCount;
runnable->Dispatch(Terminating, aRv);
if (aRv.Failed()) {
- if (!--mProxy->mOpenCount) {
+ if (mProxy && !--mProxy->mOpenCount) {
ReleaseProxy();
}

View File

@ -0,0 +1,231 @@
commit 8dce7d3eb6a3
Author: Valentin Gosu <valentin.gosu@gmail.com>
Date: Thu Nov 9 16:32:51 2017 +0100
Bug 1414425 - Make sure the appropriate triggeringPrincipal is set for a meta refresh. r=bz, a=gchang
MozReview-Commit-ID: 4Kn6P4hnx74
--HG--
extra : source : 229546747cbf04cf71a235275d7c2eb2520a298b
---
browser/base/content/tab-content.js | 2 +-
.../content/test/general/browser_refreshBlocker.js | 2 +-
docshell/base/nsDocShell.cpp | 28 +++++++++++++++-------
docshell/base/nsDocShell.h | 12 +++++++---
docshell/base/nsIRefreshURI.idl | 23 ++++++++++++++----
5 files changed, 50 insertions(+), 17 deletions(-)
diff --git browser/base/content/tab-content.js browser/base/content/tab-content.js
index 4d85ada0321b..5497a1cc208d 100644
--- browser/base/content/tab-content.js
+++ browser/base/content/tab-content.js
@@ -995,7 +995,7 @@ var RefreshBlocker = {
let URI = Services.io.newURI(data.URI);
- refreshURI.forceRefreshURI(URI, data.delay, true);
+ refreshURI.forceRefreshURI(URI, null, data.delay, true);
}
},
diff --git browser/base/content/test/general/browser_refreshBlocker.js browser/base/content/test/general/browser_refreshBlocker.js
index cd82cf40b479..4a280d4cb12b 100644
--- browser/base/content/test/general/browser_refreshBlocker.js
+++ browser/base/content/test/general/browser_refreshBlocker.js
@@ -20,7 +20,7 @@ async function attemptFakeRefresh(browser, expectRefresh) {
await ContentTask.spawn(browser, expectRefresh, async function(contentExpectRefresh) {
let URI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
let refresher = docShell.QueryInterface(Ci.nsIRefreshURI);
- refresher.refreshURI(URI, 0, false, true);
+ refresher.refreshURI(URI, null, 0, false, true);
Assert.equal(refresher.refreshPending, contentExpectRefresh,
"Got the right refreshPending state");
diff --git docshell/base/nsDocShell.cpp docshell/base/nsDocShell.cpp
index 3ded70a66fe8..83cb87dd8255 100644
--- docshell/base/nsDocShell.cpp
+++ docshell/base/nsDocShell.cpp
@@ -6831,7 +6831,8 @@ nsDocShell::ScrollByPages(int32_t aNumPages)
//*****************************************************************************
NS_IMETHODIMP
-nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
+nsDocShell::RefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
+ int32_t aDelay, bool aRepeat,
bool aMetaRefresh)
{
NS_ENSURE_ARG(aURI);
@@ -6860,7 +6861,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
}
nsCOMPtr<nsITimerCallback> refreshTimer =
- new nsRefreshTimer(this, aURI, aDelay, aRepeat, aMetaRefresh);
+ new nsRefreshTimer(this, aURI, aPrincipal, aDelay, aRepeat, aMetaRefresh);
uint32_t busyFlags = 0;
GetBusyFlags(&busyFlags);
@@ -6891,6 +6892,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
nsresult
nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI,
+ nsIPrincipal* aPrincipal,
int32_t aDelay,
bool aMetaRefresh,
nsITimer* aTimer)
@@ -6911,11 +6913,11 @@ nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI,
}
}
- return ForceRefreshURI(aURI, aDelay, aMetaRefresh);
+ return ForceRefreshURI(aURI, aPrincipal, aDelay, aMetaRefresh);
}
NS_IMETHODIMP
-nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh)
+nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal, int32_t aDelay, bool aMetaRefresh)
{
NS_ENSURE_ARG(aURI);
@@ -6963,6 +6965,13 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh)
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
}
+ // If the principal is null, the refresh will have a triggeringPrincipal
+ // derived from the referrer URI, or will be set to the system principal
+ // if there is no refererrer. See LoadURI()
+ if (aPrincipal) {
+ loadInfo->SetTriggeringPrincipal(aPrincipal);
+ }
+
/*
* LoadURI(...) will cancel all refresh timers... This causes the
* Timer and its refreshData instance to be released...
@@ -7203,7 +7212,7 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI* aBaseURI,
return NS_ERROR_FAILURE;
}
- rv = RefreshURI(uri, seconds * 1000, false, true);
+ rv = RefreshURI(uri, aPrincipal, seconds * 1000, false, true);
}
}
}
@@ -13793,9 +13802,12 @@ nsDocShell::SetLayoutHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
return NS_OK;
}
-nsRefreshTimer::nsRefreshTimer(nsDocShell* aDocShell, nsIURI* aURI,
+nsRefreshTimer::nsRefreshTimer(nsDocShell* aDocShell,
+ nsIURI* aURI,
+ nsIPrincipal* aPrincipal,
int32_t aDelay, bool aRepeat, bool aMetaRefresh)
- : mDocShell(aDocShell), mURI(aURI), mDelay(aDelay), mRepeat(aRepeat),
+ : mDocShell(aDocShell), mURI(aURI), mPrincipal(aPrincipal),
+ mDelay(aDelay), mRepeat(aRepeat),
mMetaRefresh(aMetaRefresh)
{
}
@@ -13822,7 +13834,7 @@ nsRefreshTimer::Notify(nsITimer* aTimer)
// Get the delay count to determine load type
uint32_t delay = 0;
aTimer->GetDelay(&delay);
- mDocShell->ForceRefreshURIFromTimer(mURI, delay, mMetaRefresh, aTimer);
+ mDocShell->ForceRefreshURIFromTimer(mURI, mPrincipal, delay, mMetaRefresh, aTimer);
}
return NS_OK;
}
diff --git docshell/base/nsDocShell.h docshell/base/nsDocShell.h
index f805deaa2edf..57fc63fe5795 100644
--- docshell/base/nsDocShell.h
+++ docshell/base/nsDocShell.h
@@ -114,8 +114,12 @@ class nsRefreshTimer : public nsITimerCallback
, public nsINamed
{
public:
- nsRefreshTimer(nsDocShell* aDocShell, nsIURI* aURI, int32_t aDelay,
- bool aRepeat, bool aMetaRefresh);
+ nsRefreshTimer(nsDocShell* aDocShell,
+ nsIURI* aURI,
+ nsIPrincipal* aPrincipal,
+ int32_t aDelay,
+ bool aRepeat,
+ bool aMetaRefresh);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
@@ -125,6 +129,7 @@ public:
RefPtr<nsDocShell> mDocShell;
nsCOMPtr<nsIURI> mURI;
+ nsCOMPtr<nsIPrincipal> mPrincipal;
int32_t mDelay;
bool mRepeat;
bool mMetaRefresh;
@@ -259,7 +264,8 @@ public:
// ForceRefreshURI method on nsIRefreshURI, but makes sure to take
// the timer involved out of mRefreshURIList if it's there.
// aTimer must not be null.
- nsresult ForceRefreshURIFromTimer(nsIURI* aURI, int32_t aDelay,
+ nsresult ForceRefreshURIFromTimer(nsIURI* aURI, nsIPrincipal* aPrincipal,
+ int32_t aDelay,
bool aMetaRefresh, nsITimer* aTimer);
friend class OnLinkClickEvent;
diff --git docshell/base/nsIRefreshURI.idl docshell/base/nsIRefreshURI.idl
index f872d8b7f5cf..3e85e4c516c6 100644
--- docshell/base/nsIRefreshURI.idl
+++ docshell/base/nsIRefreshURI.idl
@@ -18,23 +18,33 @@ interface nsIRefreshURI : nsISupports {
* queued and executed when the current load finishes.
*
* @param aUri The uri to refresh.
+ * @param aPrincipal The triggeringPrincipal for the refresh load
+ * May be null, in which case a principal will be built based on the
+ * referrer URI of the previous docshell load, or will use the system
+ * principal when there is no referrer.
* @param aMillis The number of milliseconds to wait.
* @param aRepeat Flag to indicate if the uri is to be
* repeatedly refreshed every aMillis milliseconds.
* @param aMetaRefresh Flag to indicate if this is a Meta refresh.
*/
- void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat,
+ void refreshURI(in nsIURI aURI, in nsIPrincipal aPrincipal,
+ in long aMillis, in boolean aRepeat,
in boolean aMetaRefresh);
/**
* Loads a URI immediately as if it were a refresh.
*
* @param aURI The URI to refresh.
+ * @param aPrincipal The triggeringPrincipal for the refresh load
+ * May be null, in which case a principal will be built based on the
+ * referrer URI of the previous docshell load, or will use the system
+ * principal when there is no referrer.
* @param aMillis The number of milliseconds by which this refresh would
* be delayed if it were not being forced.
* @param aMetaRefresh Flag to indicate if this is a meta refresh.
*/
- void forceRefreshURI(in nsIURI aURI, in long aMillis, in boolean aMetaRefresh);
+ void forceRefreshURI(in nsIURI aURI, in nsIPrincipal aPrincipal,
+ in long aMillis, in boolean aMetaRefresh);
/**
* Checks the passed in channel to see if there is a refresh header,
@@ -57,10 +67,15 @@ interface nsIRefreshURI : nsISupports {
* the current page finishes loading.
*
* @param aBaseURI base URI to resolve refresh uri with.
- * @param principal the associated principal
+ * @param aPrincipal The triggeringPrincipal for the refresh load
+ * May be null, in which case a principal will be built based on the
+ * referrer URI of the previous docshell load, or will use the system
+ * principal when there is no referrer.
* @param aHeader The meta refresh header string.
*/
- void setupRefreshURIFromHeader(in nsIURI aBaseURI, in nsIPrincipal principal, in ACString aHeader);
+ void setupRefreshURIFromHeader(in nsIURI aBaseURI,
+ in nsIPrincipal principal,
+ in ACString aHeader);
/**
* Cancels all timer loads.

View File

@ -0,0 +1,70 @@
commit 24a8b8309514
Author: Olli Pettay <Olli.Pettay@helsinki.fi>
Date: Tue Nov 28 16:17:17 2017 +0200
Bug 1414452 - Clear dirAutoSetBy properties iteratively. r=peterv, a=abillings
--HG--
extra : source : 157a15cd5ecc8706b502f78c51e79b58ac59eaf0
---
dom/base/DirectionalityUtils.cpp | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git dom/base/DirectionalityUtils.cpp dom/base/DirectionalityUtils.cpp
index fb443e23688c..f132c8970fe7 100644
--- dom/base/DirectionalityUtils.cpp
+++ dom/base/DirectionalityUtils.cpp
@@ -419,7 +419,7 @@ class nsTextNodeDirectionalityMap
nsTextNodeDirectionalityMap* map =
reinterpret_cast<nsTextNodeDirectionalityMap * >(aPropertyValue);
- map->EnsureMapIsClear(textNode);
+ map->EnsureMapIsClear();
delete map;
}
@@ -548,11 +548,11 @@ private:
return OpRemove;
}
- static nsCheapSetOperator ClearEntry(nsPtrHashKey<Element>* aEntry, void* aData)
+ static nsCheapSetOperator TakeEntries(nsPtrHashKey<Element>* aEntry, void* aData)
{
- Element* rootNode = aEntry->GetKey();
- rootNode->ClearHasDirAutoSet();
- rootNode->DeleteProperty(nsGkAtoms::dirAutoSetBy);
+ AutoTArray<Element*, 8>* entries =
+ static_cast<AutoTArray<Element*, 8>*>(aData);
+ entries->AppendElement(aEntry->GetKey());
return OpRemove;
}
@@ -568,12 +568,15 @@ public:
mElements.EnumerateEntries(ResetNodeDirection, &data);
}
- void EnsureMapIsClear(nsINode* aTextNode)
+ void EnsureMapIsClear()
{
AutoRestore<Element*> restore(mElementToBeRemoved);
- DebugOnly<uint32_t> clearedEntries =
- mElements.EnumerateEntries(ClearEntry, aTextNode);
- MOZ_ASSERT(clearedEntries == 0, "Map should be empty already");
+ AutoTArray<Element*, 8> entries;
+ mElements.EnumerateEntries(TakeEntries, &entries);
+ for (Element* el : entries) {
+ el->ClearHasDirAutoSet();
+ el->DeleteProperty(nsGkAtoms::dirAutoSetBy);
+ }
}
static void RemoveElementFromMap(nsTextNode* aTextNode, Element* aElement)
@@ -613,7 +616,7 @@ public:
static void EnsureMapIsClearFor(nsINode* aTextNode)
{
if (aTextNode->HasTextNodeDirectionalityMap()) {
- GetDirectionalityMap(aTextNode)->EnsureMapIsClear(aTextNode);
+ GetDirectionalityMap(aTextNode)->EnsureMapIsClear();
}
}
};

View File

@ -0,0 +1,43 @@
commit 26740772e0c9
Author: Philip Chimento <philip.chimento@gmail.com>
Date: Mon Nov 6 15:49:15 2017 -0800
Bug 1414945 - Don't use TimeDuration in static initializer. r=jandem
On Darwin this would cause a race between two static initializers.
--HG--
extra : rebase_source : 0547c4018334f7112022f1893c5f36a47dc14501
---
js/src/shell/js.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git js/src/shell/js.cpp js/src/shell/js.cpp
index afb4990ecc0f..f8f81446c7ae 100644
--- js/src/shell/js.cpp
+++ js/src/shell/js.cpp
@@ -150,7 +150,7 @@ static const size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
* Limit the timeout to 30 minutes to prevent an overflow on platfoms
* that represent the time internally in microseconds using 32-bit int.
*/
-static const TimeDuration MAX_TIMEOUT_INTERVAL = TimeDuration::FromSeconds(1800.0);
+static const double MAX_TIMEOUT_SECONDS = 1800.0;
// SharedArrayBuffer and Atomics are enabled by default (tracking Firefox).
#define SHARED_MEMORY_DEFAULT 1
@@ -3852,6 +3852,7 @@ Sleep_fn(JSContext* cx, unsigned argc, Value* vp)
}
duration = TimeDuration::FromSeconds(Max(0.0, t_secs));
+ const TimeDuration MAX_TIMEOUT_INTERVAL = TimeDuration::FromSeconds(MAX_TIMEOUT_SECONDS);
if (duration > MAX_TIMEOUT_INTERVAL) {
JS_ReportErrorASCII(cx, "Excessive sleep interval");
return false;
@@ -4019,6 +4020,7 @@ SetTimeoutValue(JSContext* cx, double t)
JS_ReportErrorASCII(cx, "timeout is not a number");
return false;
}
+ const TimeDuration MAX_TIMEOUT_INTERVAL = TimeDuration::FromSeconds(MAX_TIMEOUT_SECONDS);
if (TimeDuration::FromSeconds(t) > MAX_TIMEOUT_INTERVAL) {
JS_ReportErrorASCII(cx, "Excessive timeout value");
return false;

View File

@ -0,0 +1,22 @@
commit 8b02d6d479da
Author: JW Wang <jwwang@mozilla.com>
Date: Fri Dec 8 10:01:18 2017 +0800
Bug 1415441 - Eagerly init gMediaDecoderLog to debug crash. r=cpearce, a=jcristau
---
dom/media/MediaDecoder.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git dom/media/MediaDecoder.cpp dom/media/MediaDecoder.cpp
index cbf97ddf084d..5de31894d9d9 100644
--- dom/media/MediaDecoder.cpp
+++ dom/media/MediaDecoder.cpp
@@ -280,6 +280,8 @@ void
MediaDecoder::InitStatics()
{
MOZ_ASSERT(NS_IsMainThread());
+ // Eagerly init gMediaDecoderLog to work around bug 1415441.
+ MOZ_LOG(gMediaDecoderLog, LogLevel::Info, ("MediaDecoder::InitStatics"));
}
NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)

View File

@ -0,0 +1,34 @@
commit 1ab98367b3c1
Author: Randell Jesup <rjesup@jesup.org>
Date: Wed Nov 8 11:00:24 2017 -0500
Bug 1415582 - Mirror changes done to Encoder InitDone to decoder. r=bwc, a=gchang
--HG--
extra : source : 833205c1f498bed137fb2e0a06d14ef31e3c0609
---
media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
index b8067a278f18..50189c488df1 100644
--- media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
+++ media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
@@ -449,7 +449,7 @@ private:
class InitDoneCallback : public GetGMPVideoDecoderCallback
{
public:
- explicit InitDoneCallback(WebrtcGmpVideoDecoder* aDecoder,
+ explicit InitDoneCallback(const RefPtr<WebrtcGmpVideoDecoder>& aDecoder,
const RefPtr<GmpInitDoneRunnable>& aInitDone)
: mDecoder(aDecoder),
mInitDone(aInitDone)
@@ -465,7 +465,7 @@ private:
}
private:
- WebrtcGmpVideoDecoder* mDecoder;
+ RefPtr<WebrtcGmpVideoDecoder> mDecoder;
RefPtr<GmpInitDoneRunnable> mInitDone;
};

View File

@ -0,0 +1,58 @@
commit 63db080ae5cb
Author: Marco Bonardo <mbonardo@mozilla.com>
Date: Thu Dec 7 15:28:41 2017 +0100
Bug 1415598. r=gijs, a=jcristau
--HG--
extra : source : 94f1fb1043a81e619d7b73d48a86d66d1cf4eebc
---
toolkit/components/places/History.cpp | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git toolkit/components/places/History.cpp toolkit/components/places/History.cpp
index 94755d3bdde5..b3618c065601 100644
--- toolkit/components/places/History.cpp
+++ toolkit/components/places/History.cpp
@@ -1955,6 +1955,7 @@ History::InitMemoryReporter()
NS_IMETHODIMP
History::NotifyVisited(nsIURI* aURI)
{
+ MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG(aURI);
nsAutoScriptBlocker scriptBlocker;
@@ -2565,6 +2566,7 @@ NS_IMETHODIMP
History::RegisterVisitedCallback(nsIURI* aURI,
Link* aLink)
{
+ MOZ_ASSERT(NS_IsMainThread());
NS_ASSERTION(aURI, "Must pass a non-null URI!");
if (XRE_IsContentProcess()) {
NS_PRECONDITION(aLink, "Must pass a non-null Link!");
@@ -2594,7 +2596,16 @@ History::RegisterVisitedCallback(nsIURI* aURI,
if (NS_FAILED(rv) || !aLink) {
// Remove our array from the hashtable so we don't keep it around.
MOZ_ASSERT(key == mObservers.GetEntry(aURI), "The URIs hash mutated!");
- mObservers.RemoveEntry(key);
+ // In some case calling RemoveEntry on the key obtained by PutEntry
+ // crashes for currently unknown reasons. Our suspect is that something
+ // between PutEntry and this call causes a nested loop that either removes
+ // the entry or reallocs the hash.
+ // TODO (Bug 1412647): we must figure the root cause for these issues and
+ // remove this stop-gap crash fix.
+ key = mObservers.GetEntry(aURI);
+ if (key) {
+ mObservers.RemoveEntry(key);
+ }
return rv;
}
}
@@ -2626,6 +2637,7 @@ NS_IMETHODIMP
History::UnregisterVisitedCallback(nsIURI* aURI,
Link* aLink)
{
+ MOZ_ASSERT(NS_IsMainThread());
// TODO: aURI is sometimes null - see bug 548685
NS_ASSERTION(aURI, "Must pass a non-null URI!");
NS_ASSERTION(aLink, "Must pass a non-null Link object!");

View File

@ -0,0 +1,25 @@
commit 95077ef89979
Author: Dan Minor <dminor@mozilla.com>
Date: Mon Nov 20 07:09:19 2017 -0500
Bug 1417797 - Stop callback in WebrtcGmpVideoDecoder::ReleaseGmp. r=jesup, a=gchang
--HG--
extra : source : d0eb2fe1a7389d40d1abdccbeeaef9c4b30ae7b1
---
media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
index 53212d888dcb..e3063ea3fefb 100644
--- media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
+++ media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
@@ -923,6 +923,8 @@ int32_t
WebrtcGmpVideoDecoder::ReleaseGmp()
{
LOGD(("GMP Released:"));
+ RegisterDecodeCompleteCallback(nullptr);
+
if (mGMPThread) {
mGMPThread->Dispatch(
WrapRunnableNM(&WebrtcGmpVideoDecoder::ReleaseGmp_g,

View File

@ -0,0 +1,26 @@
commit 69f7bf805f94
Author: Lee Salzman <lsalzman@mozilla.com>
Date: Tue Nov 21 16:55:20 2017 -0500
Bug 1418447 - Limit Skia edge builder allocations. r=milan, a=abillings
MozReview-Commit-ID: 1SnxwtoYJJm
--HG--
extra : source : a81b848ebcc668f10a73eff586cebed570533b48
---
gfx/skia/skia/src/core/SkEdgeBuilder.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git gfx/skia/skia/src/core/SkEdgeBuilder.cpp gfx/skia/skia/src/core/SkEdgeBuilder.cpp
index ceb8f1ad3105..af8da00a2f04 100644
--- gfx/skia/skia/src/core/SkEdgeBuilder.cpp
+++ gfx/skia/skia/src/core/SkEdgeBuilder.cpp
@@ -248,6 +248,7 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
// clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
// we turn portions that are clipped out on the left/right into vertical
// segments.
+ SkASSERT_RELEASE(maxEdgeCount <= std::numeric_limits<int>::max() / SkLineClipper::kMaxClippedLineSegments);
maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments;
}

View File

@ -0,0 +1,102 @@
commit 1fe2b37624d6
Author: Michal Novotny <michal.novotny@gmail.com>
Date: Wed Dec 6 20:48:06 2017 -0500
Bug 1418854 - Race condition in AutoClose. r=honzab, a=jcristau
--HG--
extra : source : 3e425d2e71df08dc944a26eaa41158522a75ff02
---
netwerk/base/AutoClose.h | 43 ++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git netwerk/base/AutoClose.h netwerk/base/AutoClose.h
index 8c401071428f..43ab27133fdd 100644
--- netwerk/base/AutoClose.h
+++ netwerk/base/AutoClose.h
@@ -8,6 +8,7 @@
#define mozilla_net_AutoClose_h
#include "nsCOMPtr.h"
+#include "mozilla/Mutex.h"
namespace mozilla { namespace net {
@@ -18,49 +19,48 @@ template <typename T>
class AutoClose
{
public:
- AutoClose() { }
+ AutoClose() : mMutex("net::AutoClose.mMutex") { }
~AutoClose(){
- Close();
+ CloseAndRelease();
}
- explicit operator bool() const
+ explicit operator bool()
{
+ MutexAutoLock lock(mMutex);
return mPtr;
}
already_AddRefed<T> forget()
{
+ MutexAutoLock lock(mMutex);
return mPtr.forget();
}
void takeOver(nsCOMPtr<T> & rhs)
{
- Close();
- mPtr = rhs.forget();
- }
-
- void takeOver(AutoClose<T> & rhs)
- {
- Close();
- mPtr = rhs.mPtr.forget();
+ already_AddRefed<T> other = rhs.forget();
+ TakeOverInternal(&other);
}
void CloseAndRelease()
{
- Close();
- mPtr = nullptr;
- }
-
- T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
- {
- return mPtr.operator->();
+ TakeOverInternal(nullptr);
}
private:
- void Close()
+ void TakeOverInternal(already_AddRefed<T> *aOther)
{
- if (mPtr) {
- mPtr->Close();
+ nsCOMPtr<T> ptr;
+ {
+ MutexAutoLock lock(mMutex);
+ ptr.swap(mPtr);
+ if (aOther) {
+ mPtr = *aOther;
+ }
+ }
+
+ if (ptr) {
+ ptr->Close();
}
}
@@ -68,6 +68,7 @@ private:
AutoClose(const AutoClose<T> &) = delete;
nsCOMPtr<T> mPtr;
+ Mutex mMutex;
};
} // namespace net

View File

@ -0,0 +1,32 @@
commit 2eda8f3435d6
Author: Andreas Pehrson <pehrsons@mozilla.com>
Date: Fri Dec 1 10:52:18 2017 -0500
Bug 1419363 - Switch to WeakPtr. r=jib a=gchang
--HG--
extra : source : e0a21cc26e07b19383d2bf5038b88eed211de53e
---
dom/html/HTMLMediaElement.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git dom/html/HTMLMediaElement.cpp dom/html/HTMLMediaElement.cpp
index 12ea373e8782..285a36400ad9 100644
--- dom/html/HTMLMediaElement.cpp
+++ dom/html/HTMLMediaElement.cpp
@@ -5168,11 +5168,14 @@ public:
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
+ if (!mElement) {
+ return;
+ }
mElement->NotifyMediaStreamTracksAvailable(aStream);
}
private:
- HTMLMediaElement* mElement;
+ WeakPtr<HTMLMediaElement> mElement;
};
class HTMLMediaElement::MediaStreamTrackListener :

View File

@ -0,0 +1,28 @@
commit 25e68494fad3
Author: Jan-Ivar Bruaroey <jib@mozilla.com>
Date: Fri Dec 1 20:49:46 2017 -0500
Bug 1422389 - Limit default engine resolution. r=mchiang, a=abillings
MozReview-Commit-ID: LS1z7I4myeb
--HG--
extra : rebase_source : 200216163b4555ede8912e64871eea81eb8affac
extra : source : f0fd6e20a13d11660a5ac57e9703f09978f12acb
---
dom/media/webrtc/MediaEngineDefault.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git dom/media/webrtc/MediaEngineDefault.cpp dom/media/webrtc/MediaEngineDefault.cpp
index ea5996e92e23..01efb04b5df8 100644
--- dom/media/webrtc/MediaEngineDefault.cpp
+++ dom/media/webrtc/MediaEngineDefault.cpp
@@ -120,6 +120,8 @@ MediaEngineDefaultVideoSource::Allocate(const dom::MediaTrackConstraints &aConst
MediaEngine::DEFAULT_43_VIDEO_HEIGHT
#endif
);
+ mOpts.mWidth = std::max(160, std::min(mOpts.mWidth, 4096));
+ mOpts.mHeight = std::max(90, std::min(mOpts.mHeight, 2160));
mState = kAllocated;
*aOutHandle = nullptr;
return NS_OK;

View File

@ -0,0 +1,222 @@
commit 96370abe22e4
Author: Byron Campen [:bwc] <docfaraday@gmail.com>
Date: Mon Dec 18 12:36:23 2017 -0600
Bug 1423086: (beta backport) Use nsITimerCallback for DTMF timers. r=drno a=ritu
MozReview-Commit-ID: 2IlDknNhlAG
--HG--
extra : rebase_source : 344b2b1b10084099a37fb793fc25b71144a4428c
---
.../src/peerconnection/PeerConnectionImpl.cpp | 72 +++++++++++-----------
.../src/peerconnection/PeerConnectionImpl.h | 28 +++++----
2 files changed, 51 insertions(+), 49 deletions(-)
diff --git media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index 68949feb7254..edb07486b45a 100644
--- media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -2521,8 +2521,8 @@ PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
nsString wideTrackId;
aTrack.GetId(wideTrackId);
for (size_t i = 0; i < mDTMFStates.Length(); ++i) {
- if (mDTMFStates[i].mTrackId == wideTrackId) {
- mDTMFStates[i].mSendTimer->Cancel();
+ if (mDTMFStates[i]->mTrackId == wideTrackId) {
+ mDTMFStates[i]->mSendTimer->Cancel();
mDTMFStates.RemoveElementAt(i);
break;
}
@@ -2593,17 +2593,17 @@ PeerConnectionImpl::InsertDTMF(mozilla::dom::RTCRtpSender& sender,
mst->GetId(senderTrackId);
// Attempt to locate state for the DTMFSender
- DTMFState* state = nullptr;
+ RefPtr<DTMFState> state;
for (auto& dtmfState : mDTMFStates) {
- if (dtmfState.mTrackId == senderTrackId) {
- state = &dtmfState;
+ if (dtmfState->mTrackId == senderTrackId) {
+ state = dtmfState;
break;
}
}
// No state yet, create a new one
if (!state) {
- state = mDTMFStates.AppendElement();
+ state = *mDTMFStates.AppendElement(new DTMFState);
state->mPeerConnectionImpl = this;
state->mTrackId = senderTrackId;
state->mSendTimer = NS_NewTimer();
@@ -2627,9 +2627,7 @@ PeerConnectionImpl::InsertDTMF(mozilla::dom::RTCRtpSender& sender,
state->mDuration = duration;
state->mInterToneGap = interToneGap;
if (!state->mTones.IsEmpty()) {
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state, 0,
- nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
+ state->mSendTimer->InitWithCallback(state, 0, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
@@ -2653,8 +2651,8 @@ PeerConnectionImpl::GetDTMFToneBuffer(mozilla::dom::RTCRtpSender& sender,
// Attempt to locate state for the DTMFSender
for (auto& dtmfState : mDTMFStates) {
- if (dtmfState.mTrackId == senderTrackId) {
- outToneBuffer = dtmfState.mTones;
+ if (dtmfState->mTrackId == senderTrackId) {
+ outToneBuffer = dtmfState->mTones;
break;
}
}
@@ -2671,8 +2669,8 @@ PeerConnectionImpl::ReplaceTrack(MediaStreamTrack& aThisTrack,
aThisTrack.GetId(trackId);
for (size_t i = 0; i < mDTMFStates.Length(); ++i) {
- if (mDTMFStates[i].mTrackId == trackId) {
- mDTMFStates[i].mSendTimer->Cancel();
+ if (mDTMFStates[i]->mTrackId == trackId) {
+ mDTMFStates[i]->mSendTimer->Cancel();
mDTMFStates.RemoveElementAt(i);
break;
}
@@ -3117,7 +3115,7 @@ PeerConnectionImpl::CloseInt()
PC_AUTO_ENTER_API_CALL_NO_CHECK();
for (auto& dtmfState : mDTMFStates) {
- dtmfState.mSendTimer->Cancel();
+ dtmfState->mSendTimer->Cancel();
}
// We do this at the end of the call because we want to make sure we've waited
@@ -4201,63 +4199,63 @@ PeerConnectionImpl::GetRemoteStreams(nsTArray<RefPtr<DOMMediaStream > >& result)
return NS_OK;
}
-void
-PeerConnectionImpl::DTMFSendTimerCallback_m(nsITimer* timer, void* closure)
+nsresult
+PeerConnectionImpl::DTMFState::Notify(nsITimer* timer)
{
MOZ_ASSERT(NS_IsMainThread());
- auto state = static_cast<DTMFState*>(closure);
-
nsString eventTone;
- if (!state->mTones.IsEmpty()) {
- uint16_t toneChar = state->mTones.CharAt(0);
+ if (!mTones.IsEmpty()) {
+ uint16_t toneChar = mTones.CharAt(0);
int tone = GetDTMFToneCode(toneChar);
eventTone.Assign(toneChar);
- state->mTones.Cut(0, 1);
+ mTones.Cut(0, 1);
if (tone == -1) {
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state,
- 2000, nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
+ mSendTimer->InitWithCallback(this, 2000, nsITimer::TYPE_ONE_SHOT);
} else {
// Reset delay if necessary
- state->mSendTimer->InitWithNamedFuncCallback(DTMFSendTimerCallback_m, state,
- state->mDuration + state->mInterToneGap,
- nsITimer::TYPE_ONE_SHOT,
- "DTMFSendTimerCallback_m");
+ mSendTimer->InitWithCallback(this,
+ mDuration + mInterToneGap,
+ nsITimer::TYPE_ONE_SHOT);
RefPtr<AudioSessionConduit> conduit =
- state->mPeerConnectionImpl->mMedia->GetAudioConduit(state->mLevel);
+ mPeerConnectionImpl->mMedia->GetAudioConduit(mLevel);
if (conduit) {
- uint32_t duration = state->mDuration;
- state->mPeerConnectionImpl->mSTSThread->Dispatch(WrapRunnableNM([conduit, tone, duration] () {
+ uint32_t duration = mDuration;
+ mPeerConnectionImpl->mSTSThread->Dispatch(WrapRunnableNM([conduit, tone, duration] () {
//Note: We default to channel 0, not inband, and 6dB attenuation.
// here. We might want to revisit these choices in the future.
conduit->InsertDTMFTone(0, tone, true, duration, 6);
}), NS_DISPATCH_NORMAL);
}
-
}
} else {
- state->mSendTimer->Cancel();
+ mSendTimer->Cancel();
}
- RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(state->mPeerConnectionImpl->mPCObserver);
+ RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPeerConnectionImpl->mPCObserver);
if (!pco) {
NS_WARNING("Failed to dispatch the RTCDTMFToneChange event!");
- return;
+ return NS_OK; // Return is ignored anyhow
}
JSErrorResult jrv;
- pco->OnDTMFToneChange(state->mTrackId, eventTone, jrv);
+ pco->OnDTMFToneChange(mTrackId, eventTone, jrv);
if (jrv.Failed()) {
NS_WARNING("Failed to dispatch the RTCDTMFToneChange event!");
- return;
}
+
+ return NS_OK;
}
+PeerConnectionImpl::DTMFState::DTMFState() = default;
+PeerConnectionImpl::DTMFState::~DTMFState() = default;
+
+NS_IMPL_ISUPPORTS(PeerConnectionImpl::DTMFState, nsITimerCallback)
+
} // end mozilla namespace
diff --git media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 3090a25bf57e..5213931161fc 100644
--- media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -829,20 +829,24 @@ private:
uint16_t mMaxSending[SdpMediaSection::kMediaTypes];
// DTMF
- struct DTMFState {
- PeerConnectionImpl* mPeerConnectionImpl;
- nsCOMPtr<nsITimer> mSendTimer;
- nsString mTrackId;
- nsString mTones;
- size_t mLevel;
- uint32_t mDuration;
- uint32_t mInterToneGap;
+ class DTMFState : public nsITimerCallback {
+ virtual ~DTMFState();
+ public:
+ DTMFState();
+
+ NS_DECL_NSITIMERCALLBACK
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ PeerConnectionImpl* mPeerConnectionImpl;
+ nsCOMPtr<nsITimer> mSendTimer;
+ nsString mTrackId;
+ nsString mTones;
+ size_t mLevel;
+ uint32_t mDuration;
+ uint32_t mInterToneGap;
};
- static void
- DTMFSendTimerCallback_m(nsITimer* timer, void*);
-
- nsTArray<DTMFState> mDTMFStates;
+ nsTArray<RefPtr<DTMFState>> mDTMFStates;
std::vector<unsigned> mSendPacketDumpFlags;
std::vector<unsigned> mRecvPacketDumpFlags;

View File

@ -0,0 +1,69 @@
commit 6508b1194af3
Author: Olli Pettay <Olli.Pettay@helsinki.fi>
Date: Sun Dec 10 14:49:49 2017 -0500
Bug 1423159 - Ensure proper multiprocess mouse enter/exit handling. r=stone, a=abillings
--HG--
extra : source : 689357a9394830406290ae1fb2200521a99bd7ad
---
dom/events/EventStateManager.cpp | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git dom/events/EventStateManager.cpp dom/events/EventStateManager.cpp
index 441036b5c5bf..f076f8ae0f09 100644
--- dom/events/EventStateManager.cpp
+++ dom/events/EventStateManager.cpp
@@ -4041,33 +4041,36 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
return nullptr;
}
+ nsCOMPtr<nsIContent> targetContent = aTargetContent;
+ nsCOMPtr<nsIContent> relatedContent = aRelatedContent;
+
nsAutoPtr<WidgetMouseEvent> dispatchEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, aMessage,
- aRelatedContent, dispatchEvent);
+ relatedContent, dispatchEvent);
AutoWeakFrame previousTarget = mCurrentTarget;
- mCurrentTargetContent = aTargetContent;
+ mCurrentTargetContent = targetContent;
nsIFrame* targetFrame = nullptr;
nsEventStatus status = nsEventStatus_eIgnore;
- ESMEventCB callback(aTargetContent);
- EventDispatcher::Dispatch(aTargetContent, mPresContext, dispatchEvent, nullptr,
+ ESMEventCB callback(targetContent);
+ EventDispatcher::Dispatch(targetContent, mPresContext, dispatchEvent, nullptr,
&status, &callback);
if (mPresContext) {
// Although the primary frame was checked in event callback, it may not be
// the same object after event dispatch and handling, so refetch it.
- targetFrame = mPresContext->GetPrimaryFrameFor(aTargetContent);
+ targetFrame = mPresContext->GetPrimaryFrameFor(targetContent);
// If we are entering/leaving remote content, dispatch a mouse enter/exit
// event to the remote frame.
- if (IsRemoteTarget(aTargetContent)) {
+ if (IsRemoteTarget(targetContent)) {
if (aMessage == eMouseOut) {
// For remote content, send a "top-level" widget mouse exit event.
nsAutoPtr<WidgetMouseEvent> remoteEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget,
- aRelatedContent, remoteEvent);
+ relatedContent, remoteEvent);
remoteEvent->mExitFrom = WidgetMouseEvent::eTopLevel;
// mCurrentTarget is set to the new target, so we must reset it to the
@@ -4079,7 +4082,7 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
} else if (aMessage == eMouseOver) {
nsAutoPtr<WidgetMouseEvent> remoteEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseEnterIntoWidget,
- aRelatedContent, remoteEvent);
+ relatedContent, remoteEvent);
HandleCrossProcessEvent(remoteEvent, &status);
}
}

View File

@ -0,0 +1,305 @@
commit 3512ab03dd1f
Author: Mike Conley <mconley@mozilla.com>
Date: Mon Dec 18 11:19:53 2017 -0500
Bug 1424373 - Don't set crash reporting prefs when showing about:tabcrashed for a crash without a report. r=Mossop a=jcristau
---
browser/base/content/aboutTabCrashed.js | 1 +
.../test/tabcrashed/browser_autoSubmitRequest.js | 63 ++++++++++++++++++++--
.../content/test/tabcrashed/browser_withoutDump.js | 10 +---
browser/base/content/test/tabcrashed/head.js | 12 +++++
browser/modules/ContentCrashHandlers.jsm | 13 +++--
5 files changed, 83 insertions(+), 16 deletions(-)
diff --git browser/base/content/aboutTabCrashed.js browser/base/content/aboutTabCrashed.js
index 822e3f78d4b5..8fccc92aa0fe 100644
--- browser/base/content/aboutTabCrashed.js
+++ browser/base/content/aboutTabCrashed.js
@@ -303,6 +303,7 @@ var AboutTabCrashed = {
includeURL,
URL,
autoSubmit,
+ hasReport: this.hasReport,
});
},
};
diff --git browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
index a86b1e2c79b7..e04ebc80cdea 100644
--- browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
+++ browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
@@ -19,9 +19,9 @@ requestLongerTimeout(2);
add_task(async function test_show_form() {
await SpecialPowers.pushPrefEnv({
set: [[AUTOSUBMIT_PREF, false]],
- })
+ });
- return BrowserTestUtils.withNewTab({
+ await BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, async function(browser) {
@@ -66,9 +66,9 @@ add_task(async function test_show_form() {
add_task(async function test_show_form() {
await SpecialPowers.pushPrefEnv({
set: [[AUTOSUBMIT_PREF, true]],
- })
+ });
- return BrowserTestUtils.withNewTab({
+ await BrowserTestUtils.withNewTab({
gBrowser,
url: PAGE,
}, async function(browser) {
@@ -95,3 +95,58 @@ add_task(async function test_show_form() {
"Autosubmission pref should have been set.");
});
});
+
+/**
+ * Tests that we properly set the autoSubmit preference if the user is
+ * presented with a tabcrashed page without a crash report.
+ */
+add_task(async function test_no_offer() {
+ // We should default to sending the report.
+ Assert.ok(TabCrashHandler.prefs.getBoolPref("sendReport"));
+
+ await SpecialPowers.pushPrefEnv({
+ set: [[AUTOSUBMIT_PREF, false]],
+ });
+
+ await BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: PAGE,
+ }, async function(browser) {
+ await TabStateFlusher.flush(browser);
+
+ // Make it so that it seems like no dump is available for the next crash.
+ prepareNoDump();
+
+ // Now crash the browser.
+ await BrowserTestUtils.crashBrowser(browser);
+
+ // eslint-disable-next-line mozilla/no-cpows-in-tests
+ let doc = browser.contentDocument;
+
+ // Ensure the request to autosubmit is invisible, since there's no report.
+ let requestRect = doc.getElementById("requestAutoSubmit")
+ .getBoundingClientRect();
+ Assert.equal(0, requestRect.height,
+ "Request for autosubmission has no height");
+ Assert.equal(0, requestRect.width,
+ "Request for autosubmission has no width");
+
+ // Since the pref is set to false, the checkbox should be
+ // unchecked.
+ let autoSubmit = doc.getElementById("autoSubmit");
+ Assert.ok(!autoSubmit.checked,
+ "Checkbox for autosubmission is not checked.");
+
+ let restoreButton = doc.getElementById("restoreTab");
+ restoreButton.click();
+
+ await BrowserTestUtils.browserLoaded(browser, false, PAGE);
+
+ // The autosubmission pref should now be set.
+ Assert.ok(!Services.prefs.getBoolPref(AUTOSUBMIT_PREF),
+ "Autosubmission pref should not have changed.");
+ });
+
+ // We should not have changed the default value for sending the report.
+ Assert.ok(TabCrashHandler.prefs.getBoolPref("sendReport"));
+});
diff --git browser/base/content/test/tabcrashed/browser_withoutDump.js browser/base/content/test/tabcrashed/browser_withoutDump.js
index 62d997240af4..33bc2b3164a1 100644
--- browser/base/content/test/tabcrashed/browser_withoutDump.js
+++ browser/base/content/test/tabcrashed/browser_withoutDump.js
@@ -2,16 +2,8 @@
const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-/**
- * Monkey patches TabCrashHandler.getDumpID to return null in order to test
- * about:tabcrashed when a dump is not available.
- */
add_task(async function setup() {
- let originalGetDumpID = TabCrashHandler.getDumpID;
- TabCrashHandler.getDumpID = function(browser) { return null; };
- registerCleanupFunction(() => {
- TabCrashHandler.getDumpID = originalGetDumpID;
- });
+ prepareNoDump();
});
/**
diff --git browser/base/content/test/tabcrashed/head.js browser/base/content/test/tabcrashed/head.js
index e437acbcc4d5..9102e409ee91 100644
--- browser/base/content/test/tabcrashed/head.js
+++ browser/base/content/test/tabcrashed/head.js
@@ -121,3 +121,15 @@ async function setupLocalCrashReportServer() {
env.set("MOZ_CRASHREPORTER_URL", serverUrl);
});
}
+
+/**
+ * Monkey patches TabCrashHandler.getDumpID to return null in order to test
+ * about:tabcrashed when a dump is not available.
+ */
+function prepareNoDump() {
+ let originalGetDumpID = TabCrashHandler.getDumpID;
+ TabCrashHandler.getDumpID = function(browser) { return null; };
+ registerCleanupFunction(() => {
+ TabCrashHandler.getDumpID = originalGetDumpID;
+ });
+}
diff --git browser/modules/ContentCrashHandlers.jsm browser/modules/ContentCrashHandlers.jsm
index 36e60ede4f03..524d6a86a50a 100644
--- browser/modules/ContentCrashHandlers.jsm
+++ browser/modules/ContentCrashHandlers.jsm
@@ -361,8 +361,14 @@ this.TabCrashHandler = {
* even if they are empty.
*/
maybeSendCrashReport(message) {
- if (!AppConstants.MOZ_CRASHREPORTER)
+ if (!AppConstants.MOZ_CRASHREPORTER) {
+ return;
+ }
+
+ if (!message.data.hasReport) {
+ // There was no report, so nothing to do.
return;
+ }
let browser = message.target.browser;
@@ -374,8 +380,9 @@ this.TabCrashHandler = {
let childID = this.browserMap.get(browser);
let dumpID = this.childMap.get(childID);
- if (!dumpID)
- return
+ if (!dumpID) {
+ return;
+ }
if (!message.data.sendReport) {
Services.telemetry.getHistogramById("FX_CONTENT_CRASH_NOT_SUBMITTED").add(1);
commit a4a421108540
Author: Mike Conley <mconley@mozilla.com>
Date: Thu Dec 21 16:36:13 2017 -0500
Bug 1424373 - Rename crash report submission pref. r=Mossop a=jcristau
---
browser/app/profile/firefox.js | 2 +-
browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js | 2 +-
browser/components/preferences/in-content/privacy.xul | 6 +++---
.../tests/browser_bug1020245_openPreferences_to_paneContent.js | 4 ++--
.../components/sessionstore/test/browser_background_tab_crash.js | 2 +-
browser/modules/ContentCrashHandlers.jsm | 4 ++--
browser/modules/test/browser/browser_UnsubmittedCrashHandler.js | 4 ++--
7 files changed, 12 insertions(+), 12 deletions(-)
diff --git browser/app/profile/firefox.js browser/app/profile/firefox.js
index 8c29be0acc58..a1844936fdea 100644
--- browser/app/profile/firefox.js
+++ browser/app/profile/firefox.js
@@ -1664,7 +1664,7 @@ pref("browser.crashReports.unsubmittedCheck.enabled", false);
// without a user choice before we suppress the notification for
// some number of days.
pref("browser.crashReports.unsubmittedCheck.chancesUntilSuppress", 4);
-pref("browser.crashReports.unsubmittedCheck.autoSubmit", false);
+pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);
// Preferences for the form autofill system extension
// The truthy values of "extensions.formautofill.available" are "on" and "detect",
diff --git browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
index e04ebc80cdea..1d4a70a1d145 100644
--- browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
+++ browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
@@ -1,7 +1,7 @@
"use strict";
const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
-const AUTOSUBMIT_PREF = "browser.crashReports.unsubmittedCheck.autoSubmit";
+const AUTOSUBMIT_PREF = "browser.crashReports.unsubmittedCheck.autoSubmit2";
const {TabStateFlusher} =
Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
diff --git browser/components/preferences/in-content-new/privacy.xul browser/components/preferences/in-content-new/privacy.xul
index 7eb882972ffa..1d34065ac7e5 100644
--- browser/components/preferences/in-content-new/privacy.xul
+++ browser/components/preferences/in-content-new/privacy.xul
@@ -161,8 +161,8 @@
<!-- Data Choices tab -->
#ifdef MOZ_CRASHREPORTER
- <preference id="browser.crashReports.unsubmittedCheck.autoSubmit"
- name="browser.crashReports.unsubmittedCheck.autoSubmit"
+ <preference id="browser.crashReports.unsubmittedCheck.autoSubmit2"
+ name="browser.crashReports.unsubmittedCheck.autoSubmit2"
type="bool"/>
#endif
@@ -671,7 +671,7 @@
#ifdef MOZ_CRASHREPORTER
<hbox align="center">
<checkbox id="automaticallySubmitCrashesBox"
- preference="browser.crashReports.unsubmittedCheck.autoSubmit"
+ preference="browser.crashReports.unsubmittedCheck.autoSubmit2"
label="&alwaysSubmitCrashReports1.label;"
accesskey="&alwaysSubmitCrashReports1.accesskey;"/>
<label id="crashReporterLearnMore"
diff --git browser/components/sessionstore/test/browser_background_tab_crash.js browser/components/sessionstore/test/browser_background_tab_crash.js
index 9df18999a32f..34d92a9bdb39 100644
--- browser/components/sessionstore/test/browser_background_tab_crash.js
+++ browser/components/sessionstore/test/browser_background_tab_crash.js
@@ -147,7 +147,7 @@ add_task(async function test_background_crash_simple() {
*/
add_task(async function test_background_crash_autosubmit_backlogged() {
await SpecialPowers.pushPrefEnv({
- set: [["browser.crashReports.unsubmittedCheck.autoSubmit", true]],
+ set: [["browser.crashReports.unsubmittedCheck.autoSubmit2", true]],
});
await setupBackgroundTabs(async function([tab1, tab2]) {
diff --git browser/modules/ContentCrashHandlers.jsm browser/modules/ContentCrashHandlers.jsm
index a5f95677c006..7127e2785c3a 100644
--- browser/modules/ContentCrashHandlers.jsm
+++ browser/modules/ContentCrashHandlers.jsm
@@ -885,11 +885,11 @@ this.UnsubmittedCrashHandler = {
get autoSubmit() {
return Services.prefs
- .getBoolPref("browser.crashReports.unsubmittedCheck.autoSubmit");
+ .getBoolPref("browser.crashReports.unsubmittedCheck.autoSubmit2");
},
set autoSubmit(val) {
- Services.prefs.setBoolPref("browser.crashReports.unsubmittedCheck.autoSubmit",
+ Services.prefs.setBoolPref("browser.crashReports.unsubmittedCheck.autoSubmit2",
val);
},
diff --git browser/modules/test/browser/browser_UnsubmittedCrashHandler.js browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
index 12c673ca92d2..2e79413d0a15 100644
--- browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
+++ browser/modules/test/browser/browser_UnsubmittedCrashHandler.js
@@ -398,7 +398,7 @@ add_task(async function test_can_submit_several() {
* and sends the pending crash reports.
*/
add_task(async function test_can_submit_always() {
- let pref = "browser.crashReports.unsubmittedCheck.autoSubmit";
+ let pref = "browser.crashReports.unsubmittedCheck.autoSubmit2";
Assert.equal(Services.prefs.getBoolPref(pref), false,
"We should not be auto-submitting by default");
@@ -442,7 +442,7 @@ add_task(async function test_can_submit_always() {
*/
add_task(async function test_can_auto_submit() {
await SpecialPowers.pushPrefEnv({ set: [
- ["browser.crashReports.unsubmittedCheck.autoSubmit", true],
+ ["browser.crashReports.unsubmittedCheck.autoSubmit2", true],
]});
let reportIDs = await createPendingCrashReports(3);

View File

@ -0,0 +1,159 @@
commit bc308d794057
Author: Karl Tomlinson <karlt+@karlt.net>
Date: Sat Nov 4 19:00:46 2017 +1300
Bug 1382366 - Disable AudioCallback -> SystemClockDriver fallback before disowning graph. f=pehrsons, r=padenot, a=gchang
MozReview-Commit-ID: ESr6yxjPVWf
--HG--
extra : rebase_source : 6ed3093ab9dec68515f39353dc46ab40780cd161
extra : source : 53f055298fa9d2446fd90ad8a51fefd3b15b16c1
---
dom/media/GraphDriver.cpp | 38 +++++++++++---------------------------
dom/media/GraphDriver.h | 14 ++++++++------
2 files changed, 19 insertions(+), 33 deletions(-)
diff --git dom/media/GraphDriver.cpp dom/media/GraphDriver.cpp
index 13944338e3d7..62c847e90155 100644
--- dom/media/GraphDriver.cpp
+++ dom/media/GraphDriver.cpp
@@ -33,8 +33,7 @@ GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
mWaitState(WAITSTATE_RUNNING),
mCurrentTimeStamp(TimeStamp::Now()),
mPreviousDriver(nullptr),
- mNextDriver(nullptr),
- mScheduled(false)
+ mNextDriver(nullptr)
{ }
void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
@@ -121,12 +120,6 @@ void GraphDriver::SetPreviousDriver(GraphDriver* aPreviousDriver)
mPreviousDriver = aPreviousDriver;
}
-bool GraphDriver::Scheduled()
-{
- GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
- return mScheduled;
-}
-
ThreadedDriver::ThreadedDriver(MediaStreamGraphImpl* aGraphImpl)
: GraphDriver(aGraphImpl)
{ }
@@ -216,8 +209,7 @@ ThreadedDriver::Start()
// Note: mThread may be null during event->Run() if we pass to NewNamedThread! See AudioInitTask
nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
if (NS_SUCCEEDED(rv)) {
- rv = mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
- mScheduled = NS_SUCCEEDED(rv);
+ mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
}
}
}
@@ -545,6 +537,7 @@ AudioCallbackDriver::AudioCallbackDriver(MediaStreamGraphImpl* aGraphImpl)
, mAddedMixer(false)
, mInCallback(false)
, mMicrophoneActive(false)
+ , mShouldFallbackIfError(false)
, mFromFallback(false)
{
LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
@@ -765,13 +758,13 @@ AudioCallbackDriver::Start()
"to ensure it runs after previous shutdown."));
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebOperation::INIT);
- nsresult rv = initEvent->Dispatch();
- mScheduled = NS_SUCCEEDED(rv);
+ initEvent->Dispatch();
}
bool
AudioCallbackDriver::StartStream()
{
+ mShouldFallbackIfError = true;
if (cubeb_stream_start(mAudioStream) != CUBEB_OK) {
NS_WARNING("Could not start cubeb stream for MSG.");
return false;
@@ -1015,6 +1008,10 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
mSampleRate, mOutputChannels);
if (!stillProcessing) {
+ // About to hand over control of the graph. Do not start a new driver if
+ // StateCallback() receives an error for this stream while the main thread
+ // or another driver has control of the graph.
+ mShouldFallbackIfError = false;
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown if the graph does not get restarted.
mGraphImpl->SignalMainThreadCleanup();
@@ -1028,6 +1025,7 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
}
if (switching) {
+ mShouldFallbackIfError = false;
// If the audio stream has not been started by the previous driver or
// the graph itself, keep it alive.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
@@ -1052,22 +1050,8 @@ AudioCallbackDriver::StateCallback(cubeb_state aState)
{
LOG(LogLevel::Debug, ("AudioCallbackDriver State: %d", aState));
- if (aState == CUBEB_STATE_ERROR) {
- if (!mAudioStream) {
- // If we don't have an audio stream here, this means that the stream
- // initialization has failed. A fallback on a SystemCallDriver will happen at
- // the callsite of `cubeb_stream_init`.
- return;
- }
-
+ if (aState == CUBEB_STATE_ERROR && mShouldFallbackIfError) {
MonitorAutoLock lock(GraphImpl()->GetMonitor());
-
- if (NextDriver() && NextDriver()->Scheduled()) {
- // We are switching to another driver that has already been scheduled
- // to be initialized and started. There's nothing for us to do here.
- return;
- }
-
// Fall back to a driver using a normal thread. If needed,
// the graph will try to re-open an audio stream later.
SystemClockDriver* nextDriver = new SystemClockDriver(GraphImpl());
diff --git dom/media/GraphDriver.h dom/media/GraphDriver.h
index 4857d74b114a..1f8b9386c6fa 100644
--- dom/media/GraphDriver.h
+++ dom/media/GraphDriver.h
@@ -146,9 +146,6 @@ public:
void SetNextDriver(GraphDriver* aNextDriver);
void SetPreviousDriver(GraphDriver* aPreviousDriver);
- /* Return whether we have been scheduled to start. */
- bool Scheduled();
-
/**
* If we are running a real time graph, get the current time stamp to schedule
* video frames. This has to be reimplemented by real time drivers.
@@ -252,9 +249,6 @@ protected:
// driver at the end of this iteration.
// This must be accessed using the {Set,Get}NextDriver methods.
RefPtr<GraphDriver> mNextDriver;
- // This is initially false, but set to true as soon the driver has been
- // scheduled to start through GraphDriver::Start().
- bool mScheduled;
virtual ~GraphDriver()
{ }
};
@@ -558,6 +552,14 @@ private:
* True if microphone is being used by this process. This is synchronized by
* the graph's monitor. */
Atomic<bool> mMicrophoneActive;
+ /* Indication of whether a fallback SystemClockDriver should be started if
+ * StateCallback() receives an error. No mutex need be held during access.
+ * The transition to true happens before cubeb_stream_start() is called.
+ * After transitioning to false on the last DataCallback(), the stream is
+ * not accessed from another thread until the graph thread either signals
+ * main thread cleanup or dispatches an event to switch to another
+ * driver. */
+ bool mShouldFallbackIfError;
/* True if this driver was created from a driver created because of a previous
* AudioCallbackDriver failure. */
bool mFromFallback;