Title: [210945] trunk
Revision
210945
Author
jer.no...@apple.com
Date
2017-01-19 17:09:20 -0800 (Thu, 19 Jan 2017)

Log Message

CRASH at WebCore::TrackListBase::remove
https://bugs.webkit.org/show_bug.cgi?id=167217

Reviewed by Brent Fulgham.

Source/WebCore:

Test: media/media-source/media-source-error-crash.html

In very specific conditions, a HTMLMediaElement backed by a MediaSource can try to remove
the same track from its track list twice. If there are two SourceBuffers attached to a
HTMLMediaElement, and one has not yet been initialized, when the second fails to parse an
appended buffer after receiving an initialization segment, the HTMLMediaElement will remove
all its tracks in mediaLoadingFailed(), then MediaSource object itself will attempt remove
the same track in removeSourceBuffer().

Solving this the safest way possible: bail early from TrackListBase if asked to remove a
track which the list does not contain.

* html/track/TrackListBase.cpp:
(TrackListBase::remove):

LayoutTests:

* media/media-source/media-source-error-crash-expected.txt: Added.
* media/media-source/media-source-error-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (210944 => 210945)


--- trunk/LayoutTests/ChangeLog	2017-01-20 00:56:28 UTC (rev 210944)
+++ trunk/LayoutTests/ChangeLog	2017-01-20 01:09:20 UTC (rev 210945)
@@ -1,3 +1,13 @@
+2017-01-19  Jer Noble  <jer.no...@apple.com>
+
+        CRASH at WebCore::TrackListBase::remove
+        https://bugs.webkit.org/show_bug.cgi?id=167217
+
+        Reviewed by Brent Fulgham.
+
+        * media/media-source/media-source-error-crash-expected.txt: Added.
+        * media/media-source/media-source-error-crash.html: Added.
+
 2017-01-19  Megan Gardner  <megan_gard...@apple.com>
 
         Additional selection tests and interpolation fix

Added: trunk/LayoutTests/media/media-source/media-source-error-crash-expected.txt (0 => 210945)


--- trunk/LayoutTests/media/media-source/media-source-error-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-error-crash-expected.txt	2017-01-20 01:09:20 UTC (rev 210945)
@@ -0,0 +1,11 @@
+
+RUN(video.src = ""
+EVENT(sourceopen)
+RUN(source.duration = loader.duration())
+RUN(sourceBuffer = source.addSourceBuffer(loader.type()))
+RUN(sourceBuffer2 = source.addSourceBuffer(loader.type()))
+Append an invalid media segment; should not crash.
+RUN(sourceBuffer.appendBuffer(concatArrayBuffers(loader.initSegment(), new ArrayBuffer(512))))
+EVENT(error)
+END OF TEST
+

Added: trunk/LayoutTests/media/media-source/media-source-error-crash.html (0 => 210945)


--- trunk/LayoutTests/media/media-source/media-source-error-crash.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-source/media-source-error-crash.html	2017-01-20 01:09:20 UTC (rev 210945)
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>media-source-error-crash</title>
+    <script src=""
+    <script src=""
+    <script>
+    var loader;
+    var source;
+    var sourceBuffer;
+    var sourceBuffer2;
+
+    function concatArrayBuffers(buffer1, buffer2) {
+    	var view = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
+    	view.set(new Uint8Array(buffer1), 0);
+    	view.set(new Uint8Array(buffer2), buffer1.byteLength);
+    	return view.buffer;
+    }
+
+    function runTest() {
+        findMediaElement();
+
+        loader = new MediaSourceLoader('content/test-fragmented-manifest.json');
+        loader._onload_ = mediaDataLoaded;
+        loader._onerror_ = mediaDataLoadingFailed;
+    }
+
+    function mediaDataLoadingFailed() {
+        failTest('Media data loading failed');
+    }
+
+    function mediaDataLoaded() {
+        source = new MediaSource();
+        waitForEvent('sourceopen', sourceOpen, false, false, source);
+        run('video.src = ""
+    }
+
+    function sourceOpen() {
+        run('source.duration = loader.duration()');
+        run('sourceBuffer = source.addSourceBuffer(loader.type())');
+        run('sourceBuffer2 = source.addSourceBuffer(loader.type())');
+        waitForEventAndEnd('error');
+        consoleWrite('Append an invalid media segment; should not crash.')
+        run('sourceBuffer.appendBuffer(concatArrayBuffers(loader.initSegment(), new ArrayBuffer(512)))');
+    }
+
+    </script>
+</head>
+<body _onload_="runTest()">
+    <video controls></video>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (210944 => 210945)


--- trunk/Source/WebCore/ChangeLog	2017-01-20 00:56:28 UTC (rev 210944)
+++ trunk/Source/WebCore/ChangeLog	2017-01-20 01:09:20 UTC (rev 210945)
@@ -1,3 +1,25 @@
+2017-01-19  Jer Noble  <jer.no...@apple.com>
+
+        CRASH at WebCore::TrackListBase::remove
+        https://bugs.webkit.org/show_bug.cgi?id=167217
+
+        Reviewed by Brent Fulgham.
+
+        Test: media/media-source/media-source-error-crash.html
+
+        In very specific conditions, a HTMLMediaElement backed by a MediaSource can try to remove
+        the same track from its track list twice. If there are two SourceBuffers attached to a
+        HTMLMediaElement, and one has not yet been initialized, when the second fails to parse an
+        appended buffer after receiving an initialization segment, the HTMLMediaElement will remove
+        all its tracks in mediaLoadingFailed(), then MediaSource object itself will attempt remove
+        the same track in removeSourceBuffer().
+
+        Solving this the safest way possible: bail early from TrackListBase if asked to remove a
+        track which the list does not contain.
+
+        * html/track/TrackListBase.cpp:
+        (TrackListBase::remove):
+
 2017-01-19  Andy Estes  <aes...@apple.com>
 
         [iOS] Move the PDF password view into its own class for reuse

Modified: trunk/Source/WebCore/html/track/TrackListBase.cpp (210944 => 210945)


--- trunk/Source/WebCore/html/track/TrackListBase.cpp	2017-01-20 00:56:28 UTC (rev 210944)
+++ trunk/Source/WebCore/html/track/TrackListBase.cpp	2017-01-20 01:09:20 UTC (rev 210945)
@@ -71,7 +71,8 @@
 void TrackListBase::remove(TrackBase& track, bool scheduleEvent)
 {
     size_t index = m_inbandTracks.find(&track);
-    ASSERT(index != notFound);
+    if (index == notFound)
+        return;
 
     if (track.mediaElement()) {
         ASSERT(track.mediaElement() == m_element);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to