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 };
};