From 2aff185c7d3e458b7ba45f3be3e8a0bb7f49b761 Mon Sep 17 00:00:00 2001 From: ldm0 Date: Thu, 1 Oct 2026 07:01:21 +0800 Subject: [PATCH] test(trusted-types): cover policy callback conversion rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cover createPolicy dictionary conversion, inherited callbacks, omitted/null options, variadic callback arguments, null callback results and original conversion exceptions. These regressions exercise the Trusted Types implementation already on main. Keep all three Web IDL methods on an empty policy’s prototype and require TypeError when their callbacks are absent. This corrects the old fixture assumption that omitted callbacks remove methods. --- .../tests/browser_api/trusted_types.rs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/trusted_types.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/trusted_types.rs index 5015d37056..91be9d465f 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/trusted_types.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/trusted_types.rs @@ -40,6 +40,90 @@ fn trusted_types_csp_policy_creation_matches_only_valid_name_tokens() { } } +#[test] +fn trusted_type_policy_callbacks_follow_webidl_dictionary_and_callback_rules() { + let mut vm = new_storage_test_vm("https://trusted-type-policy-webidl.test/"); + + let result = vm + .eval( + r#" +(() => { + const errorName = callback => { + try { + callback(); + return "none"; + } catch (error) { + return error.constructor.name; + } + }; + const methodTypes = policy => [ + typeof policy.createHTML, + typeof policy.createScript, + typeof policy.createScriptURL + ]; + + const emptyFromNull = trustedTypes.createPolicy("empty-null", null); + const emptyFromOmission = trustedTypes.createPolicy("empty-omitted"); + const extra = { marker: "extra" }; + let observed; + class NullCallbacks { + createHTML(input, ...rest) { + observed = [this === undefined, input, rest.length, rest[0] === extra, rest[1]]; + return null; + } + createScript() { + return null; + } + createScriptURL() { + return null; + } + } + const nullPolicy = trustedTypes.createPolicy("null-results", new NullCallbacks()); + const nullResults = [ + String(nullPolicy.createHTML({ toString: () => "converted" }, extra, 42)), + String(nullPolicy.createScript("script")), + String(nullPolicy.createScriptURL("script-url")) + ]; + + const variadicPolicy = trustedTypes.createPolicy("variadic", { + createHTML: (a, b, c) => a + b + c, + createScript: (a, b, c) => a + b + c, + createScriptURL: (a, b, c) => a + b + c + }); + const variadicResults = [ + String(variadicPolicy.createHTML("a", "b", "c")), + String(variadicPolicy.createScript("a", "b")), + String(variadicPolicy.createScriptURL("a", 123, null)) + ]; + + return JSON.stringify({ + emptyMethods: [methodTypes(emptyFromNull), methodTypes(emptyFromOmission)], + missingCallbacks: [emptyFromNull, emptyFromOmission].map(policy => + ['createHTML', 'createScript', 'createScriptURL'].map(method => + errorName(() => policy[method]('input')))), + nullResults, + observed, + variadicResults, + errors: [ + errorName(() => trustedTypes.createPolicy("primitive-options", 1)), + errorName(() => trustedTypes.createPolicy("non-callable", { createHTML: null })), + errorName(() => trustedTypes.createPolicy("throwing-getter", { + get createHTML() { throw new RangeError("getter"); } + })), + errorName(() => nullPolicy.createHTML()) + ] + }); +})() +"#, + ) + .expect("TrustedTypePolicy WebIDL callback probe should evaluate"); + + assert_eq!( + result, + r#"{"emptyMethods":[["function","function","function"],["function","function","function"]],"missingCallbacks":[["TypeError","TypeError","TypeError"],["TypeError","TypeError","TypeError"]],"nullResults":["","",""],"observed":[true,"converted",2,true,42],"variadicResults":["abc","abundefined","a123null"],"errors":["TypeError","TypeError","RangeError","TypeError"]}"# + ); +} + #[test] fn element_markup_sinks_enforce_trusted_html_and_standard_sink_names() { let mut vm = new_storage_test_vm("https://element-markup-trusted-types.test/");