mirror of
https://github.com/servo/servo.git
synced 2025-09-30 08:39:16 +01:00
script: Implement QuotaExceededError WebIDL interface (#38507)
Implements the new WebIDL interface for QuotaExceededError and uses it in appropriate places. Testing: WPT tests. Now passing many more in `tests/wpt/tests/WebCryptoAPI/getRandomValues.any.js` and `tests/wpt/tests/webstorage/storage_session_setitem_quotaexceedederr.window.js`. Fixes: #38489 --------- Signed-off-by: Rahul Menon <menonrahul02@gmail.com>
This commit is contained in:
parent
fad247c802
commit
b5932e5abf
14 changed files with 173 additions and 67 deletions
|
@ -18,6 +18,7 @@ use js::rust::{HandleObject, HandleValue, MutableHandleValue};
|
|||
use libc::c_uint;
|
||||
use script_bindings::conversions::SafeToJSValConvertible;
|
||||
pub(crate) use script_bindings::error::*;
|
||||
use script_bindings::str::DOMString;
|
||||
|
||||
#[cfg(feature = "js_backtrace")]
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
|
@ -27,6 +28,7 @@ use crate::dom::bindings::conversions::{
|
|||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::domexception::{DOMErrorName, DOMException};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::types::QuotaExceededError;
|
||||
use crate::realms::InRealm;
|
||||
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||
|
||||
|
@ -92,7 +94,15 @@ pub(crate) fn throw_dom_exception(
|
|||
Error::ReadOnly => DOMErrorName::ReadOnlyError,
|
||||
Error::Version => DOMErrorName::VersionError,
|
||||
Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError,
|
||||
Error::QuotaExceeded => DOMErrorName::QuotaExceededError,
|
||||
Error::QuotaExceeded { quota, requested } => unsafe {
|
||||
assert!(!JS_IsExceptionPending(*cx));
|
||||
let exception =
|
||||
QuotaExceededError::new(global, DOMString::new(), quota, requested, can_gc);
|
||||
rooted!(in(*cx) let mut thrown = UndefinedValue());
|
||||
exception.safe_to_jsval(cx, thrown.handle_mut());
|
||||
JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture);
|
||||
return;
|
||||
},
|
||||
Error::TypeMismatch => DOMErrorName::TypeMismatchError,
|
||||
Error::InvalidModification => DOMErrorName::InvalidModificationError,
|
||||
Error::NotReadable => DOMErrorName::NotReadableError,
|
||||
|
|
|
@ -63,7 +63,10 @@ impl CryptoMethods<crate::DomTypeHolder> for Crypto {
|
|||
} else {
|
||||
let data = unsafe { input.as_mut_slice() };
|
||||
if data.len() > 65536 {
|
||||
return Err(Error::QuotaExceeded);
|
||||
return Err(Error::QuotaExceeded {
|
||||
quota: None,
|
||||
requested: None,
|
||||
});
|
||||
}
|
||||
self.rng.borrow_mut().fill_bytes(data);
|
||||
let underlying_object = unsafe { input.underlying_object() };
|
||||
|
|
|
@ -263,7 +263,10 @@ impl IDBTransactionMethods<crate::DomTypeHolder> for IDBTransaction {
|
|||
// Step 2
|
||||
if let Err(_result) = result {
|
||||
// FIXME:(rasviitanen) also support Unknown error
|
||||
return Err(Error::QuotaExceeded);
|
||||
return Err(Error::QuotaExceeded {
|
||||
quota: None,
|
||||
requested: None,
|
||||
});
|
||||
}
|
||||
|
||||
// Step 3
|
||||
|
|
|
@ -513,6 +513,7 @@ pub(crate) mod progressevent;
|
|||
pub(crate) mod promise;
|
||||
pub(crate) mod promisenativehandler;
|
||||
pub(crate) mod promiserejectionevent;
|
||||
pub(crate) mod quotaexceedederror;
|
||||
pub(crate) mod radionodelist;
|
||||
pub(crate) mod range;
|
||||
pub(crate) mod raredata;
|
||||
|
|
118
components/script/dom/quotaexceedederror.rs
Normal file
118
components/script/dom/quotaexceedederror.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use js::gc::HandleObject;
|
||||
use script_bindings::codegen::GenericBindings::QuotaExceededErrorBinding::{
|
||||
QuotaExceededErrorMethods, QuotaExceededErrorOptions,
|
||||
};
|
||||
use script_bindings::num::Finite;
|
||||
use script_bindings::root::DomRoot;
|
||||
use script_bindings::script_runtime::CanGc;
|
||||
use script_bindings::str::DOMString;
|
||||
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
|
||||
use crate::dom::types::{DOMException, GlobalScope};
|
||||
|
||||
/// <https://webidl.spec.whatwg.org/#quotaexceedederror>
|
||||
#[dom_struct]
|
||||
pub(crate) struct QuotaExceededError {
|
||||
/// <https://webidl.spec.whatwg.org/#idl-DOMException>
|
||||
dom_exception: DOMException,
|
||||
/// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
|
||||
quota: Option<Finite<f64>>,
|
||||
/// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
|
||||
requested: Option<Finite<f64>>,
|
||||
}
|
||||
|
||||
impl QuotaExceededError {
|
||||
fn new_inherited(
|
||||
message: DOMString,
|
||||
quota: Option<Finite<f64>>,
|
||||
requested: Option<Finite<f64>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
dom_exception: DOMException::new_inherited(
|
||||
message,
|
||||
DOMString::from_string("QuotaExceededError".to_string()),
|
||||
),
|
||||
quota,
|
||||
requested,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new(
|
||||
global: &GlobalScope,
|
||||
message: DOMString,
|
||||
quota: Option<Finite<f64>>,
|
||||
requested: Option<Finite<f64>>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Self> {
|
||||
reflect_dom_object(
|
||||
Box::new(Self::new_inherited(message, quota, requested)),
|
||||
global,
|
||||
can_gc,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl QuotaExceededErrorMethods<crate::DomTypeHolder> for QuotaExceededError {
|
||||
/// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quotaexceedederror>
|
||||
fn Constructor(
|
||||
global: &GlobalScope,
|
||||
proto: Option<HandleObject>,
|
||||
can_gc: CanGc,
|
||||
message: DOMString,
|
||||
options: &QuotaExceededErrorOptions,
|
||||
) -> Result<DomRoot<Self>, Error> {
|
||||
// If options["quota"] is present:
|
||||
if let Some(quota) = options.quota {
|
||||
// If options["quota"] is less than 0, then throw a RangeError.
|
||||
if *quota < 0.0 {
|
||||
return Err(Error::Range(
|
||||
"quota must be at least zero if present".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
// If options["requested"] is present:
|
||||
if let Some(requested) = options.requested {
|
||||
// If options["requested"] is less than 0, then throw a RangeError.
|
||||
if *requested < 0.0 {
|
||||
return Err(Error::Range(
|
||||
"requested must be at least zero if present".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
// If this’s quota is not null, this’s requested is not null, and this’s requested
|
||||
// is less than this’s quota, then throw a RangeError.
|
||||
if let (Some(quota), Some(requested)) = (options.quota, options.requested) {
|
||||
if *requested < *quota {
|
||||
return Err(Error::Range("requested is less than quota".to_string()));
|
||||
}
|
||||
}
|
||||
Ok(reflect_dom_object_with_proto(
|
||||
Box::new(QuotaExceededError::new_inherited(
|
||||
message,
|
||||
options.quota,
|
||||
options.requested,
|
||||
)),
|
||||
global,
|
||||
proto,
|
||||
can_gc,
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-quota>
|
||||
fn GetQuota(&self) -> Option<Finite<f64>> {
|
||||
// The quota getter steps are to return this’s quota.
|
||||
self.quota
|
||||
}
|
||||
|
||||
/// <https://webidl.spec.whatwg.org/#dom-quotaexceedederror-requested>
|
||||
fn GetRequested(&self) -> Option<Finite<f64>> {
|
||||
// The requested getter steps are to return this’s requested.
|
||||
self.requested
|
||||
}
|
||||
}
|
|
@ -127,7 +127,10 @@ impl StorageMethods<crate::DomTypeHolder> for Storage {
|
|||
);
|
||||
self.get_storage_thread().send(msg).unwrap();
|
||||
match receiver.recv().unwrap() {
|
||||
Err(_) => Err(Error::QuotaExceeded),
|
||||
Err(_) => Err(Error::QuotaExceeded {
|
||||
quota: None,
|
||||
requested: None,
|
||||
}),
|
||||
Ok((changed, old_value)) => {
|
||||
if changed {
|
||||
self.broadcast_change_notification(Some(name), old_value, Some(value));
|
||||
|
|
|
@ -6,6 +6,7 @@ use js::error::throw_type_error;
|
|||
use js::jsapi::JS_IsExceptionPending;
|
||||
|
||||
use crate::codegen::PrototypeList::proto_id_to_name;
|
||||
use crate::num::Finite;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
|
||||
/// DOM exceptions that can be thrown by a native DOM method.
|
||||
|
@ -55,7 +56,10 @@ pub enum Error {
|
|||
/// NoModificationAllowedError DOMException
|
||||
NoModificationAllowed,
|
||||
/// QuotaExceededError DOMException
|
||||
QuotaExceeded,
|
||||
QuotaExceeded {
|
||||
quota: Option<Finite<f64>>,
|
||||
requested: Option<Finite<f64>>,
|
||||
},
|
||||
/// TypeMismatchError DOMException
|
||||
TypeMismatch,
|
||||
/// InvalidModificationError DOMException
|
||||
|
|
|
@ -11,7 +11,7 @@ use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
|||
use num_traits::Float;
|
||||
|
||||
/// Encapsulates the IDL restricted float type.
|
||||
#[derive(Clone, Copy, Eq, JSTraceable, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, JSTraceable, PartialEq)]
|
||||
pub struct Finite<T: Float>(T);
|
||||
|
||||
impl<T: Float> Finite<T> {
|
||||
|
|
21
components/script_bindings/webidls/QuotaExceededError.webidl
Normal file
21
components/script_bindings/webidls/QuotaExceededError.webidl
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// https://heycam.github.io/webidl/#quotaexceedederror
|
||||
|
||||
[
|
||||
Exposed=(Window,Worker,Worklet,DissimilarOriginWindow),
|
||||
// Serializable
|
||||
]
|
||||
interface QuotaExceededError : DOMException {
|
||||
[Throws] constructor(optional DOMString message = "", optional QuotaExceededErrorOptions options = {});
|
||||
|
||||
readonly attribute double? quota;
|
||||
readonly attribute double? requested;
|
||||
};
|
||||
|
||||
dictionary QuotaExceededErrorOptions {
|
||||
double quota;
|
||||
double requested;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue