OfflineAudioContext does not validate allocation of destination buffer
https://bugs.webkit.org/show_bug.cgi?id=177259
Patch by Bjorn Melinder <bjornm@spotify.com> on 2019-10-11
Reviewed by Eric Carlson.
Moved the allocation of the destination buffer to the static
OfflineAudioContext::create method where we are able to handle a failed
allocation properly and return an Exception. This change handles both
negative lengths as well as too large lengths where the memory cannot
be allocated.
Source/WebCore:
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::AudioContext):
* Modules/webaudio/AudioContext.h:
* Modules/webaudio/OfflineAudioContext.cpp:
(WebCore::OfflineAudioContext::OfflineAudioContext):
(WebCore::OfflineAudioContext::create):
* Modules/webaudio/OfflineAudioContext.h:
LayoutTests:
* webaudio/offlineaudiocontext-constructor-expected.txt:
* webaudio/offlineaudiocontext-constructor.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251007 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c269e3a..91a216e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2019-10-11 Bjorn Melinder <bjornm@spotify.com>
+
+ OfflineAudioContext does not validate allocation of destination buffer
+ https://bugs.webkit.org/show_bug.cgi?id=177259
+
+ Reviewed by Eric Carlson.
+
+ Moved the allocation of the destination buffer to the static
+ OfflineAudioContext::create method where we are able to handle a failed
+ allocation properly and return an Exception. This change handles both
+ negative lengths as well as too large lengths where the memory cannot
+ be allocated.
+
+ * webaudio/offlineaudiocontext-constructor-expected.txt:
+ * webaudio/offlineaudiocontext-constructor.html:
+
2019-10-11 Chris Lord <clord@igalia.com>
Flaky test: imported/w3c/web-platform-tests/offscreen-canvas/compositing/2d.composite.canvas.destination-in.html
diff --git a/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt b/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
index 4d5b555..7ccc0d8 100644
--- a/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
+++ b/LayoutTests/webaudio/offlineaudiocontext-constructor-expected.txt
@@ -4,6 +4,8 @@
PASS new webkitOfflineAudioContext(1, 0, 44100) threw exception SyntaxError: The string did not match the expected pattern..
+PASS new webkitOfflineAudioContext(1, -1, 44100) threw exception SyntaxError: The string did not match the expected pattern..
+PASS new webkitOfflineAudioContext(1, 99999999999, 44100) threw exception SyntaxError: The string did not match the expected pattern..
PASS new webkitOfflineAudioContext(0, 1, 44100) threw exception SyntaxError: The string did not match the expected pattern..
PASS new webkitOfflineAudioContext(1, 1, 0) threw exception SyntaxError: The string did not match the expected pattern..
PASS new webkitOfflineAudioContext(1, 1, 44100) did not throw exception.
diff --git a/LayoutTests/webaudio/offlineaudiocontext-constructor.html b/LayoutTests/webaudio/offlineaudiocontext-constructor.html
index 6805474..1af2653 100644
--- a/LayoutTests/webaudio/offlineaudiocontext-constructor.html
+++ b/LayoutTests/webaudio/offlineaudiocontext-constructor.html
@@ -6,6 +6,8 @@
<script>
description('This tests that passing zero to the "numberOfFrames" parameter of the OfflineAudioContext constructor does not cause a crash.');
shouldThrow('new webkitOfflineAudioContext(1, 0, 44100)');
+ shouldThrow('new webkitOfflineAudioContext(1, -1, 44100)');
+ shouldThrow('new webkitOfflineAudioContext(1, 99999999999, 44100)');
shouldThrow('new webkitOfflineAudioContext(0, 1, 44100)');
shouldThrow('new webkitOfflineAudioContext(1, 1, 0)');
shouldNotThrow('new webkitOfflineAudioContext(1, 1, 44100)');
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f3f0780..2eaa342 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2019-10-11 Bjorn Melinder <bjornm@spotify.com>
+
+ OfflineAudioContext does not validate allocation of destination buffer
+ https://bugs.webkit.org/show_bug.cgi?id=177259
+
+ Reviewed by Eric Carlson.
+
+ Moved the allocation of the destination buffer to the static
+ OfflineAudioContext::create method where we are able to handle a failed
+ allocation properly and return an Exception. This change handles both
+ negative lengths as well as too large lengths where the memory cannot
+ be allocated.
+
+ * Modules/webaudio/AudioContext.cpp:
+ (WebCore::AudioContext::AudioContext):
+ * Modules/webaudio/AudioContext.h:
+ * Modules/webaudio/OfflineAudioContext.cpp:
+ (WebCore::OfflineAudioContext::OfflineAudioContext):
+ (WebCore::OfflineAudioContext::create):
+ * Modules/webaudio/OfflineAudioContext.h:
+
2019-10-10 Konstantin Tokarev <annulen@yandex.ru>
Guard GCrypt-specific code with USE(GCRYPT) instead of PLATFORM macros
diff --git a/Source/WebCore/Modules/webaudio/AudioContext.cpp b/Source/WebCore/Modules/webaudio/AudioContext.cpp
index c627f33..dd2e5ce 100644
--- a/Source/WebCore/Modules/webaudio/AudioContext.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioContext.cpp
@@ -158,7 +158,7 @@
}
// Constructor for offline (non-realtime) rendering.
-AudioContext::AudioContext(Document& document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
+AudioContext::AudioContext(Document& document, AudioBuffer* renderTarget)
: ActiveDOMObject(document)
#if !RELEASE_LOG_DISABLED
, m_logger(document.logger())
@@ -167,11 +167,11 @@
, m_isOfflineContext(true)
, m_mediaSession(PlatformMediaSession::create(*this))
, m_eventQueue(MainThreadGenericEventQueue::create(*this))
+ , m_renderTarget(renderTarget)
{
constructCommon();
// Create a new destination for offline rendering.
- m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate);
m_destinationNode = OfflineAudioDestinationNode::create(*this, m_renderTarget.get());
}
diff --git a/Source/WebCore/Modules/webaudio/AudioContext.h b/Source/WebCore/Modules/webaudio/AudioContext.h
index 0c45ad5..e466f45 100644
--- a/Source/WebCore/Modules/webaudio/AudioContext.h
+++ b/Source/WebCore/Modules/webaudio/AudioContext.h
@@ -296,7 +296,7 @@
protected:
explicit AudioContext(Document&);
- AudioContext(Document&, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
+ AudioContext(Document&, AudioBuffer* renderTarget);
static bool isSampleRateRangeGood(float sampleRate);
void clearPendingActivity();
diff --git a/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp b/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
index ef78ce7..11be75a 100644
--- a/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
+++ b/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
@@ -35,8 +35,8 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(OfflineAudioContext);
-inline OfflineAudioContext::OfflineAudioContext(Document& document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
- : AudioContext(document, numberOfChannels, numberOfFrames, sampleRate)
+inline OfflineAudioContext::OfflineAudioContext(Document& document, AudioBuffer* renderTarget)
+ : AudioContext(document, renderTarget)
{
}
@@ -47,7 +47,11 @@
return Exception { NotSupportedError };
if (!numberOfChannels || numberOfChannels > 10 || !numberOfFrames || !isSampleRateRangeGood(sampleRate))
return Exception { SyntaxError };
- auto audioContext = adoptRef(*new OfflineAudioContext(downcast<Document>(context), numberOfChannels, numberOfFrames, sampleRate));
+ auto renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate);
+ if (!renderTarget)
+ return Exception { SyntaxError };
+
+ auto audioContext = adoptRef(*new OfflineAudioContext(downcast<Document>(context), renderTarget.get()));
audioContext->suspendIfNeeded();
return audioContext;
}
diff --git a/Source/WebCore/Modules/webaudio/OfflineAudioContext.h b/Source/WebCore/Modules/webaudio/OfflineAudioContext.h
index 39cdff5..85a595f 100644
--- a/Source/WebCore/Modules/webaudio/OfflineAudioContext.h
+++ b/Source/WebCore/Modules/webaudio/OfflineAudioContext.h
@@ -34,7 +34,7 @@
static ExceptionOr<Ref<OfflineAudioContext>> create(ScriptExecutionContext&, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
private:
- OfflineAudioContext(Document&, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
+ OfflineAudioContext(Document&, AudioBuffer* renderTarget);
};
} // namespace WebCore