Commit 264d876a authored by Hongchan Choi's avatar Hongchan Choi Committed by Commit Bot

Throw an exception when ExecutionContext is not available

Some AudioNodes require an access to the execution context (mainly
because of the task runner) and this might not work (null-deref) if
the associated frame/document of a BaseAudioContext is already
detached.

This change adds a check against ExecutionContext in the factory
methods of problematic cases.

Test: Ran submitted reprocases on ASAN and they do not crash anymore.
Bug: 1057735, 1058693, 1058648, 1058687, 1058668
Change-Id: I4c6b994087f8f9561edd4fe8eaa74961fa3bebbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095141
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Reviewed-by: default avatarRaymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748478}
parent 6dd4179e
......@@ -894,4 +894,17 @@ void BaseAudioContext::ReportWillBeDestroyed() {
GraphTracer().WillDestroyBaseAudioContext(this);
}
bool BaseAudioContext::CheckExecutionContextAndThrowIfNecessary(
ExceptionState& exception_state) {
if (!GetExecutionContext()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotAllowedError,
"The operation is not allowed on a detached frame or document because "
"no execution context is available.");
return false;
}
return true;
}
} // namespace blink
......@@ -328,6 +328,11 @@ class MODULES_EXPORT BaseAudioContext
void ReportDidCreate() final;
void ReportWillBeDestroyed() final;
// TODO(crbug.com/1055983): Remove this when the execution context validity
// check is not required in the AudioNode factory methods. Returns false
// if the execution context does not exist.
bool CheckExecutionContextAndThrowIfNecessary(ExceptionState&);
protected:
enum ContextType { kRealtimeContext, kOfflineContext };
......
......@@ -152,6 +152,11 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext& context,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
// TODO(crbug.com/1055983): Remove this when the execution context validity
// check is not required in the AudioNode factory methods.
if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
return nullptr;
return MakeGarbageCollected<BiquadFilterNode>(context);
}
......
......@@ -146,6 +146,11 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext& context,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
// TODO(crbug.com/1055983): Remove this when the execution context validity
// check is not required in the AudioNode factory methods.
if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
return nullptr;
if (feedback_coef.size() == 0 ||
(feedback_coef.size() > IIRFilter::kMaxOrder + 1)) {
exception_state.ThrowDOMException(
......
......@@ -207,6 +207,11 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
// TODO(crbug.com/1055983): Remove this when the execution context validity
// check is not required in the AudioNode factory methods.
if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
return nullptr;
return MakeGarbageCollected<MediaStreamAudioDestinationNode>(
context, number_of_channels);
}
......
......@@ -135,6 +135,11 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
// TODO(crbug.com/1055983): Remove this when the execution context validity
// check is not required in the AudioNode factory methods.
if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
return nullptr;
MediaStreamTrackVector audio_tracks = media_stream.getAudioTracks();
if (audio_tracks.IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment