mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
Follow-up to #1404. An inline image whose parameters can't be read and that has no EI after them ran to the end of the stream as a BI op with no data, and those bytes were not counted. It is now skipped like one with an EI, its bytes counted in Parsed::skipped. A stream that ends inside the parameters (BI /W 1) still keeps its BI op.
This commit is contained in:
1 parent
291d738160
commit
d7590ebfbe
2 files changed
+23
-6
No files matched your search
@@ -149,7 +149,7 @@ pub fn parse(data: &[u8]) -> Parsed {
|
||||
}
|
||||
|
||||
/// Read an inline image starting after `BI`: (parameters, data, position after `EI`). `Err` holds
|
||||
/// the position after the `EI` of an image whose parameters can't be read.
|
||||
/// the position after the `EI` (or the end of the stream) of an image whose parameters can't be read.
|
||||
fn inline_image(data: &[u8], pos: usize) -> Result<(Dict, Vec<u8>, usize), usize> {
|
||||
let mut lx = Lexer::new(data, pos);
|
||||
let mut dict = Dict::new();
|
||||
@@ -164,11 +164,12 @@ fn inline_image(data: &[u8], pos: usize) -> Result<(Dict, Vec<u8>, usize), usize
|
||||
_ => None,
|
||||
};
|
||||
let Some((k, v)) = entry else {
|
||||
// Without an `EI` after it, the image runs to the end of the stream, as before.
|
||||
return match end_of_image(data, at) {
|
||||
Some((_, end)) => Err(end),
|
||||
None => Ok((dict, Vec::new(), data.len())),
|
||||
};
|
||||
// A stream that ends inside the parameters is cut short, not unreadable: keep what was read.
|
||||
if at >= data.len() {
|
||||
return Ok((dict, Vec::new(), data.len()));
|
||||
}
|
||||
// Without an `EI` after it, the image runs to the end of the stream.
|
||||
return Err(end_of_image(data, at).map_or(data.len(), |(_, end)| end));
|
||||
};
|
||||
dict.set(k, v);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,22 @@ fn an_unreadable_inline_image_is_skipped_to_its_end() {
|
||||
assert_eq!(control.ops.len(), 6);
|
||||
}
|
||||
|
||||
/// Issue #1318, follow-up: without an `EI`, an unreadable inline image runs to the end of the
|
||||
/// stream, and those bytes are counted. A readable one whose data is cut short is kept, data and
|
||||
/// all, so nothing of it is skipped.
|
||||
#[test]
|
||||
fn an_unreadable_inline_image_without_ei_is_counted() {
|
||||
let p = parse(b"q BI /W 4 H 4 ID aa");
|
||||
let names: Vec<&[u8]> = p.ops.iter().map(|o| o.op.as_slice()).collect();
|
||||
assert_eq!(names, [&b"q"[..]]);
|
||||
assert_eq!(p.skipped, b"BI /W 4 H 4 ID aa".len());
|
||||
let control = parse(b"q BI /W 4 /H 4 ID aa");
|
||||
assert_eq!(control.skipped, 0);
|
||||
let names: Vec<&[u8]> = control.ops.iter().map(|o| o.op.as_slice()).collect();
|
||||
assert_eq!(names, [&b"q"[..], b"BI"]);
|
||||
assert_eq!(control.ops[1].inline.as_ref().map(|(_, data)| data.as_slice()), Some(&b"aa"[..]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matrices_compose_and_invert() {
|
||||
let a = Matrix([2.0, 0.0, 0.0, 3.0, 10.0, 20.0]);
|
||||
|
||||
Reference in new issue
Block a user