mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Implement all trusted sinks in HTMLScriptElement
(#36668)
As a follow-up to the recent introduction of `script.src` as trusted sink, this PR refactors machinery to also support `TrustedScript`. In doing so, all trusted sinks in `HTMLScriptElement` are now covered. Instead of calling the callbacks in `policy.createX`, we now have a `TrustedType` enum that specifies which callback to invoke. Unfortunately we still have the `USVString` vs `DOMString` problem, which is why we need to `.map` twice to retrieve the backing `String` and avoid two different types. Additionally, I saw that `script.text` should have called the "String replace all" algorithm rather than setting the child contents. So that's also now fixed. Part of #36258 Requires servo/html5ever#608 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com> Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
dd63325f50
commit
4164f76769
20 changed files with 320 additions and 353 deletions
|
@ -149,7 +149,6 @@ use crate::dom::raredata::ElementRareData;
|
||||||
use crate::dom::servoparser::ServoParser;
|
use crate::dom::servoparser::ServoParser;
|
||||||
use crate::dom::shadowroot::{IsUserAgentWidget, ShadowRoot};
|
use crate::dom::shadowroot::{IsUserAgentWidget, ShadowRoot};
|
||||||
use crate::dom::text::Text;
|
use crate::dom::text::Text;
|
||||||
use crate::dom::types::TrustedTypePolicyFactory;
|
|
||||||
use crate::dom::validation::Validatable;
|
use crate::dom::validation::Validatable;
|
||||||
use crate::dom::validitystate::ValidationFlags;
|
use crate::dom::validitystate::ValidationFlags;
|
||||||
use crate::dom::virtualmethods::{VirtualMethods, vtable_for};
|
use crate::dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||||
|
@ -1961,35 +1960,6 @@ impl Element {
|
||||||
.unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
|
.unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_trusted_type_url_attribute(
|
|
||||||
&self,
|
|
||||||
local_name: &LocalName,
|
|
||||||
value: TrustedScriptURLOrUSVString,
|
|
||||||
can_gc: CanGc,
|
|
||||||
) -> Fallible<()> {
|
|
||||||
assert_eq!(*local_name, local_name.to_ascii_lowercase());
|
|
||||||
let value = match value {
|
|
||||||
TrustedScriptURLOrUSVString::USVString(url) => {
|
|
||||||
let global = self.owner_global();
|
|
||||||
// TODO(36258): Reflectively get the name of the class
|
|
||||||
let sink = format!("{} {}", "HTMLScriptElement", &local_name);
|
|
||||||
let result = TrustedTypePolicyFactory::get_trusted_type_compliant_string(
|
|
||||||
&global,
|
|
||||||
url.to_string(),
|
|
||||||
&sink,
|
|
||||||
"'script'",
|
|
||||||
can_gc,
|
|
||||||
);
|
|
||||||
result?
|
|
||||||
},
|
|
||||||
// This partially implements <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
|
|
||||||
// Step 1: If input is an instance of expectedType, return stringified input and abort these steps.
|
|
||||||
TrustedScriptURLOrUSVString::TrustedScriptURL(script_url) => script_url.to_string(),
|
|
||||||
};
|
|
||||||
self.set_attribute(local_name, AttrValue::String(value), can_gc);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
|
pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
|
||||||
match self.get_attribute(&ns!(), local_name) {
|
match self.get_attribute(&ns!(), local_name) {
|
||||||
Some(x) => x.Value(),
|
Some(x) => x.Value(),
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl HTMLElement {
|
||||||
/// `.outerText` in JavaScript.`
|
/// `.outerText` in JavaScript.`
|
||||||
///
|
///
|
||||||
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
||||||
fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString {
|
pub(crate) fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString {
|
||||||
let node = self.upcast::<Node>();
|
let node = self.upcast::<Node>();
|
||||||
let window = node.owner_window();
|
let window = node.owner_window();
|
||||||
let element = self.as_element();
|
let element = self.as_element();
|
||||||
|
@ -134,6 +134,16 @@ impl HTMLElement {
|
||||||
|
|
||||||
DOMString::from(text)
|
DOMString::from(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
||||||
|
pub(crate) fn set_inner_text(&self, input: DOMString, can_gc: CanGc) {
|
||||||
|
// Step 1: Let fragment be the rendered text fragment for value given element's node
|
||||||
|
// document.
|
||||||
|
let fragment = self.rendered_text_fragment(input, can_gc);
|
||||||
|
|
||||||
|
// Step 2: Replace all with fragment within element.
|
||||||
|
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>(), can_gc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
|
impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
|
||||||
|
@ -494,12 +504,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
||||||
fn SetInnerText(&self, input: DOMString, can_gc: CanGc) {
|
fn SetInnerText(&self, input: DOMString, can_gc: CanGc) {
|
||||||
// Step 1: Let fragment be the rendered text fragment for value given element's node
|
self.set_inner_text(input, can_gc)
|
||||||
// document.
|
|
||||||
let fragment = self.rendered_text_fragment(input, can_gc);
|
|
||||||
|
|
||||||
// Step 2: Replace all with fragment within element.
|
|
||||||
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>(), can_gc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
||||||
|
|
|
@ -32,6 +32,7 @@ use net_traits::{
|
||||||
};
|
};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||||
|
use style::attr::AttrValue;
|
||||||
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
|
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
|
||||||
use stylo_atoms::Atom;
|
use stylo_atoms::Atom;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -44,7 +45,9 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
|
use crate::dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
|
use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
|
||||||
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
|
use crate::dom::bindings::codegen::UnionTypes::{
|
||||||
|
TrustedScriptOrString, TrustedScriptURLOrUSVString,
|
||||||
|
};
|
||||||
use crate::dom::bindings::error::Fallible;
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::Trusted;
|
use crate::dom::bindings::refcounted::Trusted;
|
||||||
|
@ -64,6 +67,8 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::htmlelement::HTMLElement;
|
use crate::dom::htmlelement::HTMLElement;
|
||||||
use crate::dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeTraits};
|
use crate::dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeTraits};
|
||||||
use crate::dom::performanceresourcetiming::InitiatorType;
|
use crate::dom::performanceresourcetiming::InitiatorType;
|
||||||
|
use crate::dom::trustedscript::TrustedScript;
|
||||||
|
use crate::dom::trustedscripturl::TrustedScriptURL;
|
||||||
use crate::dom::virtualmethods::VirtualMethods;
|
use crate::dom::virtualmethods::VirtualMethods;
|
||||||
use crate::fetch::create_a_potential_cors_request;
|
use crate::fetch::create_a_potential_cors_request;
|
||||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||||
|
@ -667,7 +672,7 @@ impl HTMLScriptElement {
|
||||||
|
|
||||||
// Step 5. Let source text be el's child text content.
|
// Step 5. Let source text be el's child text content.
|
||||||
// Step 6. If el has no src attribute, and source text is the empty string, then return.
|
// Step 6. If el has no src attribute, and source text is the empty string, then return.
|
||||||
let text = self.Text();
|
let text = self.text();
|
||||||
if text.is_empty() && !element.has_attribute(&local_name!("src")) {
|
if text.is_empty() && !element.has_attribute(&local_name!("src")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1272,6 +1277,15 @@ impl HTMLScriptElement {
|
||||||
let event = Event::new(window.upcast(), type_, bubbles, cancelable, can_gc);
|
let event = Event::new(window.upcast(), type_, bubbles, cancelable, can_gc);
|
||||||
event.fire(self.upcast(), can_gc)
|
event.fire(self.upcast(), can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn text(&self) -> DOMString {
|
||||||
|
match self.Text() {
|
||||||
|
TrustedScriptOrString::String(value) => value,
|
||||||
|
TrustedScriptOrString::TrustedScript(trusted_script) => {
|
||||||
|
DOMString::from(trusted_script.to_string())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VirtualMethods for HTMLScriptElement {
|
impl VirtualMethods for HTMLScriptElement {
|
||||||
|
@ -1286,7 +1300,7 @@ impl VirtualMethods for HTMLScriptElement {
|
||||||
if *attr.local_name() == local_name!("src") {
|
if *attr.local_name() == local_name!("src") {
|
||||||
if let AttributeMutation::Set(_) = mutation {
|
if let AttributeMutation::Set(_) = mutation {
|
||||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
||||||
self.prepare(CanGc::note());
|
self.prepare(can_gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1344,10 +1358,25 @@ impl VirtualMethods for HTMLScriptElement {
|
||||||
|
|
||||||
impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-src
|
// https://html.spec.whatwg.org/multipage/#dom-script-src
|
||||||
make_trusted_type_url_getter!(Src, "src");
|
fn Src(&self) -> TrustedScriptURLOrUSVString {
|
||||||
|
let element = self.upcast::<Element>();
|
||||||
|
element.get_trusted_type_url_attribute(&local_name!("src"))
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-src
|
/// <https://w3c.github.io/trusted-types/dist/spec/#the-src-idl-attribute>
|
||||||
make_trusted_type_url_setter!(SetSrc, "src");
|
fn SetSrc(&self, value: TrustedScriptURLOrUSVString, can_gc: CanGc) -> Fallible<()> {
|
||||||
|
let element = self.upcast::<Element>();
|
||||||
|
let local_name = &local_name!("src");
|
||||||
|
let value = TrustedScriptURL::get_trusted_script_url_compliant_string(
|
||||||
|
&element.owner_global(),
|
||||||
|
value,
|
||||||
|
"HTMLScriptElement",
|
||||||
|
local_name,
|
||||||
|
can_gc,
|
||||||
|
)?;
|
||||||
|
element.set_attribute(local_name, AttrValue::String(value), can_gc);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-type
|
// https://html.spec.whatwg.org/multipage/#dom-script-type
|
||||||
make_getter!(Type, "type");
|
make_getter!(Type, "type");
|
||||||
|
@ -1416,14 +1445,77 @@ impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy
|
// https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy
|
||||||
make_setter!(SetReferrerPolicy, "referrerpolicy");
|
make_setter!(SetReferrerPolicy, "referrerpolicy");
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-text
|
/// <https://w3c.github.io/trusted-types/dist/spec/#dom-htmlscriptelement-innertext>
|
||||||
fn Text(&self) -> DOMString {
|
fn InnerText(&self, can_gc: CanGc) -> TrustedScriptOrString {
|
||||||
self.upcast::<Node>().child_text_content()
|
// Step 1: Return the result of running get the text steps with this.
|
||||||
|
TrustedScriptOrString::String(self.upcast::<HTMLElement>().get_inner_outer_text(can_gc))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-script-text
|
/// <https://w3c.github.io/trusted-types/dist/spec/#the-innerText-idl-attribute>
|
||||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
fn SetInnerText(&self, input: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
|
||||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
|
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||||
|
// this's relevant global object, the given value, HTMLScriptElement innerText, and script.
|
||||||
|
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||||
|
&self.owner_global(),
|
||||||
|
input,
|
||||||
|
"HTMLScriptElement",
|
||||||
|
"innerText",
|
||||||
|
can_gc,
|
||||||
|
)?;
|
||||||
|
// Step 3: Run set the inner text steps with this and value.
|
||||||
|
self.upcast::<HTMLElement>()
|
||||||
|
.set_inner_text(DOMString::from(value), can_gc);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://html.spec.whatwg.org/multipage/#dom-script-text>
|
||||||
|
fn Text(&self) -> TrustedScriptOrString {
|
||||||
|
TrustedScriptOrString::String(self.upcast::<Node>().child_text_content())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/trusted-types/dist/spec/#the-text-idl-attribute>
|
||||||
|
fn SetText(&self, value: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
|
||||||
|
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||||
|
// this's relevant global object, the given value, HTMLScriptElement text, and script.
|
||||||
|
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||||
|
&self.owner_global(),
|
||||||
|
value,
|
||||||
|
"HTMLScriptElement",
|
||||||
|
"text",
|
||||||
|
can_gc,
|
||||||
|
)?;
|
||||||
|
// Step 2: Set this's script text value to the given value.
|
||||||
|
// TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
|
||||||
|
// Step 3: String replace all with the given value within this.
|
||||||
|
Node::string_replace_all(DOMString::from(value), self.upcast::<Node>(), can_gc);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
|
||||||
|
fn GetTextContent(&self) -> Option<TrustedScriptOrString> {
|
||||||
|
// Step 1: Return the result of running get text content with this.
|
||||||
|
Some(TrustedScriptOrString::String(
|
||||||
|
self.upcast::<Node>().GetTextContent()?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
|
||||||
|
fn SetTextContent(&self, value: Option<TrustedScriptOrString>, can_gc: CanGc) -> Fallible<()> {
|
||||||
|
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||||
|
// this's relevant global object, the given value, HTMLScriptElement textContent, and script.
|
||||||
|
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||||
|
&self.owner_global(),
|
||||||
|
value.unwrap_or(TrustedScriptOrString::String(DOMString::from(""))),
|
||||||
|
"HTMLScriptElement",
|
||||||
|
"textContent",
|
||||||
|
can_gc,
|
||||||
|
)?;
|
||||||
|
// Step 2: Set this's script text value to value.
|
||||||
|
// TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
|
||||||
|
// Step 3: Run set text content with this and value.
|
||||||
|
self.upcast::<Node>()
|
||||||
|
.SetTextContent(Some(DOMString::from(value)), can_gc);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,32 +121,6 @@ macro_rules! make_url_setter(
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! make_trusted_type_url_getter(
|
|
||||||
( $attr:ident, $htmlname:tt ) => (
|
|
||||||
fn $attr(&self) -> TrustedScriptURLOrUSVString {
|
|
||||||
use $crate::dom::bindings::inheritance::Castable;
|
|
||||||
use $crate::dom::element::Element;
|
|
||||||
let element = self.upcast::<Element>();
|
|
||||||
element.get_trusted_type_url_attribute(&html5ever::local_name!($htmlname))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! make_trusted_type_url_setter(
|
|
||||||
( $attr:ident, $htmlname:tt ) => (
|
|
||||||
fn $attr(&self, value: TrustedScriptURLOrUSVString, can_gc: CanGc) -> Fallible<()> {
|
|
||||||
use $crate::dom::bindings::inheritance::Castable;
|
|
||||||
use $crate::dom::element::Element;
|
|
||||||
use $crate::script_runtime::CanGc;
|
|
||||||
let element = self.upcast::<Element>();
|
|
||||||
element.set_trusted_type_url_attribute(&html5ever::local_name!($htmlname),
|
|
||||||
value, can_gc)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! make_form_action_getter(
|
macro_rules! make_form_action_getter(
|
||||||
( $attr:ident, $htmlname:tt ) => (
|
( $attr:ident, $htmlname:tt ) => (
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
|
use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
|
||||||
|
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::trustedtypepolicy::TrustedType;
|
||||||
|
use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -30,6 +35,37 @@ impl TrustedScript {
|
||||||
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
|
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
|
||||||
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
|
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_trusted_script_compliant_string(
|
||||||
|
global: &GlobalScope,
|
||||||
|
value: TrustedScriptOrString,
|
||||||
|
containing_class: &str,
|
||||||
|
field: &str,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Fallible<String> {
|
||||||
|
match value {
|
||||||
|
TrustedScriptOrString::String(value) => {
|
||||||
|
let sink = format!("{} {}", containing_class, field);
|
||||||
|
TrustedTypePolicyFactory::get_trusted_type_compliant_string(
|
||||||
|
TrustedType::TrustedScript,
|
||||||
|
global,
|
||||||
|
value.as_ref().to_owned(),
|
||||||
|
&sink,
|
||||||
|
"'script'",
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for TrustedScript {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str(&self.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
|
impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
|
||||||
|
|
|
@ -7,10 +7,14 @@ use std::fmt;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::TrustedScriptURLBinding::TrustedScriptURLMethods;
|
use crate::dom::bindings::codegen::Bindings::TrustedScriptURLBinding::TrustedScriptURLMethods;
|
||||||
|
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::trustedtypepolicy::TrustedType;
|
||||||
|
use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -32,6 +36,31 @@ impl TrustedScriptURL {
|
||||||
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
|
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
|
||||||
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
|
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_trusted_script_url_compliant_string(
|
||||||
|
global: &GlobalScope,
|
||||||
|
value: TrustedScriptURLOrUSVString,
|
||||||
|
containing_class: &str,
|
||||||
|
field: &str,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Fallible<String> {
|
||||||
|
match value {
|
||||||
|
TrustedScriptURLOrUSVString::USVString(value) => {
|
||||||
|
let sink = format!("{} {}", containing_class, field);
|
||||||
|
TrustedTypePolicyFactory::get_trusted_type_compliant_string(
|
||||||
|
TrustedType::TrustedScriptURL,
|
||||||
|
global,
|
||||||
|
value.as_ref().to_owned(),
|
||||||
|
&sink,
|
||||||
|
"'script'",
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
TrustedScriptURLOrUSVString::TrustedScriptURL(trusted_script_url) => {
|
||||||
|
Ok(trusted_script_url.to_string())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TrustedScriptURL {
|
impl fmt::Display for TrustedScriptURL {
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::rc::Rc;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use js::jsapi::JSObject;
|
use js::jsapi::JSObject;
|
||||||
use js::rust::HandleValue;
|
use js::rust::HandleValue;
|
||||||
|
use strum_macros::IntoStaticStr;
|
||||||
|
|
||||||
use crate::dom::bindings::callback::ExceptionHandling;
|
use crate::dom::bindings::callback::ExceptionHandling;
|
||||||
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyBinding::TrustedTypePolicyMethods;
|
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyBinding::TrustedTypePolicyMethods;
|
||||||
|
@ -38,6 +39,13 @@ pub struct TrustedTypePolicy {
|
||||||
create_script_url: Option<Rc<CreateScriptURLCallback>>,
|
create_script_url: Option<Rc<CreateScriptURLCallback>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, IntoStaticStr)]
|
||||||
|
pub(crate) enum TrustedType {
|
||||||
|
TrustedHTML,
|
||||||
|
TrustedScript,
|
||||||
|
TrustedScriptURL,
|
||||||
|
}
|
||||||
|
|
||||||
impl TrustedTypePolicy {
|
impl TrustedTypePolicy {
|
||||||
fn new_inherited(name: String, options: &TrustedTypePolicyOptions) -> Self {
|
fn new_inherited(name: String, options: &TrustedTypePolicyOptions) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -59,39 +67,8 @@ impl TrustedTypePolicy {
|
||||||
reflect_dom_object(Box::new(Self::new_inherited(name, options)), global, can_gc)
|
reflect_dom_object(Box::new(Self::new_inherited(name, options)), global, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(36258): Remove when we refactor get_trusted_type_policy_value to take an enum
|
|
||||||
// value to handle which callback to call. The callback should not be exposed outside
|
|
||||||
// of the policy object, but is currently used in TrustedPolicyFactory::process_value_with_default_policy
|
|
||||||
pub(crate) fn create_script_url(&self) -> Option<Rc<CreateScriptURLCallback>> {
|
|
||||||
self.create_script_url.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This does not take all arguments as specified. That's because the return type of the
|
|
||||||
/// trusted type function and object are not the same. 2 of the 3 string callbacks return
|
|
||||||
/// a DOMString, while the other one returns an USVString. Additionally, all three callbacks
|
|
||||||
/// have a unique type signature in WebIDL.
|
|
||||||
///
|
|
||||||
/// To circumvent these type problems, rather than implementing the full functionality here,
|
|
||||||
/// part of the algorithm is implemented on the caller side. There, we only call the callback
|
|
||||||
/// and create the object. The rest of the machinery is ensuring the right values pass through
|
|
||||||
/// to the relevant callbacks.
|
|
||||||
///
|
|
||||||
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-policy-value-algorithm>
|
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-policy-value-algorithm>
|
||||||
pub(crate) fn get_trusted_type_policy_value<S, PolicyCallback>(
|
fn check_callback_if_missing(throw_if_missing: bool) -> Fallible<Option<String>> {
|
||||||
&self,
|
|
||||||
policy_value_callback: PolicyCallback,
|
|
||||||
throw_if_missing: bool,
|
|
||||||
) -> Fallible<Option<S>>
|
|
||||||
where
|
|
||||||
S: AsRef<str>,
|
|
||||||
PolicyCallback: FnOnce() -> Option<Fallible<Option<S>>>,
|
|
||||||
{
|
|
||||||
// Step 1: Let functionName be a function name for the given trustedTypeName, based on the following table:
|
|
||||||
// Step 2: Let function be policy’s options[functionName].
|
|
||||||
let function = policy_value_callback();
|
|
||||||
match function {
|
|
||||||
// Step 3: If function is null, then:
|
|
||||||
None => {
|
|
||||||
// Step 3.1: If throwIfMissing throw a TypeError.
|
// Step 3.1: If throwIfMissing throw a TypeError.
|
||||||
if throw_if_missing {
|
if throw_if_missing {
|
||||||
Err(Type("Cannot find type".to_owned()))
|
Err(Type("Cannot find type".to_owned()))
|
||||||
|
@ -99,11 +76,78 @@ impl TrustedTypePolicy {
|
||||||
// Step 3.2: Else return null.
|
// Step 3.2: Else return null.
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-policy-value-algorithm>
|
||||||
|
pub(crate) fn get_trusted_type_policy_value(
|
||||||
|
&self,
|
||||||
|
expected_type: TrustedType,
|
||||||
|
cx: JSContext,
|
||||||
|
input: DOMString,
|
||||||
|
arguments: Vec<HandleValue>,
|
||||||
|
throw_if_missing: bool,
|
||||||
|
can_gc: CanGc,
|
||||||
|
) -> Fallible<Option<String>> {
|
||||||
|
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:
|
||||||
|
match expected_type {
|
||||||
|
TrustedType::TrustedHTML => match &self.create_html {
|
||||||
|
// Step 3: If function is null, then:
|
||||||
|
None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
|
||||||
|
// Step 2: Let function be policy’s options[functionName].
|
||||||
|
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 null,
|
||||||
// rethrowing any exceptions.
|
// rethrowing any exceptions.
|
||||||
Some(policy_value) => policy_value,
|
callback
|
||||||
|
.Call_(
|
||||||
|
&this_object.handle(),
|
||||||
|
input,
|
||||||
|
arguments,
|
||||||
|
ExceptionHandling::Rethrow,
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
.map(|result| result.map(|str| str.as_ref().to_owned()))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TrustedType::TrustedScript => match &self.create_script {
|
||||||
|
// Step 3: If function is null, then:
|
||||||
|
None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
|
||||||
|
// Step 2: Let function be policy’s options[functionName].
|
||||||
|
Some(callback) => {
|
||||||
|
// 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,
|
||||||
|
// rethrowing any exceptions.
|
||||||
|
callback
|
||||||
|
.Call_(
|
||||||
|
&this_object.handle(),
|
||||||
|
input,
|
||||||
|
arguments,
|
||||||
|
ExceptionHandling::Rethrow,
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
.map(|result| result.map(|str| str.as_ref().to_owned()))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TrustedType::TrustedScriptURL => match &self.create_script_url {
|
||||||
|
// Step 3: If function is null, then:
|
||||||
|
None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
|
||||||
|
// Step 2: Let function be policy’s options[functionName].
|
||||||
|
Some(callback) => {
|
||||||
|
// 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,
|
||||||
|
// rethrowing any exceptions.
|
||||||
|
callback
|
||||||
|
.Call_(
|
||||||
|
&this_object.handle(),
|
||||||
|
input,
|
||||||
|
arguments,
|
||||||
|
ExceptionHandling::Rethrow,
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
|
.map(|result| result.map(|str| str.as_ref().to_owned()))
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,27 +162,30 @@ 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, S, PolicyCallback, TrustedTypeCallback>(
|
pub(crate) fn create_trusted_type<R, TrustedTypeCallback>(
|
||||||
&self,
|
&self,
|
||||||
policy_value_callback: PolicyCallback,
|
expected_type: TrustedType,
|
||||||
|
cx: JSContext,
|
||||||
|
input: DOMString,
|
||||||
|
arguments: Vec<HandleValue>,
|
||||||
trusted_type_creation_callback: TrustedTypeCallback,
|
trusted_type_creation_callback: TrustedTypeCallback,
|
||||||
|
can_gc: CanGc,
|
||||||
) -> Fallible<DomRoot<R>>
|
) -> Fallible<DomRoot<R>>
|
||||||
where
|
where
|
||||||
R: DomObject,
|
R: DomObject,
|
||||||
S: AsRef<str>,
|
|
||||||
PolicyCallback: FnOnce() -> Option<Fallible<Option<S>>>,
|
|
||||||
TrustedTypeCallback: FnOnce(String) -> DomRoot<R>,
|
TrustedTypeCallback: FnOnce(String) -> DomRoot<R>,
|
||||||
{
|
{
|
||||||
// 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 = self.get_trusted_type_policy_value(policy_value_callback, true);
|
let policy_value =
|
||||||
|
self.get_trusted_type_policy_value(expected_type, cx, 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),
|
||||||
Ok(policy_value) => {
|
Ok(policy_value) => {
|
||||||
// Step 3: Let dataString be the result of stringifying policyValue.
|
// Step 3: Let dataString be the result of stringifying policyValue.
|
||||||
let data_string = match policy_value {
|
let data_string = match policy_value {
|
||||||
Some(value) => value.as_ref().into(),
|
Some(value) => value,
|
||||||
// Step 4: If policyValue is null or undefined, set dataString to the empty string.
|
// Step 4: If policyValue is null or undefined, set dataString to the empty string.
|
||||||
None => "".to_owned(),
|
None => "".to_owned(),
|
||||||
};
|
};
|
||||||
|
@ -164,22 +211,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Fallible<DomRoot<TrustedHTML>> {
|
) -> Fallible<DomRoot<TrustedHTML>> {
|
||||||
self.create_trusted_type(
|
self.create_trusted_type(
|
||||||
|| {
|
TrustedType::TrustedHTML,
|
||||||
self.create_html.clone().map(|callback| {
|
cx,
|
||||||
rooted!(in(*cx) let this_object: *mut JSObject);
|
|
||||||
// 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,
|
|
||||||
// rethrowing any exceptions.
|
|
||||||
callback.Call_(
|
|
||||||
&this_object.handle(),
|
|
||||||
input,
|
input,
|
||||||
arguments,
|
arguments,
|
||||||
ExceptionHandling::Rethrow,
|
|
||||||
can_gc,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|data_string| TrustedHTML::new(data_string, &self.global(), can_gc),
|
|data_string| TrustedHTML::new(data_string, &self.global(), can_gc),
|
||||||
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscript>
|
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscript>
|
||||||
|
@ -191,22 +228,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Fallible<DomRoot<TrustedScript>> {
|
) -> Fallible<DomRoot<TrustedScript>> {
|
||||||
self.create_trusted_type(
|
self.create_trusted_type(
|
||||||
|| {
|
TrustedType::TrustedScript,
|
||||||
self.create_script.clone().map(|callback| {
|
cx,
|
||||||
rooted!(in(*cx) let this_object: *mut JSObject);
|
|
||||||
// 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,
|
|
||||||
// rethrowing any exceptions.
|
|
||||||
callback.Call_(
|
|
||||||
&this_object.handle(),
|
|
||||||
input,
|
input,
|
||||||
arguments,
|
arguments,
|
||||||
ExceptionHandling::Rethrow,
|
|
||||||
can_gc,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|data_string| TrustedScript::new(data_string, &self.global(), can_gc),
|
|data_string| TrustedScript::new(data_string, &self.global(), can_gc),
|
||||||
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscripturl>
|
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscripturl>
|
||||||
|
@ -218,22 +245,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Fallible<DomRoot<TrustedScriptURL>> {
|
) -> Fallible<DomRoot<TrustedScriptURL>> {
|
||||||
self.create_trusted_type(
|
self.create_trusted_type(
|
||||||
|| {
|
TrustedType::TrustedScriptURL,
|
||||||
self.create_script_url.clone().map(|callback| {
|
cx,
|
||||||
rooted!(in(*cx) let this_object: *mut JSObject);
|
|
||||||
// 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,
|
|
||||||
// rethrowing any exceptions.
|
|
||||||
callback.Call_(
|
|
||||||
&this_object.handle(),
|
|
||||||
input,
|
input,
|
||||||
arguments,
|
arguments,
|
||||||
ExceptionHandling::Rethrow,
|
|data_string| TrustedScriptURL::new(data_string, &self.global(), can_gc),
|
||||||
can_gc,
|
can_gc,
|
||||||
)
|
)
|
||||||
})
|
|
||||||
},
|
|
||||||
|data_string| TrustedScriptURL::new(data_string, &self.global(), can_gc),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@ use std::cell::RefCell;
|
||||||
use content_security_policy::CheckResult;
|
use content_security_policy::CheckResult;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
|
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
|
||||||
use js::jsapi::JSObject;
|
|
||||||
use js::jsval::NullValue;
|
use js::jsval::NullValue;
|
||||||
use js::rust::HandleValue;
|
use js::rust::HandleValue;
|
||||||
|
|
||||||
use crate::dom::bindings::callback::ExceptionHandling;
|
|
||||||
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyFactoryBinding::{
|
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyFactoryBinding::{
|
||||||
TrustedTypePolicyFactoryMethods, TrustedTypePolicyOptions,
|
TrustedTypePolicyFactoryMethods, TrustedTypePolicyOptions,
|
||||||
};
|
};
|
||||||
|
@ -23,7 +21,7 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::trustedhtml::TrustedHTML;
|
use crate::dom::trustedhtml::TrustedHTML;
|
||||||
use crate::dom::trustedscript::TrustedScript;
|
use crate::dom::trustedscript::TrustedScript;
|
||||||
use crate::dom::trustedscripturl::TrustedScriptURL;
|
use crate::dom::trustedscripturl::TrustedScriptURL;
|
||||||
use crate::dom::trustedtypepolicy::TrustedTypePolicy;
|
use crate::dom::trustedtypepolicy::{TrustedType, TrustedTypePolicy};
|
||||||
use crate::js::conversions::ToJSValConvertible;
|
use crate::js::conversions::ToJSValConvertible;
|
||||||
use crate::script_runtime::{CanGc, JSContext};
|
use crate::script_runtime::{CanGc, JSContext};
|
||||||
|
|
||||||
|
@ -144,29 +142,25 @@ impl TrustedTypePolicyFactory {
|
||||||
/// <https://w3c.github.io/trusted-types/dist/spec/#process-value-with-a-default-policy-algorithm>
|
/// <https://w3c.github.io/trusted-types/dist/spec/#process-value-with-a-default-policy-algorithm>
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub(crate) fn process_value_with_default_policy(
|
pub(crate) fn process_value_with_default_policy(
|
||||||
|
expected_type: TrustedType,
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
input: String,
|
input: String,
|
||||||
sink: &str,
|
sink: &str,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Fallible<Option<DomRoot<TrustedScriptURL>>> {
|
) -> Fallible<Option<String>> {
|
||||||
// Step 1: Let defaultPolicy be the value of global’s trusted type policy factory's default policy.
|
// Step 1: Let defaultPolicy be the value of global’s trusted type policy factory's default policy.
|
||||||
let global_policy_factory = global.trusted_types(can_gc);
|
let global_policy_factory = global.trusted_types(can_gc);
|
||||||
let default_policy = match global_policy_factory.default_policy.get() {
|
let default_policy = match global_policy_factory.default_policy.get() {
|
||||||
None => return Ok(Some(TrustedScriptURL::new(input, global, can_gc))),
|
None => return Ok(None),
|
||||||
Some(default_policy) => default_policy,
|
Some(default_policy) => default_policy,
|
||||||
};
|
};
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
// Step 2: Let policyValue be the result of executing Get Trusted Type policy value,
|
// Step 2: Let policyValue be the result of executing Get Trusted Type policy value,
|
||||||
// with the following arguments:
|
// with the following arguments:
|
||||||
let policy_value = default_policy.get_trusted_type_policy_value(
|
|
||||||
|| {
|
|
||||||
// TODO(36258): support other trusted types as well by changing get_trusted_type_policy_value to accept
|
|
||||||
// the trusted type as enum and call the appropriate callback based on that.
|
|
||||||
default_policy.create_script_url().map(|callback| {
|
|
||||||
rooted!(in(*cx) let this_object: *mut JSObject);
|
|
||||||
rooted!(in(*cx) let mut trusted_type_name_value = NullValue());
|
rooted!(in(*cx) let mut trusted_type_name_value = NullValue());
|
||||||
unsafe {
|
unsafe {
|
||||||
"TrustedScriptURL".to_jsval(*cx, trusted_type_name_value.handle_mut());
|
let trusted_type_name: &'static str = expected_type.clone().into();
|
||||||
|
trusted_type_name.to_jsval(*cx, trusted_type_name_value.handle_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
rooted!(in(*cx) let mut sink_value = NullValue());
|
rooted!(in(*cx) let mut sink_value = NullValue());
|
||||||
|
@ -174,20 +168,14 @@ impl TrustedTypePolicyFactory {
|
||||||
sink.to_jsval(*cx, sink_value.handle_mut());
|
sink.to_jsval(*cx, sink_value.handle_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = vec![trusted_type_name_value.handle(), sink_value.handle()];
|
let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()];
|
||||||
// Step 4: Let policyValue be the result of invoking function with value as a first argument,
|
let policy_value = default_policy.get_trusted_type_policy_value(
|
||||||
// items of arguments as subsequent arguments, and callback **this** value set to null,
|
expected_type,
|
||||||
// rethrowing any exceptions.
|
cx,
|
||||||
callback.Call_(
|
|
||||||
&this_object.handle(),
|
|
||||||
DOMString::from(input.to_owned()),
|
DOMString::from(input.to_owned()),
|
||||||
args,
|
arguments,
|
||||||
ExceptionHandling::Rethrow,
|
|
||||||
can_gc,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
false,
|
false,
|
||||||
|
can_gc,
|
||||||
);
|
);
|
||||||
let data_string = match policy_value {
|
let data_string = match policy_value {
|
||||||
// Step 3: If the algorithm threw an error, rethrow the error and abort the following steps.
|
// Step 3: If the algorithm threw an error, rethrow the error and abort the following steps.
|
||||||
|
@ -196,14 +184,15 @@ impl TrustedTypePolicyFactory {
|
||||||
// Step 4: If policyValue is null or undefined, return policyValue.
|
// Step 4: If policyValue is null or undefined, return policyValue.
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
// Step 5: Let dataString be the result of stringifying policyValue.
|
// Step 5: Let dataString be the result of stringifying policyValue.
|
||||||
Some(policy_value) => policy_value.as_ref().into(),
|
Some(policy_value) => policy_value,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(Some(TrustedScriptURL::new(data_string, global, can_gc)))
|
Ok(Some(data_string))
|
||||||
}
|
}
|
||||||
/// Step 1 is implemented by the caller
|
/// Step 1 is implemented by the caller
|
||||||
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
|
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
|
||||||
pub(crate) fn get_trusted_type_compliant_string(
|
pub(crate) fn get_trusted_type_compliant_string(
|
||||||
|
expected_type: TrustedType,
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
input: String,
|
input: String,
|
||||||
sink: &str,
|
sink: &str,
|
||||||
|
@ -224,6 +213,7 @@ impl TrustedTypePolicyFactory {
|
||||||
// Step 4: Let convertedInput be the result of executing Process value with a default policy
|
// Step 4: Let convertedInput be the result of executing Process value with a default policy
|
||||||
// with the same arguments as this algorithm.
|
// with the same arguments as this algorithm.
|
||||||
let converted_input = TrustedTypePolicyFactory::process_value_with_default_policy(
|
let converted_input = TrustedTypePolicyFactory::process_value_with_default_policy(
|
||||||
|
expected_type,
|
||||||
global,
|
global,
|
||||||
input.clone(),
|
input.clone(),
|
||||||
sink,
|
sink,
|
||||||
|
@ -252,7 +242,7 @@ impl TrustedTypePolicyFactory {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Step 8: Return stringified convertedInput.
|
// Step 8: Return stringified convertedInput.
|
||||||
Some(converted_input) => Ok((*converted_input).to_string()),
|
Some(converted_input) => Ok(converted_input),
|
||||||
}
|
}
|
||||||
// Step 7: Assert: convertedInput is an instance of expectedType.
|
// Step 7: Assert: convertedInput is an instance of expectedType.
|
||||||
// TODO(https://github.com/w3c/trusted-types/issues/566): Implement when spec is resolved
|
// TODO(https://github.com/w3c/trusted-types/issues/566): Implement when spec is resolved
|
||||||
|
|
|
@ -416,7 +416,7 @@ DOMInterfaces = {
|
||||||
},
|
},
|
||||||
|
|
||||||
'HTMLScriptElement': {
|
'HTMLScriptElement': {
|
||||||
'canGc': ['SetAsync', 'SetCrossOrigin', 'SetSrc', 'SetText']
|
'canGc': ['InnerText', 'SetAsync', 'SetCrossOrigin', 'SetInnerText', 'SetSrc', 'SetText', 'SetTextContent']
|
||||||
},
|
},
|
||||||
|
|
||||||
'HTMLSelectElement': {
|
'HTMLSelectElement': {
|
||||||
|
|
|
@ -21,8 +21,12 @@ interface HTMLScriptElement : HTMLElement {
|
||||||
attribute boolean defer;
|
attribute boolean defer;
|
||||||
[CEReactions]
|
[CEReactions]
|
||||||
attribute DOMString? crossOrigin;
|
attribute DOMString? crossOrigin;
|
||||||
[CEReactions, Pure]
|
[CEReactions, SetterThrows]
|
||||||
attribute DOMString text;
|
attribute (TrustedScript or DOMString) innerText;
|
||||||
|
[CEReactions, Pure, SetterThrows]
|
||||||
|
attribute (TrustedScript or DOMString) text;
|
||||||
|
[CEReactions, SetterThrows]
|
||||||
|
attribute (TrustedScript or DOMString)? textContent;
|
||||||
[CEReactions]
|
[CEReactions]
|
||||||
attribute DOMString integrity;
|
attribute DOMString integrity;
|
||||||
[CEReactions]
|
[CEReactions]
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
[HTMLElement-generic.html]
|
[HTMLElement-generic.html]
|
||||||
[TT enabled: script.src\n = String on a\n connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = String on a\n non-connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: div.innerHTML\n = String on a\n connected element\n ]
|
[TT enabled: div.innerHTML\n = String on a\n connected element\n ]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -17,30 +11,6 @@
|
||||||
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n ]
|
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n ]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[TT enabled: script.text\n = String on a\n connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.text\n = String on a\n non-connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.innerText\n = String on a\n connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.innerText\n = String on a\n non-connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.textContent\n = String on a\n connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.textContent\n = String on a\n non-connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: div.innerHTML\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
[TT enabled: div.innerHTML\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -52,33 +22,3 @@
|
||||||
|
|
||||||
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[TT enabled: script.text\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.text\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.innerText\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.innerText\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.textContent\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.textContent\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = TrustedScript on a\n connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = TrustedScript on a\n non-connected element\n ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = TrustedScript on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[TT enabled: script.src\n = TrustedScript on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
[block-string-assignment-to-HTMLElement-generic.html]
|
[block-string-assignment-to-HTMLElement-generic.html]
|
||||||
[script.src accepts only TrustedScriptURL]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[div.innerHTML accepts only TrustedHTML]
|
[div.innerHTML accepts only TrustedHTML]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -13,12 +10,3 @@
|
||||||
|
|
||||||
[iframe.srcdoc accepts string and null after default policy was created]
|
[iframe.srcdoc accepts string and null after default policy was created]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[script.text accepts only TrustedScript]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.innerText accepts only TrustedScript]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.textContent accepts only TrustedScript]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -7,12 +7,3 @@
|
||||||
|
|
||||||
[Setting SVGScriptElement.innerHTML to a plain string]
|
[Setting SVGScriptElement.innerHTML to a plain string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Setting HTMLScriptElement.innerText to a plain string]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Setting HTMLScriptElement.textContent to a plain string]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Setting HTMLScriptElement.text to a plain string]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -3,15 +3,9 @@
|
||||||
[Count SecurityPolicyViolation events.]
|
[Count SecurityPolicyViolation events.]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
||||||
[script.src no default policy]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[div.innerHTML no default policy]
|
[div.innerHTML no default policy]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[script.text no default policy]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[div.innerHTML default]
|
[div.innerHTML default]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -26,18 +20,3 @@
|
||||||
|
|
||||||
[div.innerHTML typeerror]
|
[div.innerHTML typeerror]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[script.text default]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.text null]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.text throw]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.text undefined]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[script.text typeerror]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -5,6 +5,3 @@
|
||||||
|
|
||||||
[div.innerHTML default]
|
[div.innerHTML default]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[script.text default]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
[require-trusted-types-for-report-only.html]
|
[require-trusted-types-for-report-only.html]
|
||||||
[Require trusted types for 'script' block create HTML.]
|
[Require trusted types for 'script' block create HTML.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Require trusted types for 'script' block create script.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Require trusted types for 'script' block create script URL.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
[require-trusted-types-for.html]
|
[require-trusted-types-for.html]
|
||||||
[Require trusted types for 'script' block create HTML.]
|
[Require trusted types for 'script' block create HTML.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Require trusted types for 'script' block create script.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Require trusted types for 'script' block create script URL.]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
[trusted-types-createHTMLDocument.html]
|
[trusted-types-createHTMLDocument.html]
|
||||||
[Trusted Type assignment is blocked. (document)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type instances created in the main doc can be used. (document)]
|
[Trusted Type instances created in the main doc can be used. (document)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Trusted Type assignment is blocked. (createHTMLDocument)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type instances created in the main doc can be used. (createHTMLDocument)]
|
[Trusted Type instances created in the main doc can be used. (createHTMLDocument)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Trusted Type assignment is blocked. (DOMParser)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type instances created in the main doc can be used. (DOMParser)]
|
[Trusted Type instances created in the main doc can be used. (DOMParser)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Trusted Type assignment is blocked. (XHR)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type instances created in the main doc can be used. (XHR)]
|
[Trusted Type instances created in the main doc can be used. (XHR)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
[trusted-types-report-only.html]
|
[trusted-types-report-only.html]
|
||||||
[Trusted Type violation report-only: assign string to script url]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type violation report-only: assign string to html]
|
[Trusted Type violation report-only: assign string to html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Trusted Type violation report-only: assign string to script.src]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Trusted Type violation report-only: assign string to script content]
|
[Trusted Type violation report-only: assign string to script content]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Trusted Type violation report: check report contents]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
[trusted-types-reporting-for-HTMLScriptElement.html]
|
|
||||||
[Violation report for plain string (innerText)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Violation report for plain string (textContent)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Violation report for plain string (src)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Violation report for plain string (text)]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue