mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Merge pull request #2547 from Silvertree2010/fix/h3260-svg-css-parser-applies-the-secon
Skip whole CSS at-rule blocks in the SVG parser by brace depth
This commit is contained in:
+21
-3
@@ -510,12 +510,30 @@ fn parse_css(css: &str, sheet: &mut StyleSheet) -> Result<(), Error> {
|
||||
let mut rest = css.as_str();
|
||||
while let Some(open) = rest.find('{') {
|
||||
let sel = rest[..open].trim();
|
||||
if sel.starts_with('@') {
|
||||
// Skip the whole at-rule block, matching nested braces by depth.
|
||||
let mut depth = 0usize;
|
||||
let mut end = None;
|
||||
for (i, c) in rest[open..].char_indices() {
|
||||
match c {
|
||||
'{' => depth = depth.saturating_add(1),
|
||||
'}' => {
|
||||
depth = depth.saturating_sub(1);
|
||||
if depth == 0 {
|
||||
end = Some(open + i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let Some(end) = end else { break };
|
||||
rest = &rest[end..];
|
||||
continue;
|
||||
}
|
||||
let Some(close) = rest[open..].find('}') else { break };
|
||||
let body = &rest[open + 1..open + close];
|
||||
rest = &rest[open + close + 1..];
|
||||
if sel.starts_with('@') {
|
||||
continue;
|
||||
}
|
||||
let mut decls = parse_decls(body);
|
||||
sheet.decls = sheet.decls.saturating_add(decls.len());
|
||||
if sheet.decls > MAX_CSS_DECLARATIONS {
|
||||
|
||||
@@ -422,3 +422,15 @@ fn font_size_percentage_resolves_against_the_parent_font_size() {
|
||||
assert!(matches!(shapes[0].2.geom, Geom::Rect { w, .. } if w == expected), "{body}: {:?}", shapes[0].2.geom);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn at_rule_blocks_are_skipped_by_brace_depth() {
|
||||
let mut sheet = StyleSheet::default();
|
||||
parse_css("@media print { .a{fill:#ff0000} .b{fill:#0000ff} } .c{fill:red}", &mut sheet).unwrap();
|
||||
assert_eq!(sheet.rules.len(), 1);
|
||||
assert_eq!(sheet.rules[0].classes, vec!["c".to_string()]);
|
||||
let mut sheet = StyleSheet::default();
|
||||
parse_css("@media x { @supports y { .c{} } .d{} } .e{fill:red}", &mut sheet).unwrap();
|
||||
assert_eq!(sheet.rules.len(), 1);
|
||||
assert_eq!(sheet.rules[0].classes, vec!["e".to_string()]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user