[iOS] Crash when playing <video> after playing Web Audio
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Apr 2016 05:39:18 +0000 (05:39 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Apr 2016 05:39:18 +0000 (05:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156185
<rdar://problem/10177005>

Reviewed by Eric Carlson.

Off-by-one error in AudioDestinationIOS::render. The ivars m_firstSpareFrame and m_lastSpareFrame imply that
the sample range is inclusive, i.e. [m_firstSpareFrame .. m_lastSpareFrame], but the length of the range was
being calculated as if m_lastSpareFrame was exclusive; when the two were equal, the length was calculated as
0, rather than 1. This was caught by an ASSERT (and would have been caught by a downstream ASSERT had that one
not been present).

Fix the off-by-one by treating them as inclusive/exclusive--similar to C++ iterators--and renaming them to reflect
this: [m_startSpareFrame .. m_endSpareFrame). This corrects the "length" math which caused the crash.

* platform/audio/ios/AudioDestinationIOS.cpp:
(WebCore::AudioDestinationIOS::render):
* platform/audio/ios/AudioDestinationIOS.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@199042 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp
Source/WebCore/platform/audio/ios/AudioDestinationIOS.h

index 542e332..dbaa1bf 100644 (file)
@@ -1,3 +1,24 @@
+2016-04-04  Jer Noble  <jer.noble@apple.com>
+
+        [iOS] Crash when playing <video> after playing Web Audio
+        https://bugs.webkit.org/show_bug.cgi?id=156185
+        <rdar://problem/10177005>
+
+        Reviewed by Eric Carlson.
+
+        Off-by-one error in AudioDestinationIOS::render. The ivars m_firstSpareFrame and m_lastSpareFrame imply that
+        the sample range is inclusive, i.e. [m_firstSpareFrame .. m_lastSpareFrame], but the length of the range was
+        being calculated as if m_lastSpareFrame was exclusive; when the two were equal, the length was calculated as
+        0, rather than 1. This was caught by an ASSERT (and would have been caught by a downstream ASSERT had that one
+        not been present).
+
+        Fix the off-by-one by treating them as inclusive/exclusive--similar to C++ iterators--and renaming them to reflect
+        this: [m_startSpareFrame .. m_endSpareFrame). This corrects the "length" math which caused the crash.
+
+        * platform/audio/ios/AudioDestinationIOS.cpp:
+        (WebCore::AudioDestinationIOS::render):
+        * platform/audio/ios/AudioDestinationIOS.h:
+
 2016-04-04  John Wilander  <wilander@apple.com>
 
         Block plaintext WebSocket requests to domains under HSTS.
index 765aaed..f6b0cf6 100644 (file)
@@ -218,15 +218,15 @@ OSStatus AudioDestinationIOS::render(UInt32 numberOfFrames, AudioBufferList* ioD
     UInt32 framesRemaining = numberOfFrames;
     UInt32 frameOffset = 0;
     while (framesRemaining > 0) {
-        if (m_firstSpareFrame && m_lastSpareFrame) {
-            ASSERT(m_firstSpareFrame < m_lastSpareFrame);
-            UInt32 framesThisTime = m_lastSpareFrame - m_firstSpareFrame;
+        if (m_startSpareFrame && m_endSpareFrame) {
+            ASSERT(m_startSpareFrame < m_endSpareFrame);
+            UInt32 framesThisTime = m_endSpareFrame - m_startSpareFrame;
             assignAudioBuffersToBus(buffers, *m_renderBus, numberOfBuffers, numberOfFrames, frameOffset, framesThisTime);
-            m_renderBus->copyFromRange(*m_spareBus, m_firstSpareFrame, m_lastSpareFrame);
+            m_renderBus->copyFromRange(*m_spareBus, m_startSpareFrame, m_endSpareFrame);
             frameOffset += framesThisTime;
             framesRemaining -= framesThisTime;
-            m_firstSpareFrame = 0;
-            m_lastSpareFrame = 0;
+            m_startSpareFrame = 0;
+            m_endSpareFrame = 0;
         }
 
         UInt32 framesThisTime = std::min<UInt32>(kRenderBufferSize, framesRemaining);
@@ -235,8 +235,8 @@ OSStatus AudioDestinationIOS::render(UInt32 numberOfFrames, AudioBufferList* ioD
         if (framesThisTime < kRenderBufferSize) {
             m_callback.render(0, m_spareBus.get(), kRenderBufferSize);
             m_renderBus->copyFromRange(*m_spareBus, 0, framesThisTime);
-            m_firstSpareFrame = framesThisTime;
-            m_lastSpareFrame = kRenderBufferSize - 1;
+            m_startSpareFrame = framesThisTime;
+            m_endSpareFrame = kRenderBufferSize;
         } else
             m_callback.render(0, m_renderBus.get(), framesThisTime);
         frameOffset += framesThisTime;
index b572383..6bc046c 100644 (file)
@@ -66,8 +66,8 @@ private:
     AudioIOCallback& m_callback;
     RefPtr<AudioBus> m_renderBus;
     RefPtr<AudioBus> m_spareBus;
-    unsigned m_firstSpareFrame { 0 };
-    unsigned m_lastSpareFrame { 0 };
+    unsigned m_startSpareFrame { 0 };
+    unsigned m_endSpareFrame { 0 };
 
     double m_sampleRate;
     bool m_isPlaying;