mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
Merge PR #3668: Accept a delimiter after EI when ending an inline image
vendor/hayro-syntax/src/content/mod.rs tests: kept #2483's test and this PR's three.
This commit is contained in:
+43
-3
@@ -40,7 +40,7 @@ use crate::object::name::{Name, skip_name_like};
|
||||
use crate::object::{Array, Null, Number, Object, Stream};
|
||||
use crate::reader::Reader;
|
||||
use crate::reader::{Readable, ReaderContext, ReaderExt, Skippable};
|
||||
use crate::trivia::{Comment, is_white_space_character};
|
||||
use crate::trivia::{Comment, is_regular_character, is_white_space_character};
|
||||
use crate::util::find_needle;
|
||||
use core::array;
|
||||
use core::fmt::{Debug, Formatter};
|
||||
@@ -246,11 +246,12 @@ impl<'a> UntypedIter<'a> {
|
||||
self.reader.read_bytes(pos)?;
|
||||
|
||||
if self.reader.peek_bytes(2) == Some(b"EI") {
|
||||
// If the following character is not a whitespace character, then we are in a ASCII-85 stream.
|
||||
// If the following character is a regular character, then the token
|
||||
// is not `EI` (white space and delimiters both end it).
|
||||
if self
|
||||
.reader
|
||||
.peek_bytes(3)
|
||||
.is_some_and(|b| !is_white_space_character(b[2]))
|
||||
.is_some_and(|b| is_regular_character(b[2]))
|
||||
{
|
||||
self.reader.read_bytes(3)?;
|
||||
|
||||
@@ -896,6 +897,45 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_image_ei_may_be_followed_by_a_delimiter() {
|
||||
let mut image = b"BI /W 16 /H 4 /BPC 8 /CS /G ID ".to_vec();
|
||||
image.extend([0x80; 64]);
|
||||
image.extend(b"\nEI");
|
||||
let tail = b" Q BT /F1 24 Tf 72 200 Td (AFTER) Tj ET";
|
||||
let ops = |suffix: &[u8]| {
|
||||
let mut data = image.clone();
|
||||
data.extend(suffix);
|
||||
data.extend(tail);
|
||||
operators(&data)
|
||||
};
|
||||
let control = ops(b"");
|
||||
assert_eq!(control.len(), 7);
|
||||
assert_eq!(ops(b"%c\n"), control);
|
||||
assert_eq!(ops(b"[] 0 d"), [&control[..1], &[b"d".to_vec()], &control[1..]].concat());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_image_ei_followed_by_a_regular_character_is_not_the_end() {
|
||||
let data = b"BI /W 1 /H 1 /BPC 8 /CS /G ID \x80 EIQ \x81 EI Q BT (a) Tj ET";
|
||||
// `EIQ` is one token and stays part of the image data.
|
||||
let expected: Vec<Vec<u8>> =
|
||||
["BI", "Q", "BT", "Tj", "ET"].iter().map(|s| s.as_bytes().to_vec()).collect();
|
||||
assert_eq!(operators(data), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ascii85_inline_image_data_may_contain_ei_before_a_delimiter() {
|
||||
for glue in [&b"EI["[..], b"EI/", b"EI%", b"EI(", b"EI<"] {
|
||||
let mut data = b"BI /W 4 /H 4 /BPC 8 /CS /G /F /A85 ID 9jqo^".to_vec();
|
||||
data.extend(glue);
|
||||
data.extend(b"87cURD]i,\"Ebo80~>EI Q BT /F1 12 Tf (AFTER) Tj ET");
|
||||
let expected: Vec<Vec<u8>> =
|
||||
["BI", "Q", "BT", "Tf", "Tj", "ET"].iter().map(|s| s.as_bytes().to_vec()).collect();
|
||||
assert_eq!(operators(&data), expected, "{}", String::from_utf8_lossy(glue));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tokenizer_interface_preserves_every_byte_boundary() {
|
||||
let data = b"% comment\n1 -2.5 /Name /A#20B (a\\(b\\) \\101) <4869> [1 2] << /Key (value) >> [(a) 1] TJ BI /W 1 /H 1 /BPC 8 /CS /DeviceGray ID \x00 EI q Q";
|
||||
|
||||
Reference in New Issue
Block a user