<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[210945] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/210945">210945</a></dd>
<dt>Author</dt> <dd>jer.noble@apple.com</dd>
<dt>Date</dt> <dd>2017-01-19 17:09:20 -0800 (Thu, 19 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmltrackTrackListBasecpp">trunk/Source/WebCore/html/track/TrackListBase.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceerrorcrashexpectedtxt">trunk/LayoutTests/media/media-source/media-source-error-crash-expected.txt</a></li>
<li><a href="#trunkLayoutTestsmediamediasourcemediasourceerrorcrashhtml">trunk/LayoutTests/media/media-source/media-source-error-crash.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (210944 => 210945)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-01-20 00:56:28 UTC (rev 210944)
+++ trunk/LayoutTests/ChangeLog        2017-01-20 01:09:20 UTC (rev 210945)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2017-01-19  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        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.
+
</ins><span class="cx"> 2017-01-19  Megan Gardner  &lt;megan_gardner@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Additional selection tests and interpolation fix
</span></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceerrorcrashexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-error-crash-expected.txt (0 => 210945)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+
+RUN(video.src = URL.createObjectURL(source))
+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
+
</ins></span></pre></div>
<a id="trunkLayoutTestsmediamediasourcemediasourceerrorcrashhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/media/media-source/media-source-error-crash.html (0 => 210945)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;title&gt;media-source-error-crash&lt;/title&gt;
+    &lt;script src=&quot;media-source-loader.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;../video-test.js&quot;&gt;&lt;/script&gt;
+    &lt;script&gt;
+    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 = URL.createObjectURL(source)');
+    }
+
+    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)))');
+    }
+
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;video controls&gt;&lt;/video&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (210944 => 210945)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2017-01-19  Jer Noble  &lt;jer.noble@apple.com&gt;
+
+        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):
+
</ins><span class="cx"> 2017-01-19  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Move the PDF password view into its own class for reuse
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackTrackListBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/TrackListBase.cpp (210944 => 210945)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -71,7 +71,8 @@
</span><span class="cx"> void TrackListBase::remove(TrackBase&amp; track, bool scheduleEvent)
</span><span class="cx"> {
</span><span class="cx">     size_t index = m_inbandTracks.find(&amp;track);
</span><del>-    ASSERT(index != notFound);
</del><ins>+    if (index == notFound)
+        return;
</ins><span class="cx"> 
</span><span class="cx">     if (track.mediaElement()) {
</span><span class="cx">         ASSERT(track.mediaElement() == m_element);
</span></span></pre>
</div>
</div>

</body>
</html>