mirror of
https://github.com/lexmount/moli.git
synced 2026-10-09 08:01:05 +00:00
fix(webapi): adapt replayed bindings to current interfaces
Use shared interface descriptors for document and SVG receivers, remove
duplicate Performance and DOMParser declarations, and align existing CSP
and import-map test calls with the interfaces at this replay point.
Bring forward the applicable parts of 0500891ecc so the image request
conflict resolution can remain a separate commit. Keep the original
regression assertions and duplicate-policy coverage.
Validation: cargo fmt --all; cargo clippy --workspace --all-targets
--all-features -- -D warnings; cargo nextest run --no-fail-fast
(17642 passed, 13 skipped).
This commit is contained in:
@@ -4450,7 +4450,7 @@ mod tests {
|
||||
let policy = format!("trusted-types {name}");
|
||||
let expected = byte.is_ascii_alphanumeric() || b"-#=_/@.%".contains(&byte);
|
||||
assert_eq!(
|
||||
policy_allows_trusted_type_policy_name(&policy, &name),
|
||||
policy_allows_trusted_type_policy_name(&policy, &name, false),
|
||||
expected,
|
||||
"invalid tt-policy-name byte {byte:#04x} must not match literally",
|
||||
);
|
||||
@@ -4458,21 +4458,25 @@ mod tests {
|
||||
for name in ["none", "allow-duplicates", "A-z_09#=/@.%"] {
|
||||
assert!(policy_allows_trusted_type_policy_name(
|
||||
&format!("trusted-types {name}"),
|
||||
name
|
||||
name,
|
||||
false
|
||||
));
|
||||
}
|
||||
assert!(policy_allows_trusted_type_policy_name(
|
||||
"trusted-types valid policy*name",
|
||||
"valid"
|
||||
"valid",
|
||||
false
|
||||
));
|
||||
assert!(!policy_allows_trusted_type_policy_name(
|
||||
"trusted-types valid policy*name",
|
||||
"policy*name"
|
||||
"policy*name",
|
||||
false
|
||||
));
|
||||
for wildcard in ["\u{000b}*", "*\u{000b}", "policy*"] {
|
||||
assert!(!policy_allows_trusted_type_policy_name(
|
||||
&format!("trusted-types {wildcard}"),
|
||||
"valid"
|
||||
"valid",
|
||||
false
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -4488,7 +4492,7 @@ mod tests {
|
||||
"\0",
|
||||
] {
|
||||
for policy in ["", "trusted-types *"] {
|
||||
assert!(policy_allows_trusted_type_policy_name(policy, name));
|
||||
assert!(policy_allows_trusted_type_policy_name(policy, name, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,13 +954,6 @@ fn apply_lifecycle_to_navigation_entry<'s>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn is_window_performance<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
performance: v8::Local<'s, v8::Object>,
|
||||
) -> bool {
|
||||
get_private_value(scope, performance, PERFORMANCE_NAVIGATION_TYPE_SEED_SLOT).is_some()
|
||||
}
|
||||
|
||||
pub(super) fn performance_navigation_type_seed<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
performance: v8::Local<'s, v8::Object>,
|
||||
|
||||
@@ -30,22 +30,6 @@ struct PerformanceMarkOptions<'s> {
|
||||
start_time: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(webidl::WebIdlArgs)]
|
||||
#[webidl(prefix = "PerformanceMark")]
|
||||
struct PerformanceMarkConstructorArgs {
|
||||
#[webidl(required)]
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Default, webidl::WebIdlDictionary)]
|
||||
#[webidl(prefix = "PerformanceMarkOptions")]
|
||||
struct PerformanceMarkOptions<'s> {
|
||||
#[webidl(converter = "raw")]
|
||||
detail: Option<v8::Local<'s, v8::Value>>,
|
||||
#[webidl(name = "startTime", converter = "double")]
|
||||
start_time: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(webidl::WebIdlArgs)]
|
||||
#[webidl(prefix = "Performance.clearMarks")]
|
||||
struct PerformanceClearMarksArgs {
|
||||
|
||||
@@ -407,7 +407,6 @@ pub(super) fn svg_animated_string_getter<'s>(
|
||||
if !require_svg_receiver(
|
||||
scope,
|
||||
args.this(),
|
||||
SVG_ANIMATED_STRING_BASE_VAL_SLOT,
|
||||
"SVGAnimatedString",
|
||||
&format!("{name} getter"),
|
||||
) {
|
||||
@@ -433,13 +432,7 @@ pub(super) fn svg_animated_string_setter<'s>(
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
_rv: v8::ReturnValue<'_, v8::Value>,
|
||||
) {
|
||||
if !require_svg_receiver(
|
||||
scope,
|
||||
args.this(),
|
||||
SVG_ANIMATED_STRING_BASE_VAL_SLOT,
|
||||
"SVGAnimatedString",
|
||||
"baseVal setter",
|
||||
) {
|
||||
if !require_svg_receiver(scope, args.this(), "SVGAnimatedString", "baseVal setter") {
|
||||
return;
|
||||
}
|
||||
let animated = args.this();
|
||||
|
||||
@@ -832,7 +832,9 @@ fn build_trusted_script_code_like_carrier<'s>(
|
||||
TrustedTypeObjectDeclaration::new(value)
|
||||
.initialize(scope, object)
|
||||
.expect("TrustedScript code-like carrier declaration should initialize");
|
||||
web_api_interfaces::TrustedScript::DESCRIPTOR.initialize(scope, object).ok()?;
|
||||
web_api_interfaces::TrustedScript::DESCRIPTOR
|
||||
.initialize(scope, object)
|
||||
.ok()?;
|
||||
Some(object)
|
||||
}
|
||||
|
||||
@@ -905,7 +907,7 @@ fn trusted_types_factory_receiver_is_valid<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
receiver: v8::Local<'s, v8::Object>,
|
||||
) -> bool {
|
||||
if web_api_interfaces::TrustedTypePolicyFactory::is_instance(scope, receiver.into()) {
|
||||
if web_api_interfaces::TrustedTypePolicyFactory::is_instance(scope, receiver) {
|
||||
return true;
|
||||
}
|
||||
throw_type_error(scope, "Illegal invocation");
|
||||
|
||||
@@ -18,7 +18,7 @@ pub(super) fn build_node_wrapper_template<'s, 'i>(
|
||||
let template = v8::ObjectTemplate::new(scope);
|
||||
let _ = template.set_internal_field_count(1);
|
||||
|
||||
if descriptor.prototype_name == "HTMLDocument" {
|
||||
if descriptor.interface.name() == "HTMLDocument" {
|
||||
named_access::install_document_named_property_handler(template);
|
||||
}
|
||||
|
||||
|
||||
@@ -2557,87 +2557,6 @@ fn service_worker_register_gates_script_url_before_url_resolution() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dom_parser_gates_converted_union_source_after_webidl_argument_conversion() {
|
||||
let mut vm = new_storage_test_vm("https://dom-parser-trusted-types.test/");
|
||||
vm.set_response_content_security_policies(&["require-trusted-types-for 'script'".to_owned()]);
|
||||
|
||||
let result = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const errorName = callback => {
|
||||
try {
|
||||
callback();
|
||||
return "none";
|
||||
} catch (error) {
|
||||
return error && error.name;
|
||||
}
|
||||
};
|
||||
const parser = new DOMParser();
|
||||
const custom = trustedTypes.createPolicy("dom-parser-custom", {
|
||||
createHTML: value => value
|
||||
});
|
||||
const blocked = [
|
||||
errorName(() => parser.parseFromString("<p>blocked</p>", "text/html")),
|
||||
errorName(() => parser.parseFromString(null, "text/html")),
|
||||
errorName(() => parser.parseFromString("<root/>", "application/xml"))
|
||||
];
|
||||
const accepted = [
|
||||
parser.parseFromString(
|
||||
custom.createHTML("<main>trusted</main>"),
|
||||
"text/html"
|
||||
).body.innerText,
|
||||
parser.parseFromString(
|
||||
custom.createHTML("<root/>"),
|
||||
"application/xml"
|
||||
).documentElement.tagName
|
||||
];
|
||||
|
||||
let sourceConversions = 0;
|
||||
const defaultCalls = [];
|
||||
trustedTypes.createPolicy("default", {
|
||||
createHTML: (value, type, sink) => {
|
||||
defaultCalls.push([value, type, sink]);
|
||||
return value === "source" ? "<p>default</p>" : value;
|
||||
}
|
||||
});
|
||||
const source = {
|
||||
toString() {
|
||||
sourceConversions += 1;
|
||||
return "source";
|
||||
}
|
||||
};
|
||||
const defaultValues = [
|
||||
parser.parseFromString(source, "text/html").body.innerText,
|
||||
parser.parseFromString(null, "text/html").body.innerText,
|
||||
parser.parseFromString("<root/>", "application/xml").documentElement.tagName
|
||||
];
|
||||
const callsBeforeInvalidType = defaultCalls.length;
|
||||
const invalidType = errorName(() => parser.parseFromString(source, "TEXT/html"));
|
||||
const invalidTypeSkippedPolicy = defaultCalls.length === callsBeforeInvalidType;
|
||||
|
||||
return JSON.stringify({
|
||||
blocked,
|
||||
accepted,
|
||||
defaultValues,
|
||||
sourceConversions,
|
||||
invalidType,
|
||||
invalidTypeSkippedPolicy,
|
||||
symbolSource: errorName(() => parser.parseFromString(Symbol(), "text/html")),
|
||||
defaultCalls
|
||||
});
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("DOMParser TrustedHTML union probe should evaluate");
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
r#"{"blocked":["TypeError","TypeError","TypeError"],"accepted":["trusted","root"],"defaultValues":["default","null","root"],"sourceConversions":2,"invalidType":"TypeError","invalidTypeSkippedPolicy":true,"symbolSource":"TypeError","defaultCalls":[["source","TrustedHTML","DOMParser parseFromString"],["null","TrustedHTML","DOMParser parseFromString"],["<root/>","TrustedHTML","DOMParser parseFromString"]]}"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_worker_register_converts_options_before_the_default_policy() {
|
||||
let mut vm = new_storage_test_vm("https://service-worker-register-options.test/");
|
||||
|
||||
Reference in New Issue
Block a user