script: Make root_from_handle_value a safe function by accepting SafeJSContext (#39193)

Change from unsafe pointer of root_from_handle_value  to SafeJSContext. 

#39131

---------

Signed-off-by: JasonHonKL <j2004nol@gmail.com>
Signed-off-by: Jason <jason@198-61-252-113-on-nets.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Jason <jason@198-61-252-113-on-nets.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
JasonHonKL 2025-09-09 12:26:02 -07:00 committed by GitHub
parent 721fc01c30
commit 839878c743
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 48 additions and 51 deletions

View file

@ -342,7 +342,7 @@ impl TrustedTypePolicyFactory {
cx: JSContext, cx: JSContext,
value: HandleValue, value: HandleValue,
) -> Result<DomRoot<TrustedScript>, ()> { ) -> Result<DomRoot<TrustedScript>, ()> {
unsafe { root_from_handlevalue::<TrustedScript>(value, *cx) } root_from_handlevalue::<TrustedScript>(value, cx)
} }
} }
@ -359,7 +359,7 @@ impl TrustedTypePolicyFactoryMethods<crate::DomTypeHolder> for TrustedTypePolicy
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-ishtml> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-ishtml>
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn IsHTML(&self, cx: JSContext, value: HandleValue) -> bool { fn IsHTML(&self, cx: JSContext, value: HandleValue) -> bool {
unsafe { root_from_handlevalue::<TrustedHTML>(value, *cx).is_ok() } root_from_handlevalue::<TrustedHTML>(value, cx).is_ok()
} }
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-isscript> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-isscript>
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -369,7 +369,7 @@ impl TrustedTypePolicyFactoryMethods<crate::DomTypeHolder> for TrustedTypePolicy
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-isscripturl> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-isscripturl>
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn IsScriptURL(&self, cx: JSContext, value: HandleValue) -> bool { fn IsScriptURL(&self, cx: JSContext, value: HandleValue) -> bool {
unsafe { root_from_handlevalue::<TrustedScriptURL>(value, *cx).is_ok() } root_from_handlevalue::<TrustedScriptURL>(value, cx).is_ok()
} }
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-emptyhtml> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicyfactory-emptyhtml>
fn EmptyHTML(&self, can_gc: CanGc) -> DomRoot<TrustedHTML> { fn EmptyHTML(&self, can_gc: CanGc) -> DomRoot<TrustedHTML> {

View file

@ -295,70 +295,57 @@ pub(crate) fn evaluate_key_path_on_value(
// If value is a Blob and identifier is "size" // If value is a Blob and identifier is "size"
if identifier == "size" { if identifier == "size" {
unsafe { if let Ok(blob) = root_from_handlevalue::<Blob>(current_value.handle(), cx) {
if let Ok(blob) = root_from_handlevalue::<Blob>(current_value.handle(), *cx) // Let value be a Number equal to values size.
{ blob.Size().safe_to_jsval(cx, current_value.handle_mut());
// Let value be a Number equal to values size.
blob.Size().safe_to_jsval(cx, current_value.handle_mut());
continue; continue;
}
} }
} }
// If value is a Blob and identifier is "type" // If value is a Blob and identifier is "type"
if identifier == "type" { if identifier == "type" {
unsafe { if let Ok(blob) = root_from_handlevalue::<Blob>(current_value.handle(), cx) {
if let Ok(blob) = root_from_handlevalue::<Blob>(current_value.handle(), *cx) // Let value be a String equal to values type.
{ blob.Type().safe_to_jsval(cx, current_value.handle_mut());
// Let value be a String equal to values type.
blob.Type().safe_to_jsval(cx, current_value.handle_mut());
continue; continue;
}
} }
} }
// If value is a File and identifier is "name" // If value is a File and identifier is "name"
if identifier == "name" { if identifier == "name" {
unsafe { if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), cx) {
if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), *cx) // Let value be a String equal to values name.
{ file.name().safe_to_jsval(cx, current_value.handle_mut());
// Let value be a String equal to values name.
file.name().safe_to_jsval(cx, current_value.handle_mut());
continue; continue;
}
} }
} }
// If value is a File and identifier is "lastModified" // If value is a File and identifier is "lastModified"
if identifier == "lastModified" { if identifier == "lastModified" {
unsafe { if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), cx) {
if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), *cx) // Let value be a Number equal to values lastModified.
{ file.LastModified()
// Let value be a Number equal to values lastModified. .safe_to_jsval(cx, current_value.handle_mut());
file.LastModified()
.safe_to_jsval(cx, current_value.handle_mut());
continue; continue;
}
} }
} }
// If value is a File and identifier is "lastModifiedDate" // If value is a File and identifier is "lastModifiedDate"
if identifier == "lastModifiedDate" { if identifier == "lastModifiedDate" {
unsafe { if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), cx) {
if let Ok(file) = root_from_handlevalue::<File>(current_value.handle(), *cx) // Let value be a new Date object with [[DateValue]] internal slot equal to values lastModified.
{ let time = ClippedTime {
// Let value be a new Date object with [[DateValue]] internal slot equal to values lastModified. t: file.LastModified() as f64,
let time = ClippedTime { };
t: file.LastModified() as f64, unsafe {
};
NewDateObject(*cx, time).safe_to_jsval(cx, current_value.handle_mut()); NewDateObject(*cx, time).safe_to_jsval(cx, current_value.handle_mut());
continue;
} }
continue;
} }
} }

View file

@ -981,7 +981,7 @@ def getJSToNativeConversionInfo(type: IDLType, descriptorProvider: DescriptorPro
templateBody = fill( templateBody = fill(
""" """
match ${function}($${val}, *cx) { match ${function}($${val}, cx) {
Ok(val) => val, Ok(val) => val,
Err(()) => { Err(()) => {
$*{failureCode} $*{failureCode}
@ -991,6 +991,7 @@ def getJSToNativeConversionInfo(type: IDLType, descriptorProvider: DescriptorPro
failureCode=unwrapFailureCode + "\n", failureCode=unwrapFailureCode + "\n",
function=conversionFunction) function=conversionFunction)
declType = CGGeneric(descriptorType) declType = CGGeneric(descriptorType)
if type.nullable(): if type.nullable():
templateBody = f"Some({templateBody})" templateBody = f"Some({templateBody})"

View file

@ -229,10 +229,12 @@ impl<T: DomObject + IDLInterface> FromJSValConvertible for DomRoot<T> {
value: HandleValue, value: HandleValue,
_config: Self::Config, _config: Self::Config,
) -> Result<ConversionResult<DomRoot<T>>, ()> { ) -> Result<ConversionResult<DomRoot<T>>, ()> {
Ok(match root_from_handlevalue(value, cx) { Ok(
Ok(result) => ConversionResult::Success(result), match root_from_handlevalue(value, SafeJSContext::from_ptr(cx)) {
Err(()) => ConversionResult::Failure("value is not an object".into()), Ok(result) => ConversionResult::Success(result),
}) Err(()) => ConversionResult::Failure("value is not an object".into()),
},
)
} }
} }
@ -398,14 +400,17 @@ where
/// # Safety /// # Safety
/// cx must point to a valid, non-null JS context. /// cx must point to a valid, non-null JS context.
#[allow(clippy::result_unit_err)] #[allow(clippy::result_unit_err)]
pub unsafe fn root_from_handlevalue<T>(v: HandleValue, cx: *mut JSContext) -> Result<DomRoot<T>, ()> pub fn root_from_handlevalue<T>(v: HandleValue, cx: SafeJSContext) -> Result<DomRoot<T>, ()>
where where
T: DomObject + IDLInterface, T: DomObject + IDLInterface,
{ {
if !v.get().is_object() { if !v.get().is_object() {
return Err(()); return Err(());
} }
root_from_object(v.get().to_object(), cx) #[allow(unsafe_code)]
unsafe {
root_from_object(v.get().to_object(), *cx)
}
} }
/// Convert `id` to a `DOMString`. Returns `None` if `id` is not a string or /// Convert `id` to a `DOMString`. Returns `None` if `id` is not a string or
@ -503,14 +508,18 @@ where
/// # Safety /// # Safety
/// `cx` must point to a valid, non-null JSContext. /// `cx` must point to a valid, non-null JSContext.
#[allow(clippy::result_unit_err)] #[allow(clippy::result_unit_err)]
pub unsafe fn native_from_handlevalue<T>(v: HandleValue, cx: *mut JSContext) -> Result<*const T, ()> pub fn native_from_handlevalue<T>(v: HandleValue, cx: SafeJSContext) -> Result<*const T, ()>
where where
T: DomObject + IDLInterface, T: DomObject + IDLInterface,
{ {
if !v.get().is_object() { if !v.get().is_object() {
return Err(()); return Err(());
} }
native_from_object(v.get().to_object(), cx)
#[allow(unsafe_code)]
unsafe {
native_from_object(v.get().to_object(), *cx)
}
} }
impl<T: ToJSValConvertible + JSTraceable> ToJSValConvertible for RootedTraceableBox<T> { impl<T: ToJSValConvertible + JSTraceable> ToJSValConvertible for RootedTraceableBox<T> {
@ -587,7 +596,7 @@ pub unsafe fn is_array_like<D: crate::DomTypes>(cx: *mut JSContext, value: Handl
/// Caller is responsible for throwing a JS exception if needed in case of error. /// Caller is responsible for throwing a JS exception if needed in case of error.
pub(crate) unsafe fn windowproxy_from_handlevalue<D: crate::DomTypes>( pub(crate) unsafe fn windowproxy_from_handlevalue<D: crate::DomTypes>(
v: HandleValue, v: HandleValue,
_cx: *mut JSContext, _cx: SafeJSContext,
) -> Result<DomRoot<D::WindowProxy>, ()> { ) -> Result<DomRoot<D::WindowProxy>, ()> {
if !v.get().is_object() { if !v.get().is_object() {
return Err(()); return Err(());