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.
This commit is contained in:
bflatastic 2026-10-12 14:54:46 +07:00
parent 62bf8c862c
commit aca313f10a
1 changed files with 19 additions and 11 deletions

View File

@ -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)));