mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add CSP check for inline style attribute (#36923)
To be able to abort the update, extract the functionality into a separate method. Otherwise, we don't run the `node.rev_version` at the end, which according to the comment is probably important. Not all `style-src` tests pass and I don't fully understand why yet, but I presume it has to do with some special quirks of stylesheets that other CSP checks don't have. All `style-src-attr-elem` tests pass though. Part of #4577 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
565e16178f
commit
d0de4e64d2
10 changed files with 124 additions and 79 deletions
|
@ -12,6 +12,7 @@ use std::rc::Rc;
|
|||
use std::str::FromStr;
|
||||
use std::{fmt, mem};
|
||||
|
||||
use content_security_policy as csp;
|
||||
use cssparser::match_ignore_ascii_case;
|
||||
use devtools_traits::AttrInfo;
|
||||
use dom_struct::dom_struct;
|
||||
|
@ -2120,6 +2121,59 @@ impl Element {
|
|||
node.owner_doc().element_attr_will_change(self, attr);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-style-attribute>
|
||||
fn update_style_attribute(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||
let doc = self.upcast::<Node>().owner_doc();
|
||||
// Modifying the `style` attribute might change style.
|
||||
*self.style_attribute.borrow_mut() = match mutation {
|
||||
AttributeMutation::Set(..) => {
|
||||
// This is the fast path we use from
|
||||
// CSSStyleDeclaration.
|
||||
//
|
||||
// Juggle a bit to keep the borrow checker happy
|
||||
// while avoiding the extra clone.
|
||||
let is_declaration = matches!(*attr.value(), AttrValue::Declaration(..));
|
||||
|
||||
let block = if is_declaration {
|
||||
let mut value = AttrValue::String(String::new());
|
||||
attr.swap_value(&mut value);
|
||||
let (serialization, block) = match value {
|
||||
AttrValue::Declaration(s, b) => (s, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let mut value = AttrValue::String(serialization);
|
||||
attr.swap_value(&mut value);
|
||||
block
|
||||
} else {
|
||||
let win = self.owner_window();
|
||||
let source = &**attr.value();
|
||||
// However, if the Should element's inline behavior be blocked by
|
||||
// Content Security Policy? algorithm returns "Blocked" when executed
|
||||
// upon the attribute's element, "style attribute", and the attribute's value,
|
||||
// then the style rules defined in the attribute's value must not be applied to the element. [CSP]
|
||||
if doc.should_elements_inline_type_behavior_be_blocked(
|
||||
self,
|
||||
csp::InlineCheckType::StyleAttribute,
|
||||
source,
|
||||
) == csp::CheckResult::Blocked
|
||||
{
|
||||
return;
|
||||
}
|
||||
Arc::new(doc.style_shared_lock().wrap(parse_style_attribute(
|
||||
source,
|
||||
&UrlExtraData(doc.base_url().get_arc()),
|
||||
win.css_error_reporter(),
|
||||
doc.quirks_mode(),
|
||||
CssRuleType::Style,
|
||||
)))
|
||||
};
|
||||
|
||||
Some(block)
|
||||
},
|
||||
AttributeMutation::Removed => None,
|
||||
};
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#insert-adjacent
|
||||
pub(crate) fn insert_adjacent(
|
||||
&self,
|
||||
|
@ -3800,43 +3854,7 @@ impl VirtualMethods for Element {
|
|||
&local_name!("tabindex") | &local_name!("draggable") | &local_name!("hidden") => {
|
||||
self.update_sequentially_focusable_status(can_gc)
|
||||
},
|
||||
&local_name!("style") => {
|
||||
// Modifying the `style` attribute might change style.
|
||||
*self.style_attribute.borrow_mut() = match mutation {
|
||||
AttributeMutation::Set(..) => {
|
||||
// This is the fast path we use from
|
||||
// CSSStyleDeclaration.
|
||||
//
|
||||
// Juggle a bit to keep the borrow checker happy
|
||||
// while avoiding the extra clone.
|
||||
let is_declaration = matches!(*attr.value(), AttrValue::Declaration(..));
|
||||
|
||||
let block = if is_declaration {
|
||||
let mut value = AttrValue::String(String::new());
|
||||
attr.swap_value(&mut value);
|
||||
let (serialization, block) = match value {
|
||||
AttrValue::Declaration(s, b) => (s, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let mut value = AttrValue::String(serialization);
|
||||
attr.swap_value(&mut value);
|
||||
block
|
||||
} else {
|
||||
let win = self.owner_window();
|
||||
Arc::new(doc.style_shared_lock().wrap(parse_style_attribute(
|
||||
&attr.value(),
|
||||
&UrlExtraData(doc.base_url().get_arc()),
|
||||
win.css_error_reporter(),
|
||||
doc.quirks_mode(),
|
||||
CssRuleType::Style,
|
||||
)))
|
||||
};
|
||||
|
||||
Some(block)
|
||||
},
|
||||
AttributeMutation::Removed => None,
|
||||
};
|
||||
},
|
||||
&local_name!("style") => self.update_style_attribute(attr, mutation),
|
||||
&local_name!("id") => {
|
||||
*self.id_attribute.borrow_mut() = mutation.new_value(attr).and_then(|value| {
|
||||
let value = value.as_atom();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue