MFH: r471887
www/waterfox: apply some FF61 fixes Approved by: ports-secteam blanket
This commit is contained in:
parent
ad36f8f920
commit
901bf7f908
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/branches/2018Q2/; revision=471890
@ -3,7 +3,7 @@
|
||||
PORTNAME= waterfox
|
||||
DISTVERSION= 56.2.0-31
|
||||
DISTVERSIONSUFFIX= -gf435a827f82ac
|
||||
PORTREVISION= 2
|
||||
PORTREVISION= 3
|
||||
CATEGORIES= www ipv6
|
||||
|
||||
MAINTAINER= jbeich@FreeBSD.org
|
||||
|
100
www/waterfox/files/patch-bug1321069
Normal file
100
www/waterfox/files/patch-bug1321069
Normal file
@ -0,0 +1,100 @@
|
||||
commit a09c25bcc3b4
|
||||
Author: Kartikaya Gupta <kgupta@mozilla.com>
|
||||
Date: Wed May 30 09:49:23 2018 -0400
|
||||
|
||||
Bug 1321069 - Redirect the end event of a long-tap sequence back to the content window. r=karlt, a=RyanVM
|
||||
|
||||
In the case of a long-tap touch sequence, a new popup window (the
|
||||
contextmenu) is spawned while the sequence is ongoing. The touch-end of
|
||||
the sequence ends up getting delivered to the popup window, instead of
|
||||
the original content window, and that causes the touch-handling
|
||||
machinery state in the content window to get out of sync with reality.
|
||||
This patch detects this scenario and redirects the touch events on the
|
||||
popup window back to the original content window.
|
||||
|
||||
MozReview-Commit-ID: L2vvKLlogRA
|
||||
|
||||
--HG--
|
||||
extra : source : 27a160b7025ffaadd7cc1ce326ce8729c2b180a0
|
||||
---
|
||||
widget/gtk/nsWindow.cpp | 36 +++++++++++++++++++++++++++++++++++-
|
||||
widget/gtk/nsWindow.h | 3 +++
|
||||
2 files changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp
|
||||
index 54ec8615051f1..18d0ccac4dbd6 100644
|
||||
--- widget/gtk/nsWindow.cpp
|
||||
+++ widget/gtk/nsWindow.cpp
|
||||
@@ -3455,11 +3455,41 @@ nsWindow::OnDragDataReceivedEvent(GtkWidget *aWidget,
|
||||
aSelectionData, aInfo, aTime);
|
||||
}
|
||||
|
||||
+nsWindow*
|
||||
+nsWindow::GetTransientForWindowIfPopup()
|
||||
+{
|
||||
+ if (mWindowType != eWindowType_popup) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ GtkWindow* toplevel = gtk_window_get_transient_for(GTK_WINDOW(mShell));
|
||||
+ if (toplevel) {
|
||||
+ return get_window_for_gtk_widget(GTK_WIDGET(toplevel));
|
||||
+ }
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+bool
|
||||
+nsWindow::IsHandlingTouchSequence(GdkEventSequence* aSequence)
|
||||
+{
|
||||
+ return mHandleTouchEvent && mTouches.Contains(aSequence);
|
||||
+}
|
||||
+
|
||||
#if GTK_CHECK_VERSION(3,4,0)
|
||||
gboolean
|
||||
nsWindow::OnTouchEvent(GdkEventTouch* aEvent)
|
||||
{
|
||||
if (!mHandleTouchEvent) {
|
||||
+ // If a popup window was spawned (e.g. as the result of a long-press)
|
||||
+ // and touch events got diverted to that window within a touch sequence,
|
||||
+ // ensure the touch event gets sent to the original window instead. We
|
||||
+ // keep the checks here very conservative so that we only redirect
|
||||
+ // events in this specific scenario.
|
||||
+ nsWindow* targetWindow = GetTransientForWindowIfPopup();
|
||||
+ if (targetWindow &&
|
||||
+ targetWindow->IsHandlingTouchSequence(aEvent->sequence)) {
|
||||
+ return targetWindow->OnTouchEvent(aEvent);
|
||||
+ }
|
||||
+
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -4780,12 +4810,16 @@ nsWindow::GrabPointer(guint32 aTime)
|
||||
return;
|
||||
|
||||
gint retval;
|
||||
+ // Note that we need GDK_TOUCH_MASK below to work around a GDK/X11 bug that
|
||||
+ // causes touch events that would normally be received by this client on
|
||||
+ // other windows to be discarded during the grab.
|
||||
retval = gdk_pointer_grab(mGdkWindow, TRUE,
|
||||
(GdkEventMask)(GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK |
|
||||
GDK_LEAVE_NOTIFY_MASK |
|
||||
- GDK_POINTER_MOTION_MASK),
|
||||
+ GDK_POINTER_MOTION_MASK |
|
||||
+ GDK_TOUCH_MASK),
|
||||
(GdkWindow *)nullptr, nullptr, aTime);
|
||||
|
||||
if (retval == GDK_GRAB_NOT_VIEWABLE) {
|
||||
diff --git widget/gtk/nsWindow.h widget/gtk/nsWindow.h
|
||||
index c28c1749c76dc..33e8c4db7c1c0 100644
|
||||
--- widget/gtk/nsWindow.h
|
||||
+++ widget/gtk/nsWindow.h
|
||||
@@ -434,6 +434,8 @@ private:
|
||||
nsIWidgetListener* GetListener();
|
||||
bool IsComposited() const;
|
||||
|
||||
+ nsWindow* GetTransientForWindowIfPopup();
|
||||
+ bool IsHandlingTouchSequence(GdkEventSequence* aSequence);
|
||||
|
||||
GtkWidget *mShell;
|
||||
MozContainer *mContainer;
|
27
www/waterfox/files/patch-bug1346126
Normal file
27
www/waterfox/files/patch-bug1346126
Normal file
@ -0,0 +1,27 @@
|
||||
commit b46bdf1c51e0
|
||||
Author: Ryan Hunt <rhunt@eqrion.net>
|
||||
Date: Fri Jun 1 11:18:07 2018 -0500
|
||||
|
||||
Bug 1346126 - Use RemoveAllChildren in ~ContainerLayerComposite. r=mattwoodrow, a=RyanVM
|
||||
|
||||
--HG--
|
||||
extra : source : b9814173e9a8ebbf9e6a0cb6dbf751fadead17c4
|
||||
---
|
||||
gfx/layers/composite/ContainerLayerComposite.cpp | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git gfx/layers/composite/ContainerLayerComposite.cpp gfx/layers/composite/ContainerLayerComposite.cpp
|
||||
index c40b3c19f8a88..74aed9bbcc03c 100644
|
||||
--- gfx/layers/composite/ContainerLayerComposite.cpp
|
||||
+++ gfx/layers/composite/ContainerLayerComposite.cpp
|
||||
@@ -650,9 +650,7 @@ ContainerLayerComposite::~ContainerLayerComposite()
|
||||
// LayerManagerComposite::Destroy(), a parent
|
||||
// *ContainerLayerComposite::Destroy(), or Disconnect() will trigger
|
||||
// cleanup of our resources.
|
||||
- while (mFirstChild) {
|
||||
- RemoveChild(mFirstChild);
|
||||
- }
|
||||
+ RemoveAllChildren();
|
||||
}
|
||||
|
||||
void
|
@ -1,36 +1,605 @@
|
||||
commit 7f8f5d958ed6
|
||||
Author: Bryce Van Dyk <bvandyk@mozilla.com>
|
||||
Date: Wed Apr 18 15:30:57 2018 -0400
|
||||
commit 890e77744a2a
|
||||
Author: Andreas Pehrson <pehrsons@mozilla.com>
|
||||
Date: Tue May 29 10:13:14 2018 +0200
|
||||
|
||||
Bug 1453127 - Do not use iterators in MediaStreamTrack when removing listeners. r=pehrsons a=lizzard
|
||||
|
||||
--HG--
|
||||
extra : source : 6b3aaee40f7507e240da08d6e073cff3c53971f4
|
||||
Bug 1453127 - Make sure decoder-captured tracks end when changing src. r=jya, a=RyanVM
|
||||
---
|
||||
dom/media/MediaStreamTrack.cpp | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
dom/html/HTMLMediaElement.cpp | 18 ++++++++++++++++++
|
||||
dom/html/HTMLMediaElement.h | 5 +++++
|
||||
2 files changed, 23 insertions(+)
|
||||
|
||||
diff --git dom/media/MediaStreamTrack.cpp dom/media/MediaStreamTrack.cpp
|
||||
index 010373e9086d..af6c6014cf02 100644
|
||||
--- dom/media/MediaStreamTrack.cpp
|
||||
+++ dom/media/MediaStreamTrack.cpp
|
||||
@@ -166,11 +166,15 @@ MediaStreamTrack::Destroy()
|
||||
mPrincipalHandleListener->Forget();
|
||||
mPrincipalHandleListener = nullptr;
|
||||
diff --git dom/html/HTMLMediaElement.cpp dom/html/HTMLMediaElement.cpp
|
||||
index b0e787fbf9278..d1502cecfb237 100644
|
||||
--- dom/html/HTMLMediaElement.cpp
|
||||
+++ dom/html/HTMLMediaElement.cpp
|
||||
@@ -1429,6 +1429,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mErrorSink->mError)
|
||||
for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
|
||||
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mPreCreatedTracks)
|
||||
}
|
||||
- for (auto l : mTrackListeners) {
|
||||
- RemoveListener(l);
|
||||
+ // Remove all listeners -- avoid iterating over the list we're removing from
|
||||
+ const nsTArray<RefPtr<MediaStreamTrackListener>> trackListeners(mTrackListeners);
|
||||
+ for (auto listener : trackListeners) {
|
||||
+ RemoveListener(listener);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
|
||||
@@ -3494,6 +3495,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
RefPtr<MediaStreamTrack> track =
|
||||
out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO,
|
||||
trackSource);
|
||||
+ out->mPreCreatedTracks.AppendElement(track);
|
||||
out->mStream->AddTrackInternal(track);
|
||||
LOG(LogLevel::Debug,
|
||||
("Created audio track %d for captured decoder", audioTrackId));
|
||||
@@ -3505,6 +3507,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
RefPtr<MediaStreamTrack> track =
|
||||
out->mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO,
|
||||
trackSource);
|
||||
+ out->mPreCreatedTracks.AppendElement(track);
|
||||
out->mStream->AddTrackInternal(track);
|
||||
LOG(LogLevel::Debug,
|
||||
("Created video track %d for captured decoder", videoTrackId));
|
||||
@@ -7526,6 +7529,21 @@ HTMLMediaElement::RemoveMediaTracks()
|
||||
}
|
||||
- for (auto l : mDirectTrackListeners) {
|
||||
- RemoveDirectListener(l);
|
||||
+ // Do the same as above for direct listeners
|
||||
+ const nsTArray<RefPtr<DirectMediaStreamTrackListener>> directTrackListeners(mDirectTrackListeners);
|
||||
+ for (auto listener : directTrackListeners) {
|
||||
+ RemoveDirectListener(listener);
|
||||
|
||||
mMediaTracksConstructed = false;
|
||||
+
|
||||
+ for (OutputMediaStream& ms : mOutputStreams) {
|
||||
+ if (!ms.mCapturingDecoder) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ for (RefPtr<MediaStreamTrack>& t : ms.mPreCreatedTracks) {
|
||||
+ if (t->Ended()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ mAbstractMainThread->Dispatch(NewRunnableMethod(
|
||||
+ "dom::HTMLMediaElement::RemoveMediaTracks",
|
||||
+ t, &MediaStreamTrack::OverrideEnded));
|
||||
+ }
|
||||
+ ms.mPreCreatedTracks.Clear();
|
||||
+ }
|
||||
}
|
||||
|
||||
class MediaElementGMPCrashHelper : public GMPCrashHelper
|
||||
diff --git dom/html/HTMLMediaElement.h dom/html/HTMLMediaElement.h
|
||||
index a81a2dfb22f39..126aaee2ae655 100644
|
||||
--- dom/html/HTMLMediaElement.h
|
||||
+++ dom/html/HTMLMediaElement.h
|
||||
@@ -843,6 +843,11 @@ protected:
|
||||
bool mCapturingDecoder;
|
||||
bool mCapturingMediaStream;
|
||||
|
||||
+ // The following members are keeping state for a captured MediaDecoder.
|
||||
+ // Tracks that were created on main thread before MediaDecoder fed them
|
||||
+ // to the MediaStreamGraph.
|
||||
+ nsTArray<RefPtr<MediaStreamTrack>> mPreCreatedTracks;
|
||||
+
|
||||
// The following members are keeping state for a captured MediaStream.
|
||||
TrackID mNextAvailableTrackID;
|
||||
nsTArray<Pair<nsString, RefPtr<MediaInputPort>>> mTrackPorts;
|
||||
|
||||
commit dee1e1ec98be
|
||||
Author: Andreas Pehrson <pehrsons@mozilla.com>
|
||||
Date: Tue May 29 10:21:51 2018 +0200
|
||||
|
||||
Bug 1453127 - Ensure TrackID uniqueness for captured MediaDecoder. r=jya, a=RyanVM
|
||||
---
|
||||
dom/html/HTMLMediaElement.cpp | 22 +++++++---
|
||||
dom/html/HTMLMediaElement.h | 2 +-
|
||||
dom/media/MediaDecoder.cpp | 13 +++++-
|
||||
dom/media/MediaDecoder.h | 3 ++
|
||||
dom/media/MediaDecoderStateMachine.cpp | 10 ++++-
|
||||
dom/media/MediaDecoderStateMachine.h | 5 ++-
|
||||
dom/media/mediasink/DecodedStream.cpp | 11 +++--
|
||||
dom/media/mediasink/OutputStreamManager.cpp | 68 ++++++++++++++++++++++-------
|
||||
dom/media/mediasink/OutputStreamManager.h | 33 ++++++++++----
|
||||
9 files changed, 131 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git dom/html/HTMLMediaElement.cpp dom/html/HTMLMediaElement.cpp
|
||||
index d1502cecfb237..d11c9d03a7e52 100644
|
||||
--- dom/html/HTMLMediaElement.cpp
|
||||
+++ dom/html/HTMLMediaElement.cpp
|
||||
@@ -1710,6 +1710,14 @@ void HTMLMediaElement::ShutdownDecoder()
|
||||
if (mMediaSource) {
|
||||
mMediaSource->CompletePendingTransactions();
|
||||
}
|
||||
+ for (OutputMediaStream& out : mOutputStreams) {
|
||||
+ if (!out.mCapturingDecoder) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ out.mNextAvailableTrackID = std::max<TrackID>(
|
||||
+ mDecoder->NextAvailableTrackIDFor(out.mStream->GetInputStream()),
|
||||
+ out.mNextAvailableTrackID);
|
||||
+ }
|
||||
mDecoder->Shutdown();
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
@@ -3476,6 +3484,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
if (mDecoder) {
|
||||
out->mCapturingDecoder = true;
|
||||
mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(),
|
||||
+ out->mNextAvailableTrackID,
|
||||
aFinishWhenEnded);
|
||||
} else if (mSrcStream) {
|
||||
out->mCapturingMediaStream = true;
|
||||
@@ -3489,11 +3498,12 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
|
||||
if (mDecoder) {
|
||||
if (HasAudio()) {
|
||||
- TrackID audioTrackId = mMediaInfo.mAudio.mTrackId;
|
||||
+ TrackID audioTrackId = out->mNextAvailableTrackID++;
|
||||
RefPtr<MediaStreamTrackSource> trackSource =
|
||||
getter->GetMediaStreamTrackSource(audioTrackId);
|
||||
RefPtr<MediaStreamTrack> track =
|
||||
- out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO,
|
||||
+ out->mStream->CreateDOMTrack(audioTrackId,
|
||||
+ MediaSegment::AUDIO,
|
||||
trackSource);
|
||||
out->mPreCreatedTracks.AppendElement(track);
|
||||
out->mStream->AddTrackInternal(track);
|
||||
@@ -3501,7 +3511,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
|
||||
("Created audio track %d for captured decoder", audioTrackId));
|
||||
}
|
||||
if (IsVideo() && HasVideo() && !out->mCapturingAudioOnly) {
|
||||
- TrackID videoTrackId = mMediaInfo.mVideo.mTrackId;
|
||||
+ TrackID videoTrackId = out->mNextAvailableTrackID++;
|
||||
RefPtr<MediaStreamTrackSource> trackSource =
|
||||
getter->GetMediaStreamTrackSource(videoTrackId);
|
||||
RefPtr<MediaStreamTrack> track =
|
||||
@@ -4241,11 +4251,12 @@ HTMLMediaElement::WakeLockRelease()
|
||||
}
|
||||
|
||||
HTMLMediaElement::OutputMediaStream::OutputMediaStream()
|
||||
- : mFinishWhenEnded(false)
|
||||
+ : mNextAvailableTrackID(1)
|
||||
+ , mFinishWhenEnded(false)
|
||||
, mCapturingAudioOnly(false)
|
||||
, mCapturingDecoder(false)
|
||||
, mCapturingMediaStream(false)
|
||||
- , mNextAvailableTrackID(1) {}
|
||||
+{}
|
||||
|
||||
HTMLMediaElement::OutputMediaStream::~OutputMediaStream()
|
||||
{
|
||||
@@ -4844,6 +4855,7 @@ HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder)
|
||||
|
||||
ms.mCapturingDecoder = true;
|
||||
aDecoder->AddOutputStream(ms.mStream->GetInputStream()->AsProcessedStream(),
|
||||
+ ms.mNextAvailableTrackID,
|
||||
ms.mFinishWhenEnded);
|
||||
}
|
||||
|
||||
diff --git dom/html/HTMLMediaElement.h dom/html/HTMLMediaElement.h
|
||||
index 126aaee2ae655..aeccfa5ba221d 100644
|
||||
--- dom/html/HTMLMediaElement.h
|
||||
+++ dom/html/HTMLMediaElement.h
|
||||
@@ -838,6 +838,7 @@ protected:
|
||||
~OutputMediaStream();
|
||||
|
||||
RefPtr<DOMMediaStream> mStream;
|
||||
+ TrackID mNextAvailableTrackID;
|
||||
bool mFinishWhenEnded;
|
||||
bool mCapturingAudioOnly;
|
||||
bool mCapturingDecoder;
|
||||
@@ -849,7 +850,6 @@ protected:
|
||||
nsTArray<RefPtr<MediaStreamTrack>> mPreCreatedTracks;
|
||||
|
||||
// The following members are keeping state for a captured MediaStream.
|
||||
- TrackID mNextAvailableTrackID;
|
||||
nsTArray<Pair<nsString, RefPtr<MediaInputPort>>> mTrackPorts;
|
||||
};
|
||||
|
||||
diff --git dom/media/MediaDecoder.cpp dom/media/MediaDecoder.cpp
|
||||
index c4bf14d1206fd..11d48fb9921c1 100644
|
||||
--- dom/media/MediaDecoder.cpp
|
||||
+++ dom/media/MediaDecoder.cpp
|
||||
@@ -322,11 +322,13 @@ MediaDecoder::SetVolume(double aVolume)
|
||||
|
||||
void
|
||||
MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load().");
|
||||
- mDecoderStateMachine->AddOutputStream(aStream, aFinishWhenEnded);
|
||||
+ mDecoderStateMachine->AddOutputStream(
|
||||
+ aStream, aNextAvailableTrackID, aFinishWhenEnded);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -337,6 +339,14 @@ MediaDecoder::RemoveOutputStream(MediaStream* aStream)
|
||||
mDecoderStateMachine->RemoveOutputStream(aStream);
|
||||
}
|
||||
|
||||
+TrackID
|
||||
+MediaDecoder::NextAvailableTrackIDFor(MediaStream* aOutputStream) const
|
||||
+{
|
||||
+ MOZ_ASSERT(NS_IsMainThread());
|
||||
+ MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load().");
|
||||
+ return mDecoderStateMachine->NextAvailableTrackIDFor(aOutputStream);
|
||||
+}
|
||||
+
|
||||
double
|
||||
MediaDecoder::GetDuration()
|
||||
{
|
||||
diff --git dom/media/MediaDecoder.h dom/media/MediaDecoder.h
|
||||
index a8708b390433a..357f87ef8e0e8 100644
|
||||
--- dom/media/MediaDecoder.h
|
||||
+++ dom/media/MediaDecoder.h
|
||||
@@ -183,9 +183,12 @@ public:
|
||||
// The stream is initially blocked. The decoder is responsible for unblocking
|
||||
// it while it is playing back.
|
||||
virtual void AddOutputStream(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
bool aFinishWhenEnded);
|
||||
// Remove an output stream added with AddOutputStream.
|
||||
virtual void RemoveOutputStream(MediaStream* aStream);
|
||||
+ // The next TrackID that can be used without risk of a collision.
|
||||
+ virtual TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const;
|
||||
|
||||
// Return the duration of the video in seconds.
|
||||
virtual double GetDuration();
|
||||
diff --git dom/media/MediaDecoderStateMachine.cpp dom/media/MediaDecoderStateMachine.cpp
|
||||
index cea333f5d9a05..fef3b318b48cb 100644
|
||||
--- dom/media/MediaDecoderStateMachine.cpp
|
||||
+++ dom/media/MediaDecoderStateMachine.cpp
|
||||
@@ -3973,11 +3973,12 @@ MediaDecoderStateMachine::RequestDebugInfo()
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG("AddOutputStream aStream=%p!", aStream);
|
||||
- mOutputStreamManager->Add(aStream, aFinishWhenEnded);
|
||||
+ mOutputStreamManager->Add(aStream, aNextAvailableTrackID, aFinishWhenEnded);
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NewRunnableMethod<bool>("MediaDecoderStateMachine::SetAudioCaptured",
|
||||
this,
|
||||
@@ -4001,6 +4002,13 @@ void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
||||
}
|
||||
}
|
||||
|
||||
+TrackID
|
||||
+MediaDecoderStateMachine::NextAvailableTrackIDFor(MediaStream* aOutputStream) const
|
||||
+{
|
||||
+ MOZ_ASSERT(NS_IsMainThread());
|
||||
+ return mOutputStreamManager->NextAvailableTrackIDFor(aOutputStream);
|
||||
+}
|
||||
+
|
||||
class VideoQueueMemoryFunctor : public nsDequeFunctor
|
||||
{
|
||||
public:
|
||||
diff --git dom/media/MediaDecoderStateMachine.h dom/media/MediaDecoderStateMachine.h
|
||||
index 6f7fcf825ea83..b59bcca7dc70a 100644
|
||||
--- dom/media/MediaDecoderStateMachine.h
|
||||
+++ dom/media/MediaDecoderStateMachine.h
|
||||
@@ -175,9 +175,12 @@ public:
|
||||
|
||||
RefPtr<MediaDecoder::DebugInfoPromise> RequestDebugInfo();
|
||||
|
||||
- void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
+ void AddOutputStream(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
+ bool aFinishWhenEnded);
|
||||
// Remove an output stream added with AddOutputStream.
|
||||
void RemoveOutputStream(MediaStream* aStream);
|
||||
+ TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const;
|
||||
|
||||
// Seeks to the decoder to aTarget asynchronously.
|
||||
RefPtr<MediaDecoder::SeekPromise> InvokeSeek(const SeekTarget& aTarget);
|
||||
diff --git dom/media/mediasink/DecodedStream.cpp dom/media/mediasink/DecodedStream.cpp
|
||||
index 5244a087c77e7..b5c40b9067e57 100644
|
||||
--- dom/media/mediasink/DecodedStream.cpp
|
||||
+++ dom/media/mediasink/DecodedStream.cpp
|
||||
@@ -193,17 +193,22 @@ DecodedStreamData::DecodedStreamData(OutputStreamManager* aOutputStreamManager,
|
||||
, mAbstractMainThread(aMainThread)
|
||||
{
|
||||
mStream->AddListener(mListener);
|
||||
- mOutputStreamManager->Connect(mStream);
|
||||
+ TrackID audioTrack = TRACK_NONE;
|
||||
+ TrackID videoTrack = TRACK_NONE;
|
||||
|
||||
// Initialize tracks.
|
||||
if (aInit.mInfo.HasAudio()) {
|
||||
- mStream->AddAudioTrack(aInit.mInfo.mAudio.mTrackId,
|
||||
+ audioTrack = aInit.mInfo.mAudio.mTrackId;
|
||||
+ mStream->AddAudioTrack(audioTrack,
|
||||
aInit.mInfo.mAudio.mRate,
|
||||
0, new AudioSegment());
|
||||
}
|
||||
if (aInit.mInfo.HasVideo()) {
|
||||
- mStream->AddTrack(aInit.mInfo.mVideo.mTrackId, 0, new VideoSegment());
|
||||
+ videoTrack = aInit.mInfo.mVideo.mTrackId;
|
||||
+ mStream->AddTrack(videoTrack, 0, new VideoSegment());
|
||||
}
|
||||
+
|
||||
+ mOutputStreamManager->Connect(mStream, audioTrack, videoTrack);
|
||||
}
|
||||
|
||||
DecodedStreamData::~DecodedStreamData()
|
||||
diff --git dom/media/mediasink/OutputStreamManager.cpp dom/media/mediasink/OutputStreamManager.cpp
|
||||
index d5685837a6783..b3ec8936d435e 100644
|
||||
--- dom/media/mediasink/OutputStreamManager.cpp
|
||||
+++ dom/media/mediasink/OutputStreamManager.cpp
|
||||
@@ -13,29 +13,41 @@ OutputStreamData::~OutputStreamData()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Break the connection to the input stream if necessary.
|
||||
- if (mPort) {
|
||||
- mPort->Destroy();
|
||||
+ for (RefPtr<MediaInputPort>& port : mPorts) {
|
||||
+ port->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
-OutputStreamData::Init(OutputStreamManager* aOwner, ProcessedMediaStream* aStream)
|
||||
+OutputStreamData::Init(OutputStreamManager* aOwner,
|
||||
+ ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
mStream = aStream;
|
||||
+ mNextAvailableTrackID = aNextAvailableTrackID;
|
||||
}
|
||||
|
||||
bool
|
||||
-OutputStreamData::Connect(MediaStream* aStream)
|
||||
+OutputStreamData::Connect(MediaStream* aStream,
|
||||
+ TrackID aInputAudioTrackID,
|
||||
+ TrackID aInputVideoTrackID)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
- MOZ_ASSERT(!mPort, "Already connected?");
|
||||
+ MOZ_ASSERT(mPorts.IsEmpty(), "Already connected?");
|
||||
|
||||
if (mStream->IsDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
- mPort = mStream->AllocateInputPort(aStream);
|
||||
+ for (TrackID tid : {aInputAudioTrackID, aInputVideoTrackID}) {
|
||||
+ if (tid == TRACK_NONE) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ MOZ_ASSERT(IsTrackIDExplicit(tid));
|
||||
+ mPorts.AppendElement(mStream->AllocateInputPort(
|
||||
+ aStream, tid, mNextAvailableTrackID++));
|
||||
+ }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -51,11 +63,11 @@ OutputStreamData::Disconnect()
|
||||
return false;
|
||||
}
|
||||
|
||||
- // Disconnect the existing port if necessary.
|
||||
- if (mPort) {
|
||||
- mPort->Destroy();
|
||||
- mPort = nullptr;
|
||||
+ // Disconnect any existing port.
|
||||
+ for (RefPtr<MediaInputPort>& port : mPorts) {
|
||||
+ port->Destroy();
|
||||
}
|
||||
+ mPorts.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,8 +83,16 @@ OutputStreamData::Graph() const
|
||||
return mStream->Graph();
|
||||
}
|
||||
|
||||
+TrackID
|
||||
+OutputStreamData::NextAvailableTrackID() const
|
||||
+{
|
||||
+ return mNextAvailableTrackID;
|
||||
+}
|
||||
+
|
||||
void
|
||||
-OutputStreamManager::Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
|
||||
+OutputStreamManager::Add(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
+ bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// All streams must belong to the same graph.
|
||||
@@ -84,12 +104,12 @@ OutputStreamManager::Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
|
||||
}
|
||||
|
||||
OutputStreamData* p = mStreams.AppendElement();
|
||||
- p->Init(this, aStream);
|
||||
+ p->Init(this, aStream, aNextAvailableTrackID);
|
||||
|
||||
// Connect to the input stream if we have one. Otherwise the output stream
|
||||
// will be connected in Connect().
|
||||
if (mInputStream) {
|
||||
- p->Connect(mInputStream);
|
||||
+ p->Connect(mInputStream, mInputAudioTrackID, mInputVideoTrackID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,13 +125,29 @@ OutputStreamManager::Remove(MediaStream* aStream)
|
||||
}
|
||||
}
|
||||
|
||||
+TrackID
|
||||
+OutputStreamManager::NextAvailableTrackIDFor(MediaStream* aOutputStream) const
|
||||
+{
|
||||
+ MOZ_ASSERT(NS_IsMainThread());
|
||||
+ for (const OutputStreamData& out : mStreams) {
|
||||
+ if (out.Equals(aOutputStream)) {
|
||||
+ return out.NextAvailableTrackID();
|
||||
+ }
|
||||
+ }
|
||||
+ return TRACK_INVALID;
|
||||
+}
|
||||
+
|
||||
void
|
||||
-OutputStreamManager::Connect(MediaStream* aStream)
|
||||
+OutputStreamManager::Connect(MediaStream* aStream,
|
||||
+ TrackID aAudioTrackID,
|
||||
+ TrackID aVideoTrackID)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mInputStream = aStream;
|
||||
+ mInputAudioTrackID = aAudioTrackID;
|
||||
+ mInputVideoTrackID = aVideoTrackID;
|
||||
for (int32_t i = mStreams.Length() - 1; i >= 0; --i) {
|
||||
- if (!mStreams[i].Connect(aStream)) {
|
||||
+ if (!mStreams[i].Connect(aStream, mInputAudioTrackID, mInputVideoTrackID)) {
|
||||
// Probably the DOMMediaStream was GCed. Clean up.
|
||||
mStreams.RemoveElementAt(i);
|
||||
}
|
||||
@@ -123,6 +159,8 @@ OutputStreamManager::Disconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mInputStream = nullptr;
|
||||
+ mInputAudioTrackID = TRACK_INVALID;
|
||||
+ mInputVideoTrackID = TRACK_INVALID;
|
||||
for (int32_t i = mStreams.Length() - 1; i >= 0; --i) {
|
||||
if (!mStreams[i].Disconnect()) {
|
||||
// Probably the DOMMediaStream was GCed. Clean up.
|
||||
diff --git dom/media/mediasink/OutputStreamManager.h dom/media/mediasink/OutputStreamManager.h
|
||||
index 7f91a60c1e9dd..8e89878e45090 100644
|
||||
--- dom/media/mediasink/OutputStreamManager.h
|
||||
+++ dom/media/mediasink/OutputStreamManager.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsTArray.h"
|
||||
+#include "MediaSegment.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -21,11 +22,13 @@ class ProcessedMediaStream;
|
||||
class OutputStreamData {
|
||||
public:
|
||||
~OutputStreamData();
|
||||
- void Init(OutputStreamManager* aOwner, ProcessedMediaStream* aStream);
|
||||
+ void Init(OutputStreamManager* aOwner,
|
||||
+ ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID);
|
||||
|
||||
- // Connect mStream to the input stream.
|
||||
+ // Connect the given input stream's audio and video tracks to mStream.
|
||||
// Return false is mStream is already destroyed, otherwise true.
|
||||
- bool Connect(MediaStream* aStream);
|
||||
+ bool Connect(MediaStream* aStream, TrackID aAudioTrackID, TrackID aVideoTrackID);
|
||||
// Disconnect mStream from its input stream.
|
||||
// Return false is mStream is already destroyed, otherwise true.
|
||||
bool Disconnect();
|
||||
@@ -34,12 +37,16 @@ public:
|
||||
bool Equals(MediaStream* aStream) const;
|
||||
// Return the graph mStream belongs to.
|
||||
MediaStreamGraph* Graph() const;
|
||||
+ // The next TrackID that will not cause a collision in mStream.
|
||||
+ TrackID NextAvailableTrackID() const;
|
||||
|
||||
private:
|
||||
OutputStreamManager* mOwner;
|
||||
RefPtr<ProcessedMediaStream> mStream;
|
||||
- // mPort connects our mStream to an input stream.
|
||||
- RefPtr<MediaInputPort> mPort;
|
||||
+ // mPort connects an input stream to our mStream.
|
||||
+ nsTArray<RefPtr<MediaInputPort>> mPorts;
|
||||
+ // For guaranteeing TrackID uniqueness in our mStream.
|
||||
+ TrackID mNextAvailableTrackID = TRACK_INVALID;
|
||||
};
|
||||
|
||||
class OutputStreamManager {
|
||||
@@ -47,18 +54,24 @@ class OutputStreamManager {
|
||||
|
||||
public:
|
||||
// Add the output stream to the collection.
|
||||
- void Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
+ void Add(ProcessedMediaStream* aStream,
|
||||
+ TrackID aNextAvailableTrackID,
|
||||
+ bool aFinishWhenEnded);
|
||||
// Remove the output stream from the collection.
|
||||
void Remove(MediaStream* aStream);
|
||||
+ // The next TrackID that will not cause a collision in aOutputStream.
|
||||
+ TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const;
|
||||
// Return true if the collection empty.
|
||||
bool IsEmpty() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mStreams.IsEmpty();
|
||||
}
|
||||
- // Connect all output streams in the collection to the input stream.
|
||||
- void Connect(MediaStream* aStream);
|
||||
- // Disconnect all output streams from the input stream.
|
||||
+ // Connect the given input stream's tracks to all output streams.
|
||||
+ void Connect(MediaStream* aStream,
|
||||
+ TrackID aAudioTrackID,
|
||||
+ TrackID aVideoTrackID);
|
||||
+ // Disconnect the input stream to all output streams.
|
||||
void Disconnect();
|
||||
// Return the graph these streams belong to or null if empty.
|
||||
MediaStreamGraph* Graph() const
|
||||
@@ -72,6 +85,8 @@ private:
|
||||
// Keep the input stream so we can connect the output streams that
|
||||
// are added after Connect().
|
||||
RefPtr<MediaStream> mInputStream;
|
||||
+ TrackID mInputAudioTrackID = TRACK_INVALID;
|
||||
+ TrackID mInputVideoTrackID = TRACK_INVALID;
|
||||
nsTArray<OutputStreamData> mStreams;
|
||||
};
|
||||
|
||||
|
||||
commit 91317ba976c8
|
||||
Author: Andreas Pehrson <pehrsons@mozilla.com>
|
||||
Date: Wed May 30 10:44:56 2018 +0200
|
||||
|
||||
Bug 1453127 - Clear output streams on shutdown. r=jya, a=RyanVM
|
||||
---
|
||||
dom/media/MediaDecoderStateMachine.cpp | 4 ++++
|
||||
dom/media/mediasink/OutputStreamManager.cpp | 7 +++++++
|
||||
dom/media/mediasink/OutputStreamManager.h | 2 ++
|
||||
3 files changed, 13 insertions(+)
|
||||
|
||||
diff --git dom/media/MediaDecoderStateMachine.cpp dom/media/MediaDecoderStateMachine.cpp
|
||||
index fef3b318b48cb..582fe7ba995fe 100644
|
||||
--- dom/media/MediaDecoderStateMachine.cpp
|
||||
+++ dom/media/MediaDecoderStateMachine.cpp
|
||||
@@ -3564,6 +3564,10 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
|
||||
RefPtr<ShutdownPromise>
|
||||
MediaDecoderStateMachine::BeginShutdown()
|
||||
{
|
||||
+ MOZ_ASSERT(NS_IsMainThread());
|
||||
+ if (mOutputStreamManager) {
|
||||
+ mOutputStreamManager->Clear();
|
||||
+ }
|
||||
return InvokeAsync(OwnerThread(), this, __func__,
|
||||
&MediaDecoderStateMachine::Shutdown);
|
||||
}
|
||||
diff --git dom/media/mediasink/OutputStreamManager.cpp dom/media/mediasink/OutputStreamManager.cpp
|
||||
index b3ec8936d435e..7ecc203ed8309 100644
|
||||
--- dom/media/mediasink/OutputStreamManager.cpp
|
||||
+++ dom/media/mediasink/OutputStreamManager.cpp
|
||||
@@ -125,6 +125,13 @@ OutputStreamManager::Remove(MediaStream* aStream)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+OutputStreamManager::Clear()
|
||||
+{
|
||||
+ MOZ_ASSERT(NS_IsMainThread());
|
||||
+ mStreams.Clear();
|
||||
+}
|
||||
+
|
||||
TrackID
|
||||
OutputStreamManager::NextAvailableTrackIDFor(MediaStream* aOutputStream) const
|
||||
{
|
||||
diff --git dom/media/mediasink/OutputStreamManager.h dom/media/mediasink/OutputStreamManager.h
|
||||
index 8e89878e45090..ec5040178ee0b 100644
|
||||
--- dom/media/mediasink/OutputStreamManager.h
|
||||
+++ dom/media/mediasink/OutputStreamManager.h
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
bool aFinishWhenEnded);
|
||||
// Remove the output stream from the collection.
|
||||
void Remove(MediaStream* aStream);
|
||||
+ // Clear all output streams from the collection.
|
||||
+ void Clear();
|
||||
// The next TrackID that will not cause a collision in aOutputStream.
|
||||
TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const;
|
||||
// Return true if the collection empty.
|
||||
|
80
www/waterfox/files/patch-bug1461448
Normal file
80
www/waterfox/files/patch-bug1461448
Normal file
@ -0,0 +1,80 @@
|
||||
commit cd48fc1a4518
|
||||
Author: Jon Coppeard <jcoppeard@mozilla.com>
|
||||
Date: Fri May 18 10:29:00 2018 +0100
|
||||
|
||||
Bug 1461448 - Add gray marking phase to delayed marking phase. r=sfink, a=RyanVM
|
||||
|
||||
--HG--
|
||||
extra : source : ff105a4cff4eb85a9e50a4ccf8144069412521e5
|
||||
---
|
||||
js/src/gc/GenerateStatsPhases.py | 6 +++--
|
||||
js/src/jit-test/tests/gc/bug-1461448.js | 40 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git js/src/gc/GenerateStatsPhases.py js/src/gc/GenerateStatsPhases.py
|
||||
index ece873dc05004..2daf83555e33b 100644
|
||||
--- js/src/gc/GenerateStatsPhases.py
|
||||
+++ js/src/gc/GenerateStatsPhases.py
|
||||
@@ -88,12 +88,14 @@ PhaseKindGraphRoots = [
|
||||
PhaseKind("PURGE", "Purge", 5),
|
||||
PhaseKind("PURGE_SHAPE_TABLES", "Purge ShapeTables", 60),
|
||||
JoinParallelTasksPhaseKind
|
||||
- ]),
|
||||
+ ]),
|
||||
PhaseKind("MARK", "Mark", 6, [
|
||||
MarkRootsPhaseKind,
|
||||
UnmarkGrayPhaseKind,
|
||||
- PhaseKind("MARK_DELAYED", "Mark Delayed", 8)
|
||||
+ PhaseKind("MARK_DELAYED", "Mark Delayed", 8, [
|
||||
+ UnmarkGrayPhaseKind,
|
||||
]),
|
||||
+ ]),
|
||||
PhaseKind("SWEEP", "Sweep", 9, [
|
||||
PhaseKind("SWEEP_MARK", "Mark During Sweeping", 10, [
|
||||
UnmarkGrayPhaseKind,
|
||||
diff --git js/src/jit-test/tests/gc/bug-1461448.js js/src/jit-test/tests/gc/bug-1461448.js
|
||||
new file mode 100644
|
||||
index 0000000000000..3b9e69df89101
|
||||
--- /dev/null
|
||||
+++ js/src/jit-test/tests/gc/bug-1461448.js
|
||||
@@ -0,0 +1,40 @@
|
||||
+if (helperThreadCount() === 0)
|
||||
+ quit();
|
||||
+
|
||||
+gczeal(0);
|
||||
+
|
||||
+let lfPreamble = `
|
||||
+ var lfOffThreadGlobal = newGlobal();
|
||||
+ for (lfLocal in this)
|
||||
+ try {} catch(lfVare5) {}
|
||||
+`;
|
||||
+evaluate(lfPreamble);
|
||||
+evaluate(`
|
||||
+ var g = newGlobal();
|
||||
+ var dbg = new Debugger;
|
||||
+ var gw = dbg.addDebuggee(g);
|
||||
+ for (lfLocal in this)
|
||||
+ if (!(lfLocal in lfOffThreadGlobal))
|
||||
+ try {
|
||||
+ lfOffThreadGlobal[lfLocal] = this[lfLocal];
|
||||
+ } catch(lfVare5) {}
|
||||
+ var g = newGlobal();
|
||||
+ var gw = dbg.addDebuggee(g);
|
||||
+`);
|
||||
+lfOffThreadGlobal.offThreadCompileScript(`
|
||||
+ gcparam("markStackLimit", 1);
|
||||
+ grayRoot()[0] = "foo";
|
||||
+`);
|
||||
+lfOffThreadGlobal.runOffThreadScript();
|
||||
+eval(`
|
||||
+ var lfOffThreadGlobal = newGlobal();
|
||||
+ try { evaluate(\`
|
||||
+ gczeal(18, 1);
|
||||
+ grayRoot()[0] = "foo";
|
||||
+ let inst = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
|
||||
+ \\\`(module
|
||||
+ (memory (export "memory") 1 1)
|
||||
+ )\\\`
|
||||
+ )));
|
||||
+\`); } catch(exc) {}
|
||||
+`);
|
28
www/waterfox/files/patch-z-bug1392739
Normal file
28
www/waterfox/files/patch-z-bug1392739
Normal file
@ -0,0 +1,28 @@
|
||||
commit ef5f80343490
|
||||
Author: Valentin Gosu <valentin.gosu@gmail.com>
|
||||
Date: Mon Jun 4 13:57:51 2018 +0200
|
||||
|
||||
Bug 1392739 - Use CheckedInt in nsStandardURL::Deserialize(). r=mayhemer, a=RyanVM
|
||||
|
||||
--HG--
|
||||
extra : source : 5c47f8a1bad20a61a1ec699cc6508e21f39a7a98
|
||||
---
|
||||
netwerk/base/nsStandardURL.cpp | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git netwerk/base/nsStandardURL.cpp netwerk/base/nsStandardURL.cpp
|
||||
index db7bf74f31812..4d3da91f88b20 100644
|
||||
--- netwerk/base/nsStandardURL.cpp
|
||||
+++ netwerk/base/nsStandardURL.cpp
|
||||
@@ -3552,8 +3551,10 @@ FromIPCSegment(const nsACString& aSpec, const ipc::StandardURLSegment& aSegment,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ CheckedInt<uint32_t> segmentLen = aSegment.position();
|
||||
+ segmentLen += aSegment.length();
|
||||
// Make sure the segment does not extend beyond the spec.
|
||||
- if (NS_WARN_IF(aSegment.position() + aSegment.length() > aSpec.Length())) {
|
||||
+ if (NS_WARN_IF(!segmentLen.isValid() || segmentLen.value() > aSpec.Length())) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user