Batch fix: EPS: filter keeps its source, so an image's data source isn't skipped twice (#1909)

This commit is contained in:
aiongg
2026-10-24 01:22:55 +00:00
parent fec95ff7ea
commit 69d6e3d28a
2 changed files with 21 additions and 9 deletions
+11 -9
View File
@@ -1271,31 +1271,33 @@ impl Interp {
}
// `source [params] /Name filter`. A SubFileDecode of the current file with a count of
// 0 reads to its end-of-data string: skip that data (an embedded XMP packet, which
// otherwise ran as PostScript). Other filters stand for the file they read.
// otherwise ran as PostScript). Other filters read what their source reads.
"filter" => {
let name = self.pop().key();
if name == "SubFileDecode" {
let mut skipped = false;
let source = if name == "SubFileDecode" && !matches!(self.st.last(), Some(V::Dict(_))) {
let eod = match self.pop() {
V::Str(s) => s.borrow().clone(),
_ => vec![],
};
let count = self.popn();
if let V::File = self.pop()
&& count == 0.0
&& !eod.is_empty()
{
let source = self.pop();
if matches!(source, V::File) && count == 0.0 && !eod.is_empty() {
src.pos = match find_from(src.d, &eod, src.pos) {
Some(p) => p.saturating_add(eod.len()),
None => src.d.len(),
};
skipped = true;
}
source
} else {
if matches!(self.st.last(), Some(V::Dict(_))) {
self.pop();
}
self.pop();
}
self.push(V::File);
self.pop()
};
// Data already stepped over leaves nothing for `image` to skip.
self.push(if skipped { V::Null } else { source });
}
"vmstatus" => {
for _ in 0..3 {
+10
View File
@@ -45,6 +45,16 @@ fn eps_with_aliased_operators_device_queries_and_embedded_data_draws() {
assert!(coverage(&render(&doc), 50, 25, 150, 75) > 4900.0, "drawing after the embedded data");
}
#[test]
fn eps_filter_on_a_string_source_does_not_skip_the_program() {
let square = "1 0 0 setrgbcolor 50 25 moveto 150 25 lineto 150 75 lineto 50 75 lineto closepath fill\n";
let img = "gsave 1 1 8 [1 0 0 1 0 0] (FF) /ASCIIHexDecode filter image grestore\n";
// Images aren't drawn yet, so this parses without `eps`'s nothing-skipped check.
let doc = parse(format!("%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 200 100\n{img}{square}").as_bytes()).unwrap();
assert_eq!(doc.skipped, ["image"]);
assert!(coverage(&render(&doc), 50, 25, 150, 75) > 4900.0, "drawing after an image read from a string");
}
#[test]
fn eps_text_with_bundled_fonts_and_show_variants() {
// Not embedded: drawn with the bundled stand-in, like the same text in a PDF.