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,
|
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| {
|
let elem = root.upcast::<Node>().child_elements().find(|node| {
|
||||||
node.namespace() == &ns!(svg) && node.local_name() == &local_name!("title")
|
node.namespace() == &ns!(svg) && node.local_name() == &local_name!("title")
|
||||||
});
|
});
|
||||||
|
@ -5036,7 +5036,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
|
||||||
return;
|
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
|
// https://html.spec.whatwg.org/multipage/#dom-document-head
|
||||||
|
|
|
@ -3876,8 +3876,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
||||||
.iter()
|
.iter()
|
||||||
.any(|c| matches!(*c, b'&' | b'\0' | b'<' | b'\r'))
|
.any(|c| matches!(*c, b'&' | b'\0' | b'<' | b'\r'))
|
||||||
{
|
{
|
||||||
Node::SetTextContent(&target, Some(value), can_gc);
|
return Node::SetTextContent(&target, Some(value), can_gc);
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Let fragment be the result of invoking the fragment parsing algorithm steps
|
// 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
|
// https://html.spec.whatwg.org/multipage/#dom-a-text
|
||||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
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
|
// 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);
|
HTMLElement::new(local_name!("summary"), None, &document, None, can_gc);
|
||||||
fallback_summary
|
fallback_summary
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc);
|
.set_text_content_for_element(Some(DEFAULT_SUMMARY.into()), can_gc);
|
||||||
summary
|
summary
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.AppendChild(fallback_summary.upcast::<Node>(), can_gc)
|
.AppendChild(fallback_summary.upcast::<Node>(), can_gc)
|
||||||
|
|
|
@ -2055,7 +2055,7 @@ impl HTMLMediaElement {
|
||||||
*self.media_controls_id.borrow_mut() = Some(id);
|
*self.media_controls_id.borrow_mut() = Some(id);
|
||||||
script
|
script
|
||||||
.upcast::<Node>()
|
.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
|
if let Err(e) = shadow_root
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.AppendChild(script.upcast::<Node>(), can_gc)
|
.AppendChild(script.upcast::<Node>(), can_gc)
|
||||||
|
@ -2074,7 +2074,7 @@ impl HTMLMediaElement {
|
||||||
);
|
);
|
||||||
style
|
style
|
||||||
.upcast::<Node>()
|
.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
|
if let Err(e) = shadow_root
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
|
|
|
@ -176,7 +176,9 @@ impl HTMLOptionElementMethods<crate::DomTypeHolder> for HTMLOptionElement {
|
||||||
let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap();
|
let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap();
|
||||||
|
|
||||||
if !text.is_empty() {
|
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 {
|
if let Some(val) = value {
|
||||||
|
@ -224,7 +226,8 @@ impl HTMLOptionElementMethods<crate::DomTypeHolder> for HTMLOptionElement {
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-option-text>
|
/// <https://html.spec.whatwg.org/multipage/#dom-option-text>
|
||||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
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>
|
/// <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.
|
// Step 2: Set this's script text value to value.
|
||||||
*self.script_text.borrow_mut() = value.clone();
|
*self.script_text.borrow_mut() = value.clone();
|
||||||
// Step 3: Run set text content with this and value.
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ impl HTMLSelectElement {
|
||||||
);
|
);
|
||||||
chevron_container
|
chevron_container
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.SetTextContent(Some("▾".into()), can_gc);
|
.set_text_content_for_element(Some("▾".into()), can_gc);
|
||||||
select_box
|
select_box
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.AppendChild(chevron_container.upcast::<Node>(), can_gc)
|
.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
|
// https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue
|
||||||
fn SetDefaultValue(&self, value: DOMString, can_gc: CanGc) {
|
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
|
// 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
|
// 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 js::rust::HandleObject;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementMethods;
|
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::inheritance::Castable;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
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
|
// https://html.spec.whatwg.org/multipage/#dom-title-text
|
||||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
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)
|
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> {
|
pub(crate) fn namespace_to_string(namespace: Namespace) -> Option<DOMString> {
|
||||||
match namespace {
|
match namespace {
|
||||||
ns!() => None,
|
ns!() => None,
|
||||||
|
@ -3372,34 +3396,23 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://dom.spec.whatwg.org/#dom-node-textcontent>
|
/// <https://dom.spec.whatwg.org/#set-text-content>
|
||||||
fn SetTextContent(&self, value: Option<DOMString>, can_gc: CanGc) {
|
fn SetTextContent(&self, value: Option<DOMString>, can_gc: CanGc) -> Fallible<()> {
|
||||||
let value = value.unwrap_or_default();
|
|
||||||
match self.type_id() {
|
match self.type_id() {
|
||||||
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => {
|
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => {
|
||||||
// Step 1-2.
|
self.set_text_content_for_element(value, can_gc);
|
||||||
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);
|
|
||||||
},
|
},
|
||||||
NodeTypeId::Attr => {
|
NodeTypeId::Attr => {
|
||||||
let attr = self.downcast::<Attr>().unwrap();
|
let attr = self.downcast::<Attr>().unwrap();
|
||||||
// TODO(#36258): Propagate failure to callers
|
attr.SetValue(value.unwrap_or_default(), can_gc)?;
|
||||||
let _ = attr.SetValue(value, can_gc);
|
|
||||||
},
|
},
|
||||||
NodeTypeId::CharacterData(..) => {
|
NodeTypeId::CharacterData(..) => {
|
||||||
let characterdata = self.downcast::<CharacterData>().unwrap();
|
let characterdata = self.downcast::<CharacterData>().unwrap();
|
||||||
characterdata.SetData(value);
|
characterdata.SetData(value.unwrap_or_default());
|
||||||
},
|
},
|
||||||
NodeTypeId::DocumentType | NodeTypeId::Document(_) => {},
|
NodeTypeId::DocumentType | NodeTypeId::Document(_) => {},
|
||||||
}
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://dom.spec.whatwg.org/#dom-node-insertbefore>
|
/// <https://dom.spec.whatwg.org/#dom-node-insertbefore>
|
||||||
|
|
|
@ -56,7 +56,7 @@ interface Node : EventTarget {
|
||||||
|
|
||||||
[CEReactions, Pure, SetterThrows]
|
[CEReactions, Pure, SetterThrows]
|
||||||
attribute DOMString? nodeValue;
|
attribute DOMString? nodeValue;
|
||||||
[CEReactions, Pure]
|
[CEReactions, Pure, SetterThrows]
|
||||||
attribute DOMString? textContent;
|
attribute DOMString? textContent;
|
||||||
[CEReactions]
|
[CEReactions]
|
||||||
undefined normalize();
|
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