[Crash] WebCore::AudioBuffer::AudioBuffer don't checking illegal value
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Mar 2017 20:17:08 +0000 (20:17 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Mar 2017 20:17:08 +0000 (20:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169956

Reviewed by Youenn Fablet.

Source/WebCore:

Test: webaudio/audiobuffer-crash.html

* Modules/webaudio/AudioBuffer.cpp:
(WebCore::AudioBuffer::AudioBuffer): Invalidate the object and return early if the channel
array allocation fails.
(WebCore::AudioBuffer::AudioBuffer): Ditto.
(WebCore::AudioBuffer::invalidate): Invalidate the object.
* Modules/webaudio/AudioBuffer.h:

LayoutTests:

* webaudio/audiobuffer-crash-expected.txt: Added.
* webaudio/audiobuffer-crash.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/webaudio/audiobuffer-crash-expected.txt [new file with mode: 0644]
LayoutTests/webaudio/audiobuffer-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webaudio/AudioBuffer.cpp
Source/WebCore/Modules/webaudio/AudioBuffer.h

index e279549..6e3abda 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-30  Eric Carlson  <eric.carlson@apple.com>
+
+        [Crash] WebCore::AudioBuffer::AudioBuffer don't checking illegal value
+        https://bugs.webkit.org/show_bug.cgi?id=169956
+
+        Reviewed by Youenn Fablet.
+
+        * webaudio/audiobuffer-crash-expected.txt: Added.
+        * webaudio/audiobuffer-crash.html: Added.
+
 2017-03-30  Simon Fraser  <simon.fraser@apple.com>
 
         Add some tests that dump the touch event regions with various content configurations
diff --git a/LayoutTests/webaudio/audiobuffer-crash-expected.txt b/LayoutTests/webaudio/audiobuffer-crash-expected.txt
new file mode 100644 (file)
index 0000000..94a5b01
--- /dev/null
@@ -0,0 +1,11 @@
+Attempting to create a large AudioBuffer should not crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS context = new webkitAudioContext().createBuffer(1, -1, 44100) threw exception NotSupportedError (DOM Exception 9): The operation is not supported..
+PASS Test passed because if it didn't crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/webaudio/audiobuffer-crash.html b/LayoutTests/webaudio/audiobuffer-crash.html
new file mode 100644 (file)
index 0000000..e104fb5
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+    <head>
+    <script src="../resources/js-test-pre.js"></script>
+    </head>
+    <body>
+        <script>
+            description("Attempting to create a large AudioBuffer should not crash.");
+            shouldThrow("context = new webkitAudioContext().createBuffer(1, -1, 44100)");
+            testPassed("Test passed because if it didn't crash.");
+        </script>
+
+        <script src="../resources/js-test-post.js"></script>
+    </body>
+</html>
index c43eed2..78e236d 100644 (file)
@@ -1,3 +1,19 @@
+2017-03-30  Eric Carlson  <eric.carlson@apple.com>
+
+        [Crash] WebCore::AudioBuffer::AudioBuffer don't checking illegal value
+        https://bugs.webkit.org/show_bug.cgi?id=169956
+
+        Reviewed by Youenn Fablet.
+
+        Test: webaudio/audiobuffer-crash.html
+
+        * Modules/webaudio/AudioBuffer.cpp:
+        (WebCore::AudioBuffer::AudioBuffer): Invalidate the object and return early if the channel 
+        array allocation fails.
+        (WebCore::AudioBuffer::AudioBuffer): Ditto.
+        (WebCore::AudioBuffer::invalidate): Invalidate the object.
+        * Modules/webaudio/AudioBuffer.h:
+
 2017-03-30  Antoine Quint  <graouts@apple.com>
 
         [mac-wk1] LayoutTest media/modern-media-controls/airplay-button/airplay-button.html is a flaky timeout
index 43d760f..d14e669 100644 (file)
@@ -43,7 +43,12 @@ RefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t number
 {
     if (sampleRate < 22050 || sampleRate > 96000 || numberOfChannels > AudioContext::maxNumberOfChannels() || !numberOfFrames)
         return nullptr;
-    return adoptRef(*new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate));
+
+    auto buffer = adoptRef(*new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate));
+    if (!buffer->m_length)
+        return nullptr;
+
+    return WTFMove(buffer);
 }
 
 RefPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate)
@@ -61,9 +66,14 @@ AudioBuffer::AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, float
     m_channels.reserveCapacity(numberOfChannels);
 
     for (unsigned i = 0; i < numberOfChannels; ++i) {
-        RefPtr<Float32Array> channelDataArray = Float32Array::create(m_length);
+        auto channelDataArray = Float32Array::create(m_length);
+        if (!channelDataArray) {
+            invalidate();
+            break;
+        }
+
         channelDataArray->setNeuterable(false);
-        m_channels.append(channelDataArray);
+        m_channels.append(WTFMove(channelDataArray));
     }
 }
 
@@ -76,12 +86,23 @@ AudioBuffer::AudioBuffer(AudioBus& bus)
     m_channels.reserveCapacity(numberOfChannels);
     for (unsigned i = 0; i < numberOfChannels; ++i) {
         auto channelDataArray = Float32Array::create(m_length);
+        if (!channelDataArray) {
+            invalidate();
+            break;
+        }
+
         channelDataArray->setNeuterable(false);
         channelDataArray->setRange(bus.channel(i)->data(), m_length, 0);
         m_channels.append(WTFMove(channelDataArray));
     }
 }
 
+void AudioBuffer::invalidate()
+{
+    releaseMemory();
+    m_length = 0;
+}
+
 void AudioBuffer::releaseMemory()
 {
     m_channels.clear();
index 394a0d3..9c9dd1d 100644 (file)
@@ -69,6 +69,8 @@ private:
     AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
     explicit AudioBuffer(AudioBus&);
 
+    void invalidate();
+
     double m_gain { 1.0 }; // scalar gain
     float m_sampleRate;
     size_t m_length;