Add input validation for AudioParam methods

This commit is contained in:
Manish Goregaokar 2019-04-25 15:22:26 -07:00
parent 54f54d194d
commit 8a8a9f7135
3 changed files with 73 additions and 47 deletions

View file

@ -7,6 +7,7 @@ use crate::dom::bindings::codegen::Bindings::AudioParamBinding;
use crate::dom::bindings::codegen::Bindings::AudioParamBinding::{ use crate::dom::bindings::codegen::Bindings::AudioParamBinding::{
AudioParamMethods, AutomationRate, AudioParamMethods, AutomationRate,
}; };
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
@ -142,12 +143,22 @@ impl AudioParamMethods for AudioParam {
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-setvalueattime // https://webaudio.github.io/web-audio-api/#dom-audioparam-setvalueattime
fn SetValueAtTime(&self, value: Finite<f32>, start_time: Finite<f64>) -> DomRoot<AudioParam> { fn SetValueAtTime(
&self,
value: Finite<f32>,
start_time: Finite<f64>,
) -> Fallible<DomRoot<AudioParam>> {
if *start_time < 0. {
return Err(Error::Range(format!(
"start time {} should not be negative",
*start_time
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::SetValueAtTime(*value, *start_time), UserAutomationEvent::SetValueAtTime(*value, *start_time),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-linearramptovalueattime // https://webaudio.github.io/web-audio-api/#dom-audioparam-linearramptovalueattime
@ -155,12 +166,18 @@ impl AudioParamMethods for AudioParam {
&self, &self,
value: Finite<f32>, value: Finite<f32>,
end_time: Finite<f64>, end_time: Finite<f64>,
) -> DomRoot<AudioParam> { ) -> Fallible<DomRoot<AudioParam>> {
if *end_time < 0. {
return Err(Error::Range(format!(
"end time {} should not be negative",
*end_time
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::RampToValueAtTime(RampKind::Linear, *value, *end_time), UserAutomationEvent::RampToValueAtTime(RampKind::Linear, *value, *end_time),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-exponentialramptovalueattime // https://webaudio.github.io/web-audio-api/#dom-audioparam-exponentialramptovalueattime
@ -168,12 +185,24 @@ impl AudioParamMethods for AudioParam {
&self, &self,
value: Finite<f32>, value: Finite<f32>,
end_time: Finite<f64>, end_time: Finite<f64>,
) -> DomRoot<AudioParam> { ) -> Fallible<DomRoot<AudioParam>> {
if *end_time < 0. {
return Err(Error::Range(format!(
"end time {} should not be negative",
*end_time
)));
}
if *value == 0. {
return Err(Error::Range(format!(
"target value {} should not be 0",
*value
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::RampToValueAtTime(RampKind::Exponential, *value, *end_time), UserAutomationEvent::RampToValueAtTime(RampKind::Exponential, *value, *end_time),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-settargetattime // https://webaudio.github.io/web-audio-api/#dom-audioparam-settargetattime
@ -182,30 +211,54 @@ impl AudioParamMethods for AudioParam {
target: Finite<f32>, target: Finite<f32>,
start_time: Finite<f64>, start_time: Finite<f64>,
time_constant: Finite<f32>, time_constant: Finite<f32>,
) -> DomRoot<AudioParam> { ) -> Fallible<DomRoot<AudioParam>> {
if *start_time < 0. {
return Err(Error::Range(format!(
"start time {} should not be negative",
*start_time
)));
}
if *time_constant < 0. {
return Err(Error::Range(format!(
"time constant {} should not be negative",
*time_constant
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::SetTargetAtTime(*target, *start_time, (*time_constant).into()), UserAutomationEvent::SetTargetAtTime(*target, *start_time, (*time_constant).into()),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-cancelscheduledvalues // https://webaudio.github.io/web-audio-api/#dom-audioparam-cancelscheduledvalues
fn CancelScheduledValues(&self, cancel_time: Finite<f64>) -> DomRoot<AudioParam> { fn CancelScheduledValues(&self, cancel_time: Finite<f64>) -> Fallible<DomRoot<AudioParam>> {
if *cancel_time < 0. {
return Err(Error::Range(format!(
"cancel time {} should not be negative",
*cancel_time
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::CancelScheduledValues(*cancel_time), UserAutomationEvent::CancelScheduledValues(*cancel_time),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
// https://webaudio.github.io/web-audio-api/#dom-audioparam-cancelandholdattime // https://webaudio.github.io/web-audio-api/#dom-audioparam-cancelandholdattime
fn CancelAndHoldAtTime(&self, cancel_time: Finite<f64>) -> DomRoot<AudioParam> { fn CancelAndHoldAtTime(&self, cancel_time: Finite<f64>) -> Fallible<DomRoot<AudioParam>> {
if *cancel_time < 0. {
return Err(Error::Range(format!(
"cancel time {} should not be negative",
*cancel_time
)));
}
self.message_node(AudioNodeMessage::SetParam( self.message_node(AudioNodeMessage::SetParam(
self.param, self.param,
UserAutomationEvent::CancelAndHoldAtTime(*cancel_time), UserAutomationEvent::CancelAndHoldAtTime(*cancel_time),
)); ));
DomRoot::from_ref(self) Ok(DomRoot::from_ref(self))
} }
} }

View file

@ -18,15 +18,15 @@ interface AudioParam {
readonly attribute float defaultValue; readonly attribute float defaultValue;
readonly attribute float minValue; readonly attribute float minValue;
readonly attribute float maxValue; readonly attribute float maxValue;
AudioParam setValueAtTime(float value, double startTime); [Throws] AudioParam setValueAtTime(float value, double startTime);
AudioParam linearRampToValueAtTime(float value, double endTime); [Throws] AudioParam linearRampToValueAtTime(float value, double endTime);
AudioParam exponentialRampToValueAtTime(float value, double endTime); [Throws] AudioParam exponentialRampToValueAtTime(float value, double endTime);
AudioParam setTargetAtTime(float target, [Throws] AudioParam setTargetAtTime(float target,
double startTime, double startTime,
float timeConstant); float timeConstant);
// AudioParam setValueCurveAtTime(sequence<float> values, // AudioParam setValueCurveAtTime(sequence<float> values,
// double startTime, // double startTime,
// double duration); // double duration);
AudioParam cancelScheduledValues(double cancelTime); [Throws] AudioParam cancelScheduledValues(double cancelTime);
AudioParam cancelAndHoldAtTime(double cancelTime); [Throws] AudioParam cancelAndHoldAtTime(double cancelTime);
}; };

View file

@ -1,46 +1,19 @@
[audioparam-exceptional-values.html] [audioparam-exceptional-values.html]
[X gain.gain.exponentialRampToValueAtTime(-1e-100,1) did not throw an exception.]
expected: FAIL
[X gain.gain.exponentialRampToValueAtTime(0,1) did not throw an exception.]
expected: FAIL
[X gain.gain.linearRampToValueAtTime(1,-1) did not throw an exception.]
expected: FAIL
[X gain.gain.setTargetAtTime(1,-1,1) did not throw an exception.]
expected: FAIL
[X gain.gain.setValueCurveAtTime([0,0,0\],1,-1) threw "TypeError" instead of EcmaScript error RangeError.] [X gain.gain.setValueCurveAtTime([0,0,0\],1,-1) threw "TypeError" instead of EcmaScript error RangeError.]
expected: FAIL expected: FAIL
[< [special cases 1\] 9 out of 9 assertions were failed.]
expected: FAIL
[X gain.gain.setValueCurveAtTime(curve, 1, -1) threw "TypeError" instead of EcmaScript error RangeError.] [X gain.gain.setValueCurveAtTime(curve, 1, -1) threw "TypeError" instead of EcmaScript error RangeError.]
expected: FAIL expected: FAIL
[X gain.gain.exponentialRampToValueAtTime(1,-1) did not throw an exception.]
expected: FAIL
[X gain.gain.setValueAtTime(1,-1) did not throw an exception.]
expected: FAIL
[X gain.gain.setValueCurveAtTime(curve, 1, 0) threw "TypeError" instead of EcmaScript error RangeError.] [X gain.gain.setValueCurveAtTime(curve, 1, 0) threw "TypeError" instead of EcmaScript error RangeError.]
expected: FAIL expected: FAIL
[# AUDIT TASK RUNNER FINISHED: 2 out of 6 tasks were failed.] [< [special cases 1\] 4 out of 9 assertions were failed.]
expected: FAIL expected: FAIL
[X gain.gain.setValueCurveAtTime([0,0,0\],-1,1) threw "TypeError" instead of EcmaScript error RangeError.] [X gain.gain.setValueCurveAtTime([0,0,0\],-1,1) threw "TypeError" instead of EcmaScript error RangeError.]
expected: FAIL expected: FAIL
[X gain.gain.setTargetAtTime(1,1,-1) did not throw an exception.] [# AUDIT TASK RUNNER FINISHED: 1 out of 6 tasks were failed.]
expected: FAIL
[X gain.gain.exponentialRampToValueAtTime(1e-100,1) did not throw an exception.]
expected: FAIL
[< [special cases 2\] 3 out of 3 assertions were failed.]
expected: FAIL expected: FAIL