Merge pull request #6431 from ruchirguitar/test/verify-stale-high-issues

Regression tests for #3566 (SVG entities in element content) and #3084 / #2096 (Export for Screens JPGs)
This commit is contained in:
BFlat
2026-11-10 21:52:51 +07:00
committed by GitHub
2 changed files with 54 additions and 0 deletions
+31
View File
@@ -914,3 +914,34 @@ fn read_path_for_a_named_importer_stops_at_the_limit() {
assert!(e.to_string().contains("larger than") && e.to_string().contains("drawing.tuv"), "{e}");
let _ = std::fs::remove_dir_all(&dir);
}
/// #3084, #2096: Export for Screens writes JPGs a strict reader opens, in every colour model and at
/// the qualities and scales the reports used. A four-component (CMYK) file has no JFIF segment,
/// which describes only one- and three-component images (#3140); RGB and gray files keep it.
#[test]
fn export_for_screens_jpgs_open_in_every_colour_model() {
let mut s = session(100.0, 80.0, 1);
s.execute("paint.setFill", &json!({"color": "#cc3300"})).unwrap();
s.execute("shape.rectangle", &json!({"x": 10, "y": 10, "width": 60, "height": 40})).unwrap();
for (model, components) in [("rgb", 3), ("cmyk", 4), ("gray", 1)] {
for quality in [100, 80, 50] {
let r = s
.execute(
"document.exportForScreens",
&json!({"formats": [{"format": "jpg"}, {"format": "jpg", "scale": 2}], "settings": {"jpg": {"colorModel": model, "quality": quality}}}),
)
.unwrap();
let files = r["files"].as_array().unwrap();
assert_eq!(files.len(), 2, "{model} {quality}: {r}");
for (f, width) in files.iter().zip([100, 200]) {
let bytes = b64(f);
let what = format!("{model} q{quality} {}", f["name"]);
assert_eq!(bytes.get(..2), Some(&[0xFF, 0xD8][..]), "{what}: starts with SOI");
let jfif = bytes.get(2..4) == Some(&[0xFF, 0xE0][..]);
assert_eq!(jfif, components != 4, "{what}: JFIF only on one- and three-component files");
let image = image::load_from_memory(&bytes).unwrap_or_else(|e| panic!("{what}: {e}"));
assert_eq!(image.width(), width, "{what}");
}
}
}
}
+23
View File
@@ -645,3 +645,26 @@ fn nested_svg_images_past_count_cap_are_left_out() {
let (_d, warnings) = import_with(&svg, &ImportOptions::default()).unwrap();
assert!(warnings.iter().any(|w| w.contains(&format!("more than {MAX_NESTED_SVG_IMAGES} nested SVG images"))));
}
/// #3566: entity references in element content count toward the expansion limit, as in
/// attributes. A 10 KB entity, a second entity that refers to it 250 times, and eight references
/// to the second inside `<desc>` would expand to about 20 MB from a file of a few KB: the import
/// refuses it before the XML reader expands anything. The namespace entities drawing apps write
/// (`&ns_svg;`) still import.
#[test]
fn entities_repeated_in_element_content_are_refused_and_namespace_entities_import() {
let bomb = format!(
r#"<!DOCTYPE svg [<!ENTITY a "{}"><!ENTITY b "{}">]><svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><desc>{}</desc><rect width="5" height="5"/></svg>"#,
"x".repeat(10_000),
"&a;".repeat(250),
"&b;".repeat(8)
);
assert!(bomb.len() < 20_000, "{} bytes", bomb.len());
match import_with(&bomb, &ImportOptions::default()) {
Err(SvgError::Parse(e)) => assert!(e.contains("entities"), "{e}"),
other => panic!("refused as a parse error, not {:?}", other.map(|(_, w)| w)),
}
let ns = r#"<?xml version="1.0"?><!DOCTYPE svg [<!ENTITY ns_svg "http://www.w3.org/2000/svg">]><svg xmlns="&ns_svg;" width="10" height="10"><rect width="5" height="5"/></svg>"#;
let (d, _) = import_with(ns, &ImportOptions::default()).unwrap();
assert_eq!(art(&d).len(), 1, "the rectangle");
}