aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKousuke Takaki <98276492+yoseio@users.noreply.github.com>2025-05-19 20:55:06 +0900
committerGitHub <noreply@github.com>2025-05-19 11:55:06 +0000
commitec448b14230668f9e38f0d727661b6d94e184168 (patch)
tree4ad5ec5d298847589ba7f698a7ca041965c31af1
parent6e97fc0bc47b6c3c5af9b1750f01f268b6b200f5 (diff)
downloadservo-ec448b14230668f9e38f0d727661b6d94e184168.tar.gz
servo-ec448b14230668f9e38f0d727661b6d94e184168.zip
script: Make `Blob.ArrayBuffer()` more specification-compliant (#35748)
I have modified the Blob.ArrayBuffer implementation to comply with the specification part of #25209. See also: #35151. Testing: This does not seem to affect tested behavior, so no new tests. Signed-off-by: yoseio <98276492+yoseio@users.noreply.github.com>
-rw-r--r--components/script/dom/blob.rs71
-rw-r--r--components/script_bindings/codegen/Bindings.conf2
2 files changed, 44 insertions, 29 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index c5c5c480707..18e968aaa70 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -12,11 +12,10 @@ use dom_struct::dom_struct;
use encoding_rs::UTF_8;
use js::jsapi::JSObject;
use js::rust::HandleObject;
-use js::typedarray::Uint8;
+use js::typedarray::{ArrayBufferU8, Uint8};
use net_traits::filemanager_thread::RelativePos;
use uuid::Uuid;
-use crate::body::{FetchedData, run_array_buffer_data_algorithm};
use crate::dom::bindings::buffer_source::create_buffer_source;
use crate::dom::bindings::codegen::Bindings::BlobBinding;
use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
@@ -226,7 +225,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
Blob::new(&global, blob_impl, can_gc)
}
- // https://w3c.github.io/FileAPI/#text-method-algo
+ /// <https://w3c.github.io/FileAPI/#text-method-algo>
fn Text(&self, can_gc: CanGc) -> Rc<Promise> {
let global = self.global();
let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
@@ -250,35 +249,51 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
}
// https://w3c.github.io/FileAPI/#arraybuffer-method-algo
- fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
- let global = self.global();
- let in_realm_proof = AlreadyInRealm::assert::<crate::DomTypeHolder>();
- let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof), can_gc);
+ fn ArrayBuffer(&self, in_realm: InRealm, can_gc: CanGc) -> Rc<Promise> {
+ let cx = GlobalScope::get_cx();
+ let global = GlobalScope::from_safe_context(cx, in_realm);
+ let promise = Promise::new_in_current_realm(in_realm, can_gc);
- let id = self.get_blob_url_id();
+ // 1. Let stream be the result of calling get stream on this.
+ let stream = self.get_stream(can_gc);
- global.read_file_async(
- id,
- p.clone(),
- Box::new(|promise, bytes| {
- match bytes {
- Ok(b) => {
- let cx = GlobalScope::get_cx();
- let result = run_array_buffer_data_algorithm(cx, b, CanGc::note());
-
- match result {
- Ok(FetchedData::ArrayBuffer(a)) => {
- promise.resolve_native(&a, CanGc::note())
- },
- Err(e) => promise.reject_error(e, CanGc::note()),
- _ => panic!("Unexpected result from run_array_buffer_data_algorithm"),
- }
- },
- Err(e) => promise.reject_error(e, CanGc::note()),
- };
+ // 2. Let reader be the result of getting a reader from stream.
+ // If that threw an exception, return a new promise rejected with that exception.
+ let reader = match stream.and_then(|s| s.acquire_default_reader(can_gc)) {
+ Ok(reader) => reader,
+ Err(error) => {
+ promise.reject_error(error, can_gc);
+ return promise;
+ },
+ };
+
+ // 3. Let promise be the result of reading all bytes from stream with reader.
+ let success_promise = promise.clone();
+ let failure_promise = promise.clone();
+ reader.read_all_bytes(
+ cx,
+ &global,
+ Rc::new(move |bytes| {
+ rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>());
+ // 4. Return the result of transforming promise by a fulfillment handler that returns a new
+ // [ArrayBuffer]
+ let array_buffer = create_buffer_source::<ArrayBufferU8>(
+ cx,
+ bytes,
+ js_object.handle_mut(),
+ can_gc,
+ )
+ .expect("Converting input to ArrayBufferU8 should never fail");
+ success_promise.resolve_native(&array_buffer, can_gc);
}),
+ Rc::new(move |cx, value| {
+ failure_promise.reject(cx, value, can_gc);
+ }),
+ in_realm,
+ can_gc,
);
- p
+
+ promise
}
/// <https://w3c.github.io/FileAPI/#dom-blob-bytes>
diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf
index 92871bc54aa..d89b65c646d 100644
--- a/components/script_bindings/codegen/Bindings.conf
+++ b/components/script_bindings/codegen/Bindings.conf
@@ -39,7 +39,7 @@ DOMInterfaces = {
'Blob': {
'weakReferenceable': True,
'canGc': ['Slice', 'Text', 'ArrayBuffer', 'Stream', 'Bytes'],
- 'inRealms': ['Bytes'],
+ 'inRealms': ['Bytes', 'ArrayBuffer'],
},
'Bluetooth': {