Fix bad serialization, start on allowed_css_protocols

This commit is contained in:
Tyler Hallada 2020-05-12 23:27:41 -04:00
parent 6b9734143c
commit 8315b15985
4 changed files with 60 additions and 5 deletions

View File

@ -14,6 +14,7 @@ lazy_static! {
allowed_protocols: HashMap::new(), allowed_protocols: HashMap::new(),
allowed_css_at_rules: HashSet::new(), allowed_css_at_rules: HashSet::new(),
allowed_css_properties: HashSet::new(), allowed_css_properties: HashSet::new(),
allowed_css_protocols: HashSet::new(),
allow_css_comments: false, allow_css_comments: false,
remove_contents_when_unwrapped: hashset! { remove_contents_when_unwrapped: hashset! {
local_name!("iframe"), local_name!("iframe"),

View File

@ -843,6 +843,11 @@ lazy_static! {
css_property!("writing-mode"), css_property!("writing-mode"),
css_property!("z-index"), css_property!("z-index"),
}); });
config.allowed_css_protocols.extend(hashset! {
Protocol::Scheme("http"),
Protocol::Scheme("https"),
Protocol::Relative,
});
config config
}; };
} }

View File

@ -266,10 +266,7 @@ pub fn serialize_css_rules(rules: &[CssRule]) -> String {
match rule { match rule {
CssRule::StyleRule(style_rule) => { CssRule::StyleRule(style_rule) => {
serialized_rules += &style_rule.selectors; serialized_rules += &style_rule.selectors;
serialized_rules += "{"; serialized_rules += "{ ";
for declaration in style_rule.declarations.iter() {
serialized_rules += &declaration.to_string();
}
serialized_rules += &serialize_css_declarations(&style_rule.declarations); serialized_rules += &serialize_css_declarations(&style_rule.declarations);
serialized_rules += " }"; serialized_rules += " }";
} }
@ -278,7 +275,7 @@ pub fn serialize_css_rules(rules: &[CssRule]) -> String {
serialized_rules += &at_rule.name; serialized_rules += &at_rule.name;
serialized_rules += &at_rule.prelude; serialized_rules += &at_rule.prelude;
if let Some(block) = &at_rule.block { if let Some(block) = &at_rule.block {
serialized_rules += "{"; serialized_rules += "{ ";
serialized_rules += &serialize_css_rules(&block); serialized_rules += &serialize_css_rules(&block);
serialized_rules += " }"; serialized_rules += " }";
} else { } else {

View File

@ -31,6 +31,7 @@ pub struct SanitizerConfig {
pub allowed_protocols: HashMap<LocalName, HashMap<LocalName, HashSet<Protocol<'static>>>>, pub allowed_protocols: HashMap<LocalName, HashMap<LocalName, HashSet<Protocol<'static>>>>,
pub allowed_css_at_rules: HashSet<CssAtRule>, pub allowed_css_at_rules: HashSet<CssAtRule>,
pub allowed_css_properties: HashSet<CssProperty>, pub allowed_css_properties: HashSet<CssProperty>,
pub allowed_css_protocols: HashSet<Protocol<'static>>,
pub allow_css_comments: bool, pub allow_css_comments: bool,
pub remove_contents_when_unwrapped: HashSet<LocalName>, pub remove_contents_when_unwrapped: HashSet<LocalName>,
pub whitespace_around_unwrapped_content: HashMap<LocalName, ContentWhitespace<'static>>, pub whitespace_around_unwrapped_content: HashMap<LocalName, ContentWhitespace<'static>>,
@ -437,6 +438,7 @@ mod test {
allowed_protocols: HashMap::new(), allowed_protocols: HashMap::new(),
allowed_css_at_rules: HashSet::new(), allowed_css_at_rules: HashSet::new(),
allowed_css_properties: HashSet::new(), allowed_css_properties: HashSet::new(),
allowed_css_protocols: HashSet::new(),
allow_css_comments: false, allow_css_comments: false,
remove_contents_when_unwrapped: HashSet::new(), remove_contents_when_unwrapped: HashSet::new(),
whitespace_around_unwrapped_content: HashMap::new(), whitespace_around_unwrapped_content: HashMap::new(),
@ -795,6 +797,56 @@ mod test {
); );
} }
#[test]
fn sanitize_stylesheet_css() {
let mut sanitize_css_config = EMPTY_CONFIG.clone();
sanitize_css_config
.allowed_elements
.extend(vec![local_name!("html"), local_name!("style")]);
sanitize_css_config
.allowed_css_properties
.extend(vec![css_property!("margin"), css_property!("color")]);
let sanitizer = Sanitizer::new(&sanitize_css_config, vec![]);
let mut mock_data =
MockRead::new("<style>div { margin: 10px; padding: 10px; color: red; }</style>");
let mut output = vec![];
sanitizer
.sanitize_fragment(&mut mock_data, &mut output)
.unwrap();
assert_eq!(
str::from_utf8(&output).unwrap(),
"<html><style>div { margin: 10px; color: red; }</style></html>"
);
}
#[test]
fn sanitize_css_protocols() {
let mut sanitize_css_config = EMPTY_CONFIG.clone();
sanitize_css_config
.allowed_elements
.extend(vec![local_name!("html"), local_name!("style")]);
sanitize_css_config.allowed_css_properties.extend(vec![
css_property!("background-image"),
css_property!("content"),
]);
sanitize_css_config
.allowed_css_protocols
.extend(vec![Protocol::Scheme("https")]);
let sanitizer = Sanitizer::new(&sanitize_css_config, vec![]);
let mut mock_data = MockRead::new(
"<style>div { background-image: url(https://example.com); \
content: url(icon.jpg); }</style>",
);
let mut output = vec![];
sanitizer
.sanitize_fragment(&mut mock_data, &mut output)
.unwrap();
assert_eq!(
str::from_utf8(&output).unwrap(),
"<html><style>div { background-image: url(https://example.com) }</style></html>"
);
}
#[test] #[test]
fn remove_doctype() { fn remove_doctype() {
let mut disallow_doctype_config = EMPTY_CONFIG.clone(); let mut disallow_doctype_config = EMPTY_CONFIG.clone();