Title: [269632] trunk
Revision
269632
Author
[email protected]
Date
2020-11-10 11:15:33 -0800 (Tue, 10 Nov 2020)

Log Message

Crash when accessing OfflineAudioContext.length after failing to construct rendering AudioBuffer
https://bugs.webkit.org/show_bug.cgi?id=218754
<rdar://problem/71186978>

Reviewed by Eric Carlson.

Source/WebCore:

OfflineAudioContext.length should return the length passed to the constructor, even if we
failed to construct the internal AudioBuffer (and obviously we should not crash). This
matches the behavior of Firefox and Chrome.

I have also added a console message when we fail to construct the internal rendering
AudioBuffer, for clarity.

Test: webaudio/OfflineAudioContext/bad-buffer-length.html

* Modules/webaudio/OfflineAudioContext.cpp:
(WebCore::OfflineAudioContext::OfflineAudioContext):
(WebCore::OfflineAudioContext::create):
* Modules/webaudio/OfflineAudioContext.h:

LayoutTests:

Add layout test coverage and rebaseline a couple of tests now that a console message is logged.

* webaudio/OfflineAudioContext-bad-buffer-crash-expected.txt:
* webaudio/OfflineAudioContext/bad-buffer-length-expected.txt: Added.
* webaudio/OfflineAudioContext/bad-buffer-length.html: Added.
* webaudio/dom-exceptions-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269631 => 269632)


--- trunk/LayoutTests/ChangeLog	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/LayoutTests/ChangeLog	2020-11-10 19:15:33 UTC (rev 269632)
@@ -1,3 +1,18 @@
+2020-11-10  Chris Dumez  <[email protected]>
+
+        Crash when accessing OfflineAudioContext.length after failing to construct rendering AudioBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=218754
+        <rdar://problem/71186978>
+
+        Reviewed by Eric Carlson.
+
+        Add layout test coverage and rebaseline a couple of tests now that a console message is logged.
+
+        * webaudio/OfflineAudioContext-bad-buffer-crash-expected.txt:
+        * webaudio/OfflineAudioContext/bad-buffer-length-expected.txt: Added.
+        * webaudio/OfflineAudioContext/bad-buffer-length.html: Added.
+        * webaudio/dom-exceptions-expected.txt:
+
 2020-11-10  Jer Noble  <[email protected]>
 
         Add support for AudioConfiguration.spatialRendering

Added: trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length-expected.txt (0 => 269632)


--- trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length-expected.txt	2020-11-10 19:15:33 UTC (rev 269632)
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: Failed to construct internal AudioBuffer with 1 channel(s), a sample rate of 44000 and a length of 536870912.
+Make sure that the length returned by OfflineAudioContext even if we failed to construct the rendering buffer.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS new OfflineAudioContext(1, 2**29, 44000).length is 2**29
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length.html (0 => 269632)


--- trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length.html	                        (rev 0)
+++ trunk/LayoutTests/webaudio/OfflineAudioContext/bad-buffer-length.html	2020-11-10 19:15:33 UTC (rev 269632)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Make sure that the length returned by OfflineAudioContext even if we failed to construct the rendering buffer.");
+
+shouldBe("new OfflineAudioContext(1, 2**29, 44000).length", "2**29");
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/webaudio/OfflineAudioContext-bad-buffer-crash-expected.txt (269631 => 269632)


--- trunk/LayoutTests/webaudio/OfflineAudioContext-bad-buffer-crash-expected.txt	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/LayoutTests/webaudio/OfflineAudioContext-bad-buffer-crash-expected.txt	2020-11-10 19:15:33 UTC (rev 269632)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Failed to construct internal AudioBuffer with 1 channel(s), a sample rate of 44000 and a length of 536870912.
 This test passes if it does not crash.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Modified: trunk/LayoutTests/webaudio/dom-exceptions-expected.txt (269631 => 269632)


--- trunk/LayoutTests/webaudio/dom-exceptions-expected.txt	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/LayoutTests/webaudio/dom-exceptions-expected.txt	2020-11-10 19:15:33 UTC (rev 269632)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Failed to construct internal AudioBuffer with 1 channel(s), a sample rate of 44100 and a length of 1448390656.
 
 PASS # AUDIT TASK RUNNER STARTED.
 PASS Executing "initialize"

Modified: trunk/Source/WebCore/ChangeLog (269631 => 269632)


--- trunk/Source/WebCore/ChangeLog	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/Source/WebCore/ChangeLog	2020-11-10 19:15:33 UTC (rev 269632)
@@ -1,3 +1,25 @@
+2020-11-10  Chris Dumez  <[email protected]>
+
+        Crash when accessing OfflineAudioContext.length after failing to construct rendering AudioBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=218754
+        <rdar://problem/71186978>
+
+        Reviewed by Eric Carlson.
+
+        OfflineAudioContext.length should return the length passed to the constructor, even if we
+        failed to construct the internal AudioBuffer (and obviously we should not crash). This
+        matches the behavior of Firefox and Chrome.
+
+        I have also added a console message when we fail to construct the internal rendering
+        AudioBuffer, for clarity.
+
+        Test: webaudio/OfflineAudioContext/bad-buffer-length.html
+
+        * Modules/webaudio/OfflineAudioContext.cpp:
+        (WebCore::OfflineAudioContext::OfflineAudioContext):
+        (WebCore::OfflineAudioContext::create):
+        * Modules/webaudio/OfflineAudioContext.h:
+
 2020-11-10  Jer Noble  <[email protected]>
 
         Add support for AudioConfiguration.spatialRendering

Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp (269631 => 269632)


--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp	2020-11-10 19:15:33 UTC (rev 269632)
@@ -38,12 +38,13 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(OfflineAudioContext);
 
-inline OfflineAudioContext::OfflineAudioContext(Document& document, unsigned numberOfChannels, float sampleRate, RefPtr<AudioBuffer>&& renderTarget)
+inline OfflineAudioContext::OfflineAudioContext(Document& document, unsigned numberOfChannels, unsigned length, float sampleRate, RefPtr<AudioBuffer>&& renderTarget)
     : BaseAudioContext(document, numberOfChannels, sampleRate, WTFMove(renderTarget))
+    , m_length(length)
 {
 }
 
-ExceptionOr<Ref<OfflineAudioContext>> OfflineAudioContext::create(ScriptExecutionContext& context, unsigned numberOfChannels, size_t length, float sampleRate)
+ExceptionOr<Ref<OfflineAudioContext>> OfflineAudioContext::create(ScriptExecutionContext& context, unsigned numberOfChannels, unsigned length, float sampleRate)
 {
     if (!is<Document>(context))
         return Exception { NotSupportedError, "OfflineAudioContext is only supported in Document contexts"_s };
@@ -55,7 +56,10 @@
         return Exception { SyntaxError, "sampleRate is not in range"_s };
 
     auto renderTarget = AudioBuffer::create(numberOfChannels, length, sampleRate);
-    auto audioContext = adoptRef(*new OfflineAudioContext(downcast<Document>(context), numberOfChannels, sampleRate, WTFMove(renderTarget)));
+    if (!renderTarget)
+        context.addConsoleMessage(MessageSource::JS, MessageLevel::Warning, makeString("Failed to construct internal AudioBuffer with ", numberOfChannels, " channel(s), a sample rate of ", sampleRate, " and a length of ", length, "."));
+
+    auto audioContext = adoptRef(*new OfflineAudioContext(downcast<Document>(context), numberOfChannels, length, sampleRate, WTFMove(renderTarget)));
     audioContext->suspendIfNeeded();
     return audioContext;
 }
@@ -217,11 +221,6 @@
     promise->resolve<IDLInterface<AudioBuffer>>(result.releaseReturnValue());
 }
 
-unsigned OfflineAudioContext::length() const
-{
-    return renderTarget()->length();
-}
-
 void OfflineAudioContext::offlineLock(bool& mustReleaseLock)
 {
     ASSERT(!isMainThread());

Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h (269631 => 269632)


--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h	2020-11-10 19:10:31 UTC (rev 269631)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.h	2020-11-10 19:15:33 UTC (rev 269632)
@@ -36,7 +36,7 @@
 class OfflineAudioContext final : public BaseAudioContext {
     WTF_MAKE_ISO_ALLOCATED(OfflineAudioContext);
 public:
-    static ExceptionOr<Ref<OfflineAudioContext>> create(ScriptExecutionContext&, unsigned numberOfChannels, size_t length, float sampleRate);
+    static ExceptionOr<Ref<OfflineAudioContext>> create(ScriptExecutionContext&, unsigned numberOfChannels, unsigned length, float sampleRate);
     
     static ExceptionOr<Ref<OfflineAudioContext>> create(ScriptExecutionContext&, const OfflineAudioContextOptions&);
 
@@ -44,7 +44,7 @@
     void suspendOfflineRendering(double suspendTime, Ref<DeferredPromise>&&);
     void resumeOfflineRendering(Ref<DeferredPromise>&&);
 
-    unsigned length() const;
+    unsigned length() const { return m_length; }
     bool shouldSuspend() final;
 
     OfflineAudioDestinationNode* destination() { return static_cast<OfflineAudioDestinationNode*>(BaseAudioContext::destination()); }
@@ -72,7 +72,7 @@
     };
 
 private:
-    OfflineAudioContext(Document&, unsigned numberOfChannels, float sampleRate, RefPtr<AudioBuffer>&& renderTarget);
+    OfflineAudioContext(Document&, unsigned numberOfChannels, unsigned length, float sampleRate, RefPtr<AudioBuffer>&& renderTarget);
 
     void didFinishOfflineRendering(ExceptionOr<Ref<AudioBuffer>>&&) final;
     void didSuspendRendering(size_t frame) final;
@@ -80,6 +80,7 @@
 
     RefPtr<DeferredPromise> m_pendingOfflineRenderingPromise;
     HashMap<unsigned /* frame */, RefPtr<DeferredPromise>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_suspendRequests;
+    unsigned m_length;
     bool m_didStartOfflineRendering { false };
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to