From aca313f10aa0e460752ae290a1edf08e95afaa2e Mon Sep 17 00:00:00 2001 From: bflatastic Date: Mon, 12 Oct 2026 14:54:46 +0700 Subject: [PATCH] Part of #1264: an image on %_ lines of a .ai file's editing data is read as an image Its samples follow a %%BeginData comment that comes after the %_ prefix, where the lexer took it for a comment later in a line and read the samples as tokens: the rest of the file was misread ("U closes something it didn't open") and the file opened from its PDF part. --- crates/eps/src/import/ai/lex.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/eps/src/import/ai/lex.rs b/crates/eps/src/import/ai/lex.rs index a24c5fef..033e9561 100644 --- a/crates/eps/src/import/ai/lex.rs +++ b/crates/eps/src/import/ai/lex.rs @@ -113,20 +113,24 @@ impl<'a> Lexer<'a> { continue; } if b == b'%' { - if self.at_line_start() { - if self.rest().starts_with(b"%_") { - self.pos += 2; - self.hidden = true; - continue; - } - let line = self.line(); - if let Some(t) = self.special(line) { - return Some(t); - } + let start = self.at_line_start(); + if start && self.rest().starts_with(b"%_") { + self.pos += 2; + self.hidden = true; + continue; + } + // Right after `%_` a section still starts (a hidden image's data, #1264). + let prefixed = self.hidden && self.pos >= 2 && self.src.get(self.pos - 2..self.pos) == Some(b"%_"); + let line = self.line(); + if (start || prefixed) + && let Some(t) = self.special(line) + { + return Some(Token { hidden: prefixed, ..t }); + } + if start { return Some(Token { tok: Tok::Comment(line.get(1..).unwrap_or_default()), hidden: false }); } // A comment later in a line. - self.line(); continue; } let hidden = self.hidden; @@ -310,6 +314,10 @@ mod tests { let toks = all(src); assert!(toks.contains(&t(Tok::Data(b"(%)A"), false)), "{toks:?}"); assert_eq!(toks.last(), Some(&t(Tok::Word(b"XH"), false))); + // #1264: on `%_` lines too, where the samples would otherwise be read as tokens. + let toks = all(b"%_[1 0 0 1 0 0] XI\r%_%%BeginData: 7\rXI\n(U)A%%EndData\r%_XH\ru\r"); + assert!(toks.contains(&t(Tok::Data(b"(U)A"), true)), "{toks:?}"); + assert_eq!(toks.last(), Some(&t(Tok::Word(b"u"), false)), "{toks:?}"); // A section of hex lines is comments. let toks = all(b"%%BeginData: 9 Hex Bytes\r\n%00FF\r\n%%EndData\r\n1\r\n"); assert_eq!(toks.last(), Some(&t(Tok::Num(1.0), false)));