Use undefined as this in trusted type callbacks (#37594)

As discussed in w3c/trusted-types#468 the spec will be aligned to the
other browsers, which call the callback with undefined as this.

That also allows us to cleanup the JSContext arguments across a couple
of methods.

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
Tim van der Lippe 2025-06-21 20:29:09 +02:00 committed by GitHub
parent 5579b11cf6
commit d2a688d798
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 14 additions and 40 deletions

View file

@ -5,7 +5,6 @@
use std::rc::Rc; use std::rc::Rc;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::jsapi::JSObject;
use js::rust::HandleValue; use js::rust::HandleValue;
use strum_macros::IntoStaticStr; use strum_macros::IntoStaticStr;
@ -82,13 +81,11 @@ impl TrustedTypePolicy {
pub(crate) fn get_trusted_type_policy_value( pub(crate) fn get_trusted_type_policy_value(
&self, &self,
expected_type: TrustedType, expected_type: TrustedType,
cx: JSContext,
input: DOMString, input: DOMString,
arguments: Vec<HandleValue>, arguments: Vec<HandleValue>,
throw_if_missing: bool, throw_if_missing: bool,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<Option<DOMString>> { ) -> Fallible<Option<DOMString>> {
rooted!(in(*cx) let this_object: *mut JSObject);
// Step 1: Let functionName be a function name for the given trustedTypeName, based on the following table: // Step 1: Let functionName be a function name for the given trustedTypeName, based on the following table:
match expected_type { match expected_type {
TrustedType::TrustedHTML => match &self.create_html { TrustedType::TrustedHTML => match &self.create_html {
@ -97,15 +94,9 @@ impl TrustedTypePolicy {
// Step 2: Let function be policys options[functionName]. // Step 2: Let function be policys options[functionName].
Some(callback) => { Some(callback) => {
// Step 4: Let policyValue be the result of invoking function with value as a first argument, // Step 4: Let policyValue be the result of invoking function with value as a first argument,
// items of arguments as subsequent arguments, and callback **this** value set to null, // items of arguments as subsequent arguments, and callback **this** value set to undefined,
// rethrowing any exceptions. // rethrowing any exceptions.
callback.Call_( callback.Call__(input, arguments, ExceptionHandling::Rethrow, can_gc)
&this_object.handle(),
input,
arguments,
ExceptionHandling::Rethrow,
can_gc,
)
}, },
}, },
TrustedType::TrustedScript => match &self.create_script { TrustedType::TrustedScript => match &self.create_script {
@ -114,15 +105,9 @@ impl TrustedTypePolicy {
// Step 2: Let function be policys options[functionName]. // Step 2: Let function be policys options[functionName].
Some(callback) => { Some(callback) => {
// Step 4: Let policyValue be the result of invoking function with value as a first argument, // Step 4: Let policyValue be the result of invoking function with value as a first argument,
// items of arguments as subsequent arguments, and callback **this** value set to null, // items of arguments as subsequent arguments, and callback **this** value set to undefined,
// rethrowing any exceptions. // rethrowing any exceptions.
callback.Call_( callback.Call__(input, arguments, ExceptionHandling::Rethrow, can_gc)
&this_object.handle(),
input,
arguments,
ExceptionHandling::Rethrow,
can_gc,
)
}, },
}, },
TrustedType::TrustedScriptURL => match &self.create_script_url { TrustedType::TrustedScriptURL => match &self.create_script_url {
@ -131,16 +116,10 @@ impl TrustedTypePolicy {
// Step 2: Let function be policys options[functionName]. // Step 2: Let function be policys options[functionName].
Some(callback) => { Some(callback) => {
// Step 4: Let policyValue be the result of invoking function with value as a first argument, // Step 4: Let policyValue be the result of invoking function with value as a first argument,
// items of arguments as subsequent arguments, and callback **this** value set to null, // items of arguments as subsequent arguments, and callback **this** value set to undefined,
// rethrowing any exceptions. // rethrowing any exceptions.
callback callback
.Call_( .Call__(input, arguments, ExceptionHandling::Rethrow, can_gc)
&this_object.handle(),
input,
arguments,
ExceptionHandling::Rethrow,
can_gc,
)
.map(|result| result.map(|str| DOMString::from(str.as_ref()))) .map(|result| result.map(|str| DOMString::from(str.as_ref())))
}, },
}, },
@ -158,10 +137,9 @@ impl TrustedTypePolicy {
/// to the relevant callbacks. /// to the relevant callbacks.
/// ///
/// <https://w3c.github.io/trusted-types/dist/spec/#create-a-trusted-type-algorithm> /// <https://w3c.github.io/trusted-types/dist/spec/#create-a-trusted-type-algorithm>
pub(crate) fn create_trusted_type<R, TrustedTypeCallback>( fn create_trusted_type<R, TrustedTypeCallback>(
&self, &self,
expected_type: TrustedType, expected_type: TrustedType,
cx: JSContext,
input: DOMString, input: DOMString,
arguments: Vec<HandleValue>, arguments: Vec<HandleValue>,
trusted_type_creation_callback: TrustedTypeCallback, trusted_type_creation_callback: TrustedTypeCallback,
@ -174,7 +152,7 @@ impl TrustedTypePolicy {
// Step 1: Let policyValue be the result of executing Get Trusted Type policy value // Step 1: Let policyValue be the result of executing Get Trusted Type policy value
// with the same arguments as this algorithm and additionally true as throwIfMissing. // with the same arguments as this algorithm and additionally true as throwIfMissing.
let policy_value = let policy_value =
self.get_trusted_type_policy_value(expected_type, cx, input, arguments, true, can_gc); self.get_trusted_type_policy_value(expected_type, input, arguments, true, can_gc);
match policy_value { match policy_value {
// Step 2: If the algorithm threw an error, rethrow the error and abort the following steps. // Step 2: If the algorithm threw an error, rethrow the error and abort the following steps.
Err(error) => Err(error), Err(error) => Err(error),
@ -201,14 +179,13 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createhtml> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createhtml>
fn CreateHTML( fn CreateHTML(
&self, &self,
cx: JSContext, _cx: JSContext,
input: DOMString, input: DOMString,
arguments: Vec<HandleValue>, arguments: Vec<HandleValue>,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<TrustedHTML>> { ) -> Fallible<DomRoot<TrustedHTML>> {
self.create_trusted_type( self.create_trusted_type(
TrustedType::TrustedHTML, TrustedType::TrustedHTML,
cx,
input, input,
arguments, arguments,
|data_string| TrustedHTML::new(data_string, &self.global(), can_gc), |data_string| TrustedHTML::new(data_string, &self.global(), can_gc),
@ -218,14 +195,13 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscript> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscript>
fn CreateScript( fn CreateScript(
&self, &self,
cx: JSContext, _cx: JSContext,
input: DOMString, input: DOMString,
arguments: Vec<HandleValue>, arguments: Vec<HandleValue>,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<TrustedScript>> { ) -> Fallible<DomRoot<TrustedScript>> {
self.create_trusted_type( self.create_trusted_type(
TrustedType::TrustedScript, TrustedType::TrustedScript,
cx,
input, input,
arguments, arguments,
|data_string| TrustedScript::new(data_string, &self.global(), can_gc), |data_string| TrustedScript::new(data_string, &self.global(), can_gc),
@ -235,14 +211,13 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscripturl> /// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscripturl>
fn CreateScriptURL( fn CreateScriptURL(
&self, &self,
cx: JSContext, _cx: JSContext,
input: DOMString, input: DOMString,
arguments: Vec<HandleValue>, arguments: Vec<HandleValue>,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<TrustedScriptURL>> { ) -> Fallible<DomRoot<TrustedScriptURL>> {
self.create_trusted_type( self.create_trusted_type(
TrustedType::TrustedScriptURL, TrustedType::TrustedScriptURL,
cx,
input, input,
arguments, arguments,
|data_string| TrustedScriptURL::new(data_string, &self.global(), can_gc), |data_string| TrustedScriptURL::new(data_string, &self.global(), can_gc),

View file

@ -171,7 +171,6 @@ impl TrustedTypePolicyFactory {
let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()]; let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()];
let policy_value = default_policy.get_trusted_type_policy_value( let policy_value = default_policy.get_trusted_type_policy_value(
expected_type, expected_type,
cx,
input, input,
arguments, arguments,
false, false,

View file

@ -824957,7 +824957,7 @@
] ]
], ],
"TrustedTypePolicy-createXXX.html": [ "TrustedTypePolicy-createXXX.html": [
"f51f51d98455ebccdee31a5b0d844a926b27fc0e", "957a691bcd909d71b2b34a4256fe7168cd14930b",
[ [
null, null,
{} {}

View file

@ -61,7 +61,7 @@
[ s => null, "" ], [ s => null, "" ],
[ s => "well, " + s, "well, whatever" ], [ s => "well, " + s, "well, whatever" ],
[ s => { throw new Error() }, Error ], [ s => { throw new Error() }, Error ],
[ new WrappingClass().callback_to_capture_this, "null"], [ new WrappingClass().callback_to_capture_this, "undefined"],
[ s => { aGlobalVarForSideEffectTesting = s; return s }, "whatever" ], [ s => { aGlobalVarForSideEffectTesting = s; return s }, "whatever" ],
[ s => aGlobalVarForSideEffectTesting + s, "whateverwhatever" ], [ s => aGlobalVarForSideEffectTesting + s, "whateverwhatever" ],
[ aGlobalFunction.bind(aGlobalObject), "well, whatever" ], [ aGlobalFunction.bind(aGlobalObject), "well, whatever" ],
@ -73,7 +73,7 @@
[ s => null, "" ], [ s => null, "" ],
[ s => s + "#duck", INPUTS.SCRIPTURL + "#duck" ], [ s => s + "#duck", INPUTS.SCRIPTURL + "#duck" ],
[ s => { throw new Error() }, Error ], [ s => { throw new Error() }, Error ],
[ new WrappingClass().callback_to_capture_this, "null"], [ new WrappingClass().callback_to_capture_this, "undefined"],
[ s => s + "#" + aGlobalVarForSideEffectTesting, [ s => s + "#" + aGlobalVarForSideEffectTesting,
INPUTS.SCRIPTURL + "#global" ], INPUTS.SCRIPTURL + "#global" ],
[ anotherGlobalFunction.bind(aGlobalObject), INPUTS.SCRIPTURL + "#well," ], [ anotherGlobalFunction.bind(aGlobalObject), INPUTS.SCRIPTURL + "#well," ],