mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibWeb: Validate AudioParam context in AudioNode::connect()
An exception is now thown if an `AudioNode` attempts to connect to an `AudioParam` from a different `BaseAudioContext`.
This commit is contained in:
parent
2edd0812ca
commit
5c57acf140
Notes:
github-actions[bot]
2025-01-09 11:35:50 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/5c57acf140b Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3191 Reviewed-by: https://github.com/shannonbooth ✅
14 changed files with 54 additions and 43 deletions
|
@ -18,8 +18,8 @@ GC_DEFINE_ALLOCATOR(AudioBufferSourceNode);
|
|||
AudioBufferSourceNode::AudioBufferSourceNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, AudioBufferSourceOptions const& options)
|
||||
: AudioScheduledSourceNode(realm, context)
|
||||
, m_buffer(options.buffer)
|
||||
, m_playback_rate(AudioParam::create(realm, options.playback_rate, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, options.detune, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_playback_rate(AudioParam::create(realm, context, options.playback_rate, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, context, options.detune, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_loop(options.loop)
|
||||
, m_loop_start(options.loop_start)
|
||||
, m_loop_end(options.loop_end)
|
||||
|
|
|
@ -12,23 +12,23 @@ namespace Web::WebAudio {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(AudioListener);
|
||||
|
||||
AudioListener::AudioListener(JS::Realm& realm)
|
||||
AudioListener::AudioListener(JS::Realm& realm, GC::Ref<BaseAudioContext> context)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_forward_x(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_forward_y(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_forward_z(AudioParam::create(realm, -1.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_x(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_y(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_z(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_x(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_y(AudioParam::create(realm, 1.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_z(AudioParam::create(realm, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_forward_x(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_forward_y(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_forward_z(AudioParam::create(realm, context, -1.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_x(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_y(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_z(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_x(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_y(AudioParam::create(realm, context, 1.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_up_z(AudioParam::create(realm, context, 0.f, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
GC::Ref<AudioListener> AudioListener::create(JS::Realm& realm)
|
||||
GC::Ref<AudioListener> AudioListener::create(JS::Realm& realm, GC::Ref<BaseAudioContext> context)
|
||||
{
|
||||
return realm.create<AudioListener>(realm);
|
||||
return realm.create<AudioListener>(realm, context);
|
||||
}
|
||||
|
||||
AudioListener::~AudioListener() = default;
|
||||
|
|
|
@ -20,7 +20,7 @@ class AudioListener final : public Bindings::PlatformObject {
|
|||
GC_DECLARE_ALLOCATOR(AudioListener);
|
||||
|
||||
public:
|
||||
static GC::Ref<AudioListener> create(JS::Realm&);
|
||||
static GC::Ref<AudioListener> create(JS::Realm&, GC::Ref<BaseAudioContext>);
|
||||
virtual ~AudioListener() override;
|
||||
|
||||
GC::Ref<AudioParam> forward_x() const { return m_forward_x; }
|
||||
|
@ -37,7 +37,7 @@ public:
|
|||
WebIDL::ExceptionOr<void> set_orientation(float x, float y, float z, float x_up, float y_up, float z_up);
|
||||
|
||||
private:
|
||||
explicit AudioListener(JS::Realm&);
|
||||
explicit AudioListener(JS::Realm&, GC::Ref<BaseAudioContext>);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
|
|
@ -78,7 +78,11 @@ WebIDL::ExceptionOr<GC::Ref<AudioNode>> AudioNode::connect(GC::Ref<AudioNode> de
|
|||
// https://webaudio.github.io/web-audio-api/#dom-audionode-connect-destinationparam-output
|
||||
WebIDL::ExceptionOr<void> AudioNode::connect(GC::Ref<AudioParam> destination_param, WebIDL::UnsignedLong output)
|
||||
{
|
||||
(void)destination_param;
|
||||
// If destinationParam belongs to an AudioNode that belongs to a BaseAudioContext that is different from the BaseAudioContext
|
||||
// that has created the AudioNode on which this method was called, an InvalidAccessError MUST be thrown.
|
||||
if (m_context != destination_param->context()) {
|
||||
return WebIDL::InvalidAccessError::create(realm(), "Cannot connect to an AudioParam in a different AudioContext"_string);
|
||||
}
|
||||
|
||||
// The output parameter is an index describing which output of the AudioNode from which to connect.
|
||||
// If the parameter is out-of-bounds, an IndexSizeError exception MUST be thrown.
|
||||
|
|
|
@ -7,14 +7,16 @@
|
|||
#include <LibWeb/Bindings/AudioParamPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/WebAudio/AudioParam.h>
|
||||
#include <LibWeb/WebAudio/BaseAudioContext.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::WebAudio {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(AudioParam);
|
||||
|
||||
AudioParam::AudioParam(JS::Realm& realm, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
AudioParam::AudioParam(JS::Realm& realm, GC::Ref<BaseAudioContext> context, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_context(context)
|
||||
, m_current_value(default_value)
|
||||
, m_default_value(default_value)
|
||||
, m_min_value(min_value)
|
||||
|
@ -23,9 +25,9 @@ AudioParam::AudioParam(JS::Realm& realm, float default_value, float min_value, f
|
|||
{
|
||||
}
|
||||
|
||||
GC::Ref<AudioParam> AudioParam::create(JS::Realm& realm, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
GC::Ref<AudioParam> AudioParam::create(JS::Realm& realm, GC::Ref<BaseAudioContext> context, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
{
|
||||
return realm.create<AudioParam>(realm, default_value, min_value, max_value, automation_rate);
|
||||
return realm.create<AudioParam>(realm, context, default_value, min_value, max_value, automation_rate);
|
||||
}
|
||||
|
||||
AudioParam::~AudioParam() = default;
|
||||
|
@ -143,6 +145,7 @@ void AudioParam::initialize(JS::Realm& realm)
|
|||
void AudioParam::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@ class AudioParam final : public Bindings::PlatformObject {
|
|||
GC_DECLARE_ALLOCATOR(AudioParam);
|
||||
|
||||
public:
|
||||
static GC::Ref<AudioParam> create(JS::Realm&, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
static GC::Ref<AudioParam> create(JS::Realm&, GC::Ref<BaseAudioContext>, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
|
||||
virtual ~AudioParam() override;
|
||||
|
||||
GC::Ref<BaseAudioContext> context() const { return m_context; }
|
||||
|
||||
float value() const;
|
||||
void set_value(float);
|
||||
|
||||
|
@ -41,7 +43,9 @@ public:
|
|||
WebIDL::ExceptionOr<GC::Ref<AudioParam>> cancel_and_hold_at_time(double cancel_time);
|
||||
|
||||
private:
|
||||
AudioParam(JS::Realm&, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
AudioParam(JS::Realm&, GC::Ref<BaseAudioContext>, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
|
||||
GC::Ref<BaseAudioContext> m_context;
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audioparam-current-value-slot
|
||||
float m_current_value {}; // [[current value]]
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Web::WebAudio {
|
|||
BaseAudioContext::BaseAudioContext(JS::Realm& realm, float sample_rate)
|
||||
: DOM::EventTarget(realm)
|
||||
, m_sample_rate(sample_rate)
|
||||
, m_listener(AudioListener::create(realm))
|
||||
, m_listener(AudioListener::create(realm, *this))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ GC_DEFINE_ALLOCATOR(BiquadFilterNode);
|
|||
BiquadFilterNode::BiquadFilterNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, BiquadFilterOptions const& options)
|
||||
: AudioNode(realm, context)
|
||||
, m_type(options.type)
|
||||
, m_frequency(AudioParam::create(realm, options.frequency, 0, context->nyquist_frequency(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, options.detune, -1200 * AK::log2(NumericLimits<float>::max()), 1200 * AK::log2(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
, m_q(AudioParam::create(realm, options.q, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_gain(AudioParam::create(realm, options.gain, NumericLimits<float>::lowest(), 40 * AK::log10(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
, m_frequency(AudioParam::create(realm, context, options.frequency, 0, context->nyquist_frequency(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, context, options.detune, -1200 * AK::log2(NumericLimits<float>::max()), 1200 * AK::log2(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
, m_q(AudioParam::create(realm, context, options.q, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_gain(AudioParam::create(realm, context, options.gain, NumericLimits<float>::lowest(), 40 * AK::log10(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ GC_DEFINE_ALLOCATOR(ConstantSourceNode);
|
|||
|
||||
ConstantSourceNode::ConstantSourceNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, ConstantSourceOptions const& options)
|
||||
: AudioScheduledSourceNode(realm, context)
|
||||
, m_offset(AudioParam::create(realm, options.offset, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_offset(AudioParam::create(realm, context, options.offset, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ GC_DEFINE_ALLOCATOR(DelayNode);
|
|||
|
||||
DelayNode::DelayNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, DelayOptions const& options)
|
||||
: AudioNode(realm, context)
|
||||
, m_delay_time(AudioParam::create(realm, options.delay_time, 0, options.max_delay_time, Bindings::AutomationRate::ARate))
|
||||
, m_delay_time(AudioParam::create(realm, context, options.delay_time, 0, options.max_delay_time, Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -41,11 +41,11 @@ WebIDL::ExceptionOr<GC::Ref<DynamicsCompressorNode>> DynamicsCompressorNode::con
|
|||
|
||||
DynamicsCompressorNode::DynamicsCompressorNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, DynamicsCompressorOptions const& options)
|
||||
: AudioNode(realm, context)
|
||||
, m_threshold(AudioParam::create(realm, options.threshold, -100, 0, Bindings::AutomationRate::KRate))
|
||||
, m_knee(AudioParam::create(realm, options.knee, 0, 40, Bindings::AutomationRate::KRate))
|
||||
, m_ratio(AudioParam::create(realm, options.ratio, 1, 20, Bindings::AutomationRate::KRate))
|
||||
, m_attack(AudioParam::create(realm, options.attack, 0, 1, Bindings::AutomationRate::KRate))
|
||||
, m_release(AudioParam::create(realm, options.release, 0, 1, Bindings::AutomationRate::KRate))
|
||||
, m_threshold(AudioParam::create(realm, context, options.threshold, -100, 0, Bindings::AutomationRate::KRate))
|
||||
, m_knee(AudioParam::create(realm, context, options.knee, 0, 40, Bindings::AutomationRate::KRate))
|
||||
, m_ratio(AudioParam::create(realm, context, options.ratio, 1, 20, Bindings::AutomationRate::KRate))
|
||||
, m_attack(AudioParam::create(realm, context, options.attack, 0, 1, Bindings::AutomationRate::KRate))
|
||||
, m_release(AudioParam::create(realm, context, options.release, 0, 1, Bindings::AutomationRate::KRate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ WebIDL::ExceptionOr<GC::Ref<GainNode>> GainNode::construct_impl(JS::Realm& realm
|
|||
|
||||
GainNode::GainNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, GainOptions const& options)
|
||||
: AudioNode(realm, context)
|
||||
, m_gain(AudioParam::create(realm, options.gain, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_gain(AudioParam::create(realm, context, options.gain, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@ WebIDL::ExceptionOr<GC::Ref<OscillatorNode>> OscillatorNode::construct_impl(JS::
|
|||
OscillatorNode::OscillatorNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, OscillatorOptions const& options)
|
||||
: AudioScheduledSourceNode(realm, context)
|
||||
, m_type(options.type)
|
||||
, m_frequency(AudioParam::create(realm, options.frequency, -context->nyquist_frequency(), context->nyquist_frequency(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, options.detune, -1200 * AK::log2(NumericLimits<float>::max()), 1200 * AK::log2(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
, m_frequency(AudioParam::create(realm, context, options.frequency, -context->nyquist_frequency(), context->nyquist_frequency(), Bindings::AutomationRate::ARate))
|
||||
, m_detune(AudioParam::create(realm, context, options.detune, -1200 * AK::log2(NumericLimits<float>::max()), 1200 * AK::log2(NumericLimits<float>::max()), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -62,12 +62,12 @@ WebIDL::ExceptionOr<GC::Ref<PannerNode>> PannerNode::construct_impl(JS::Realm& r
|
|||
PannerNode::PannerNode(JS::Realm& realm, GC::Ref<BaseAudioContext> context, PannerOptions const& options)
|
||||
: AudioNode(realm, context)
|
||||
, m_panning_model(options.panning_model)
|
||||
, m_position_x(AudioParam::create(realm, options.position_x, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_y(AudioParam::create(realm, options.position_y, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_z(AudioParam::create(realm, options.position_z, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_x(AudioParam::create(realm, options.orientation_x, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_y(AudioParam::create(realm, options.orientation_y, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_z(AudioParam::create(realm, options.orientation_z, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_x(AudioParam::create(realm, context, options.position_x, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_y(AudioParam::create(realm, context, options.position_y, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_position_z(AudioParam::create(realm, context, options.position_z, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_x(AudioParam::create(realm, context, options.orientation_x, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_y(AudioParam::create(realm, context, options.orientation_y, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_orientation_z(AudioParam::create(realm, context, options.orientation_z, NumericLimits<float>::lowest(), NumericLimits<float>::max(), Bindings::AutomationRate::ARate))
|
||||
, m_distance_model(options.distance_model)
|
||||
, m_ref_distance(options.ref_distance)
|
||||
, m_max_distance(options.max_distance)
|
||||
|
|
Loading…
Add table
Reference in a new issue