script: Impl cloning of JSPrincipals (#32706)

* Impl cloning of JSPrincipals

* bincode as workspace dependency

* Update mozjs and cc
This commit is contained in:
Samson 2024-07-06 12:25:38 +02:00 committed by GitHub
parent 5a9dc98f07
commit 59d0f1fe1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 77 additions and 15 deletions

11
Cargo.lock generated
View file

@ -681,9 +681,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.99"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490"
dependencies = [
"jobserver",
"libc",
@ -4000,7 +4000,7 @@ dependencies = [
[[package]]
name = "mozjs"
version = "0.14.1"
source = "git+https://github.com/servo/mozjs#369f2902e6481b8f237cca1652f56e61f508a0ad"
source = "git+https://github.com/servo/mozjs#fb8225ed5eb87c0d6d0b4d6126c11f5bc98687ce"
dependencies = [
"bindgen",
"cc",
@ -4013,8 +4013,8 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.115.13-0"
source = "git+https://github.com/servo/mozjs#369f2902e6481b8f237cca1652f56e61f508a0ad"
version = "0.115.13-2"
source = "git+https://github.com/servo/mozjs#fb8225ed5eb87c0d6d0b4d6126c11f5bc98687ce"
dependencies = [
"bindgen",
"cc",
@ -5204,6 +5204,7 @@ dependencies = [
"backtrace",
"base",
"base64",
"bincode",
"bitflags 2.6.0",
"bluetooth_traits",
"canvas_traits",

View file

@ -25,6 +25,7 @@ background_hang_monitor_api = { path = "components/shared/background_hang_monito
backtrace = "0.3"
base = { path = "components/shared/base" }
base64 = "0.21.7"
bincode = "1"
bitflags = "2.6"
bluetooth_traits = { path = "components/shared/bluetooth" }
byteorder = "1.5"

View file

@ -34,6 +34,7 @@ background_hang_monitor_api = { workspace = true }
backtrace = { workspace = true }
base = { workspace = true }
base64 = { workspace = true }
bincode = { workspace = true }
bitflags = { workspace = true }
bluetooth_traits = { workspace = true }
canvas_traits = { workspace = true }

View file

@ -11,10 +11,15 @@ use js::glue::{
CreateRustJSPrincipals, DestroyRustJSPrincipals, GetRustJSPrincipalsPrivate,
JSPrincipalsCallbacks,
};
use js::jsapi::{JSPrincipals, JS_DropPrincipals, JS_HoldPrincipals};
use js::jsapi::{
JSContext, JSPrincipals, JSStructuredCloneReader, JSStructuredCloneWriter, JS_DropPrincipals,
JS_HoldPrincipals, JS_ReadUint32Pair,
};
use js::rust::Runtime;
use servo_url::MutableOrigin;
use super::structuredclone::StructuredCloneTags;
/// An owned reference to Servo's `JSPrincipals` instance.
#[repr(transparent)]
pub struct ServoJSPrincipals(NonNull<JSPrincipals>);
@ -123,8 +128,60 @@ pub unsafe extern "C" fn destroy_servo_jsprincipal(principals: *mut JSPrincipals
DestroyRustJSPrincipals(principals);
}
pub unsafe extern "C" fn write_jsprincipal(
principal: *mut JSPrincipals,
_cx: *mut JSContext,
writer: *mut JSStructuredCloneWriter,
) -> bool {
let Some(principal) = NonNull::new(principal) else {
return false;
};
let obj = ServoJSPrincipalsRef::from_raw_nonnull(principal);
let origin = obj.origin();
let Ok(bytes_of_origin) = bincode::serialize(&origin) else {
return false;
};
let Ok(len) = bytes_of_origin.len().try_into() else {
return false;
};
if !js::jsapi::JS_WriteUint32Pair(writer, StructuredCloneTags::Principals as u32, len) {
return false;
}
if !js::jsapi::JS_WriteBytes(writer, bytes_of_origin.as_ptr() as _, len as usize) {
return false;
}
true
}
pub unsafe extern "C" fn read_jsprincipal(
_cx: *mut JSContext,
reader: *mut JSStructuredCloneReader,
principals: *mut *mut JSPrincipals,
) -> bool {
let mut tag: u32 = 0;
let mut len: u32 = 0;
if !JS_ReadUint32Pair(reader, &mut tag as *mut u32, &mut len as *mut u32) {
return false;
}
if tag != StructuredCloneTags::Principals as u32 {
return false;
}
let mut bytes = vec![0u8; len as usize];
if !js::jsapi::JS_ReadBytes(reader, bytes.as_mut_ptr() as _, len as usize) {
return false;
}
let Ok(origin) = bincode::deserialize(&bytes[..]) else {
return false;
};
let principal = ServoJSPrincipals::new(&origin);
*principals = principal.as_raw();
// we transferred ownership of principal to the caller
std::mem::forget(principal);
true
}
const PRINCIPALS_CALLBACKS: JSPrincipalsCallbacks = JSPrincipalsCallbacks {
write: None,
write: Some(write_jsprincipal),
isSystemOrAddonPrincipal: Some(principals_is_system_or_addon_principal),
};

View file

@ -44,11 +44,12 @@ use crate::script_runtime::JSContext as SafeJSContext;
// NOTE: Current values found at https://dxr.mozilla.org/mozilla-central/
// rev/ff04d410e74b69acfab17ef7e73e7397602d5a68/js/public/StructuredClone.h#323
#[repr(u32)]
enum StructuredCloneTags {
pub(super) enum StructuredCloneTags {
/// To support additional types, add new tags with values incremented from the last one before Max.
Min = 0xFFFF8000,
DomBlob = 0xFFFF8001,
MessagePort = 0xFFFF8002,
Principals = 0xFFFF8003,
Max = 0xFFFFFFFF,
}

View file

@ -30,12 +30,12 @@ use js::jsapi::{
GetPromiseUserInputEventHandlingState, HandleObject, Heap, InitConsumeStreamCallback,
InitDispatchToEventLoop, JSContext as RawJSContext, JSGCParamKey, JSGCStatus,
JSJitCompilerOption, JSObject, JSSecurityCallbacks, JSTracer, JS_AddExtraGCRootsTracer,
JS_InitDestroyPrincipalsCallback, JS_RequestInterruptCallback, JS_SetGCCallback,
JS_SetGCParameter, JS_SetGlobalJitCompilerOption, JS_SetOffthreadIonCompilationEnabled,
JS_SetParallelParsingEnabled, JS_SetSecurityCallbacks, JobQueue, MimeType,
PromiseRejectionHandlingState, PromiseUserInputEventHandlingState, SetDOMCallbacks,
SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks, SetProcessBuildIdOp,
SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
JS_InitDestroyPrincipalsCallback, JS_InitReadPrincipalsCallback, JS_RequestInterruptCallback,
JS_SetGCCallback, JS_SetGCParameter, JS_SetGlobalJitCompilerOption,
JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled, JS_SetSecurityCallbacks,
JobQueue, MimeType, PromiseRejectionHandlingState, PromiseUserInputEventHandlingState,
SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
};
use js::jsval::UndefinedValue;
use js::panic::wrap_panic;
@ -466,6 +466,7 @@ unsafe fn new_rt_and_cx_with_parent(
JS_SetSecurityCallbacks(cx, &SECURITY_CALLBACKS);
JS_InitDestroyPrincipalsCallback(cx, Some(principals::destroy_servo_jsprincipal));
JS_InitReadPrincipalsCallback(cx, Some(principals::read_jsprincipal));
// Needed for debug assertions about whether GC is running.
if cfg!(debug_assertions) {

View file

@ -92,7 +92,7 @@ pub struct OpaqueOrigin(Uuid);
malloc_size_of_is_0!(OpaqueOrigin);
/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2).
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MutableOrigin(Rc<(ImmutableOrigin, RefCell<Option<Host>>)>);
malloc_size_of_is_0!(MutableOrigin);