mirror of
https://github.com/servo/servo.git
synced 2025-08-26 07:38:21 +01:00
Propagate Trusted Types errors for Node.textContent (#38871)
Part of #36258 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
f1a5da6836
commit
10ac177aa5
14 changed files with 52 additions and 85 deletions
|
@ -4982,7 +4982,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
|
|||
None => return,
|
||||
};
|
||||
|
||||
let elem = if root.namespace() == &ns!(svg) && root.local_name() == &local_name!("svg") {
|
||||
let node = if root.namespace() == &ns!(svg) && root.local_name() == &local_name!("svg") {
|
||||
let elem = root.upcast::<Node>().child_elements().find(|node| {
|
||||
node.namespace() == &ns!(svg) && node.local_name() == &local_name!("title")
|
||||
});
|
||||
|
@ -5036,7 +5036,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
|
|||
return;
|
||||
};
|
||||
|
||||
elem.SetTextContent(Some(title), can_gc);
|
||||
node.set_text_content_for_element(Some(title), can_gc);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-document-head
|
||||
|
|
|
@ -3876,8 +3876,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
|||
.iter()
|
||||
.any(|c| matches!(*c, b'&' | b'\0' | b'<' | b'\r'))
|
||||
{
|
||||
Node::SetTextContent(&target, Some(value), can_gc);
|
||||
return Ok(());
|
||||
return Node::SetTextContent(&target, Some(value), can_gc);
|
||||
}
|
||||
|
||||
// Step 3: Let fragment be the result of invoking the fragment parsing algorithm steps
|
||||
|
|
|
@ -132,7 +132,8 @@ impl HTMLAnchorElementMethods<crate::DomTypeHolder> for HTMLAnchorElement {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-a-text
|
||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
|
||||
self.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(value), can_gc)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-a-rel
|
||||
|
|
|
@ -114,7 +114,7 @@ impl HTMLDetailsElement {
|
|||
HTMLElement::new(local_name!("summary"), None, &document, None, can_gc);
|
||||
fallback_summary
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc);
|
||||
.set_text_content_for_element(Some(DEFAULT_SUMMARY.into()), can_gc);
|
||||
summary
|
||||
.upcast::<Node>()
|
||||
.AppendChild(fallback_summary.upcast::<Node>(), can_gc)
|
||||
|
|
|
@ -2055,7 +2055,7 @@ impl HTMLMediaElement {
|
|||
*self.media_controls_id.borrow_mut() = Some(id);
|
||||
script
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some(DOMString::from(media_controls_script)), can_gc);
|
||||
.set_text_content_for_element(Some(DOMString::from(media_controls_script)), can_gc);
|
||||
if let Err(e) = shadow_root
|
||||
.upcast::<Node>()
|
||||
.AppendChild(script.upcast::<Node>(), can_gc)
|
||||
|
@ -2074,7 +2074,7 @@ impl HTMLMediaElement {
|
|||
);
|
||||
style
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some(DOMString::from(MEDIA_CONTROL_CSS)), can_gc);
|
||||
.set_text_content_for_element(Some(DOMString::from(MEDIA_CONTROL_CSS)), can_gc);
|
||||
|
||||
if let Err(e) = shadow_root
|
||||
.upcast::<Node>()
|
||||
|
|
|
@ -176,7 +176,9 @@ impl HTMLOptionElementMethods<crate::DomTypeHolder> for HTMLOptionElement {
|
|||
let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap();
|
||||
|
||||
if !text.is_empty() {
|
||||
option.upcast::<Node>().SetTextContent(Some(text), can_gc)
|
||||
option
|
||||
.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(text), can_gc)
|
||||
}
|
||||
|
||||
if let Some(val) = value {
|
||||
|
@ -224,7 +226,8 @@ impl HTMLOptionElementMethods<crate::DomTypeHolder> for HTMLOptionElement {
|
|||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-option-text>
|
||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
|
||||
self.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(value), can_gc)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-option-form>
|
||||
|
|
|
@ -1523,7 +1523,8 @@ impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
|||
// Step 2: Set this's script text value to value.
|
||||
*self.script_text.borrow_mut() = value.clone();
|
||||
// Step 3: Run set text content with this and value.
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc);
|
||||
self.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(value), can_gc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ impl HTMLSelectElement {
|
|||
);
|
||||
chevron_container
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some("▾".into()), can_gc);
|
||||
.set_text_content_for_element(Some("▾".into()), can_gc);
|
||||
select_box
|
||||
.upcast::<Node>()
|
||||
.AppendChild(chevron_container.upcast::<Node>(), can_gc)
|
||||
|
|
|
@ -311,7 +311,8 @@ impl HTMLTextAreaElementMethods<crate::DomTypeHolder> for HTMLTextAreaElement {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue
|
||||
fn SetDefaultValue(&self, value: DOMString, can_gc: CanGc) {
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc);
|
||||
self.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(value), can_gc);
|
||||
|
||||
// if the element's dirty value flag is false, then the element's
|
||||
// raw value must be set to the value of the element's textContent IDL attribute
|
||||
|
|
|
@ -9,7 +9,6 @@ use html5ever::{LocalName, Prefix};
|
|||
use js::rust::HandleObject;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
|
@ -71,7 +70,8 @@ impl HTMLTitleElementMethods<crate::DomTypeHolder> for HTMLTitleElement {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-title-text
|
||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
|
||||
self.upcast::<Node>()
|
||||
.set_text_content_for_element(Some(value), can_gc)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3067,6 +3067,30 @@ impl Node {
|
|||
DOMString::from(content)
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#string-replace-all>
|
||||
pub(crate) fn set_text_content_for_element(&self, value: Option<DOMString>, can_gc: CanGc) {
|
||||
// This should only be called for elements and document fragments when setting the
|
||||
// text content: https://dom.spec.whatwg.org/#set-text-content
|
||||
assert!(matches!(
|
||||
self.type_id(),
|
||||
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..)
|
||||
));
|
||||
let value = value.unwrap_or_default();
|
||||
let node = if value.is_empty() {
|
||||
// Step 1. Let node be null.
|
||||
None
|
||||
} else {
|
||||
// Step 2. If string is not the empty string, then set node to
|
||||
// a new Text node whose data is string and node document is parent’s node document.
|
||||
Some(DomRoot::upcast(
|
||||
self.owner_doc().CreateTextNode(value, can_gc),
|
||||
))
|
||||
};
|
||||
|
||||
// Step 3. Replace all with node within parent.
|
||||
Self::replace_all(node.as_deref(), self, can_gc);
|
||||
}
|
||||
|
||||
pub(crate) fn namespace_to_string(namespace: Namespace) -> Option<DOMString> {
|
||||
match namespace {
|
||||
ns!() => None,
|
||||
|
@ -3372,34 +3396,23 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-textcontent>
|
||||
fn SetTextContent(&self, value: Option<DOMString>, can_gc: CanGc) {
|
||||
let value = value.unwrap_or_default();
|
||||
/// <https://dom.spec.whatwg.org/#set-text-content>
|
||||
fn SetTextContent(&self, value: Option<DOMString>, can_gc: CanGc) -> Fallible<()> {
|
||||
match self.type_id() {
|
||||
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => {
|
||||
// Step 1-2.
|
||||
let node = if value.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(DomRoot::upcast(
|
||||
self.owner_doc().CreateTextNode(value, can_gc),
|
||||
))
|
||||
};
|
||||
|
||||
// Step 3.
|
||||
Node::replace_all(node.as_deref(), self, can_gc);
|
||||
self.set_text_content_for_element(value, can_gc);
|
||||
},
|
||||
NodeTypeId::Attr => {
|
||||
let attr = self.downcast::<Attr>().unwrap();
|
||||
// TODO(#36258): Propagate failure to callers
|
||||
let _ = attr.SetValue(value, can_gc);
|
||||
attr.SetValue(value.unwrap_or_default(), can_gc)?;
|
||||
},
|
||||
NodeTypeId::CharacterData(..) => {
|
||||
let characterdata = self.downcast::<CharacterData>().unwrap();
|
||||
characterdata.SetData(value);
|
||||
characterdata.SetData(value.unwrap_or_default());
|
||||
},
|
||||
NodeTypeId::DocumentType | NodeTypeId::Document(_) => {},
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-node-insertbefore>
|
||||
|
|
|
@ -56,7 +56,7 @@ interface Node : EventTarget {
|
|||
|
||||
[CEReactions, Pure, SetterThrows]
|
||||
attribute DOMString? nodeValue;
|
||||
[CEReactions, Pure]
|
||||
[CEReactions, Pure, SetterThrows]
|
||||
attribute DOMString? textContent;
|
||||
[CEReactions]
|
||||
undefined normalize();
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[block-string-assignment-to-attribute-via-attribute-node.html]
|
||||
[Set script.src via textContent]
|
||||
expected: FAIL
|
||||
|
||||
[Set iframe.srcdoc via textContent]
|
||||
expected: FAIL
|
||||
|
||||
[Set div.onclick via textContent]
|
||||
expected: FAIL
|
|
@ -1,42 +0,0 @@
|
|||
[set-attributes-require-trusted-types-no-default-policy.html]
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=DIV, attrName=onclick with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=g, attrName=ondblclick with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1998/Math/MathML, element=mrow, attrName=onmousedown with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=IFRAME, attrName=srcdoc with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=SCRIPT, attrName=src with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=script, attrName=href with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=script, attrNS=http://www.w3.org/1999/xlink, attrName=href with a plain string]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=DIV, attrName=onclick with a TrustedScript input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=g, attrName=ondblclick with a TrustedScript input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1998/Math/MathML, element=mrow, attrName=onmousedown with a TrustedScript input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=IFRAME, attrName=srcdoc with a TrustedHTML input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/1999/xhtml, element=SCRIPT, attrName=src with a TrustedScriptURL input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=script, attrName=href with a TrustedScriptURL input.]
|
||||
expected: FAIL
|
||||
|
||||
[Node.textContent throws for elementNS=http://www.w3.org/2000/svg, element=script, attrNS=http://www.w3.org/1999/xlink, attrName=href with a TrustedScriptURL input.]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue