aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorshanehandley <shanehandley@fastmail.com>2025-02-02 18:49:48 +1100
committerGitHub <noreply@github.com>2025-02-02 07:49:48 +0000
commit938baf6bf36336d812277b0bc056d1a614c472cc (patch)
treeb0647f6c401c1d6e627c05b61f125c37cecacff6 /components/script
parentf364b3f6eaa0eec3200e267f9c7d7e1622de82b3 (diff)
downloadservo-938baf6bf36336d812277b0bc056d1a614c472cc.tar.gz
servo-938baf6bf36336d812277b0bc056d1a614c472cc.zip
script: Implement the Bytes() method on Request and Response (#35250)
* Implement the Bytes() method on Request and Response Signed-off-by: Shane Handley <shanehandley@fastmail.com> * avoid unsafe code during buffer creation Signed-off-by: Shane Handley <shanehandley@fastmail.com> --------- Signed-off-by: Shane Handley <shanehandley@fastmail.com>
Diffstat (limited to 'components/script')
-rw-r--r--components/script/body.rs32
-rw-r--r--components/script/dom/request.rs5
-rw-r--r--components/script/dom/response.rs5
3 files changed, 30 insertions, 12 deletions
diff --git a/components/script/body.rs b/components/script/body.rs
index 8546b3f9cd7..e65b6342d6e 100644
--- a/components/script/body.rs
+++ b/components/script/body.rs
@@ -12,7 +12,7 @@ use js::jsapi::{Heap, JSObject, JS_ClearPendingException, Value as JSValue};
use js::jsval::{JSVal, UndefinedValue};
use js::rust::wrappers::{JS_GetPendingException, JS_ParseJSON};
use js::rust::HandleValue;
-use js::typedarray::{ArrayBuffer, CreateWith};
+use js::typedarray::{ArrayBufferU8, Uint8};
use mime::{self, Mime};
use net_traits::request::{
BodyChunkRequest, BodyChunkResponse, BodySource as NetBodySource, RequestBody,
@@ -20,6 +20,7 @@ use net_traits::request::{
use script_traits::serializable::BlobImpl;
use url::form_urlencoded;
+use crate::dom::bindings::buffer_source::create_buffer_source;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::BlobBinding::Blob_Binding::BlobMethods;
use crate::dom::bindings::codegen::Bindings::FormDataBinding::FormDataMethods;
@@ -572,6 +573,7 @@ impl Extractable for URLSearchParams {
#[derive(Clone, Copy, JSTraceable, MallocSizeOf)]
pub(crate) enum BodyType {
Blob,
+ Bytes,
FormData,
Json,
Text,
@@ -582,6 +584,7 @@ pub(crate) enum FetchedData {
Text(String),
Json(RootedTraceableBox<Heap<JSValue>>),
BlobData(DomRoot<Blob>),
+ Bytes(RootedTraceableBox<Heap<*mut JSObject>>),
FormData(DomRoot<FormData>),
ArrayBuffer(RootedTraceableBox<Heap<*mut JSObject>>),
JSException(RootedTraceableBox<Heap<JSVal>>),
@@ -633,6 +636,7 @@ impl ConsumeBodyPromiseHandler {
FetchedData::Json(j) => self.result_promise.resolve_native(&j),
FetchedData::BlobData(b) => self.result_promise.resolve_native(&b),
FetchedData::FormData(f) => self.result_promise.resolve_native(&f),
+ FetchedData::Bytes(b) => self.result_promise.resolve_native(&b),
FetchedData::ArrayBuffer(a) => self.result_promise.resolve_native(&a),
FetchedData::JSException(e) => self.result_promise.reject_native(&e.handle()),
};
@@ -810,6 +814,7 @@ fn run_package_data_algorithm(
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime, can_gc),
BodyType::FormData => run_form_data_algorithm(&global, bytes, mime, can_gc),
BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes),
+ BodyType::Bytes => run_bytes_data_algorithm(cx, bytes),
}
}
@@ -891,22 +896,25 @@ fn run_form_data_algorithm(
Err(Error::Type("Inappropriate MIME-type for Body".to_string()))
}
-#[allow(unsafe_code)]
+fn run_bytes_data_algorithm(cx: JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> {
+ rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
+
+ create_buffer_source::<Uint8>(cx, &bytes, array_buffer_ptr.handle_mut())
+ .map_err(|_| Error::JSFailed)?;
+
+ let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
+ Ok(FetchedData::Bytes(rooted_heap))
+}
+
pub(crate) fn run_array_buffer_data_algorithm(
cx: JSContext,
bytes: Vec<u8>,
) -> Fallible<FetchedData> {
rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
- let arraybuffer = unsafe {
- ArrayBuffer::create(
- *cx,
- CreateWith::Slice(&bytes),
- array_buffer_ptr.handle_mut(),
- )
- };
- if arraybuffer.is_err() {
- return Err(Error::JSFailed);
- }
+
+ create_buffer_source::<ArrayBufferU8>(cx, &bytes, array_buffer_ptr.handle_mut())
+ .map_err(|_| Error::JSFailed)?;
+
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
Ok(FetchedData::ArrayBuffer(rooted_heap))
}
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index 70fa7b212e5..61f156045cb 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -643,6 +643,11 @@ impl RequestMethods<crate::DomTypeHolder> for Request {
fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
consume_body(self, BodyType::ArrayBuffer, can_gc)
}
+
+ /// <https://fetch.spec.whatwg.org/#dom-body-bytes>
+ fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
+ consume_body(self, BodyType::Bytes, can_gc)
+ }
}
impl BodyMixin for Request {
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index 5094d042996..cad5ff847cb 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -386,6 +386,11 @@ impl ResponseMethods<crate::DomTypeHolder> for Response {
fn ArrayBuffer(&self, can_gc: CanGc) -> Rc<Promise> {
consume_body(self, BodyType::ArrayBuffer, can_gc)
}
+
+ /// <https://fetch.spec.whatwg.org/#dom-body-bytes>
+ fn Bytes(&self, can_gc: CanGc) -> std::rc::Rc<Promise> {
+ consume_body(self, BodyType::Bytes, can_gc)
+ }
}
fn serialize_without_fragment(url: &ServoUrl) -> &str {