mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-02 06:28:49 -06:00
Marking a figure decorative refuses content past the page's decode budget
This commit is contained in:
+12
-1
@@ -23,6 +23,8 @@ pub enum AltError {
|
||||
Untagged,
|
||||
#[error("object {0} is not a figure")]
|
||||
NotAFigure(u32),
|
||||
#[error("the page has more content than can be edited")]
|
||||
TooLarge,
|
||||
#[error("{0}")]
|
||||
Cos(#[from] pdfcraft_cos::CosError),
|
||||
}
|
||||
@@ -375,7 +377,16 @@ fn artifact_marked_content(doc: &mut Document, page: &pdfcraft_model::Page, ids:
|
||||
let mut budget = DecodeBudget::page();
|
||||
for entry in &entries {
|
||||
match &*doc.resolve(entry) {
|
||||
Object::Stream(s) => streams.push(Some((s.clone(), budget.decode(s).unwrap_or_default()))),
|
||||
Object::Stream(s) => {
|
||||
let data = match budget.decode(s) {
|
||||
Ok(data) => data,
|
||||
// Content past the budget may hold more of the figure: editing the rest
|
||||
// would leave that part marked as a figure the tree no longer has.
|
||||
Err(_) if budget.exhausted() => return Err(AltError::TooLarge),
|
||||
Err(_) => Vec::new(),
|
||||
};
|
||||
streams.push(Some((s.clone(), data)));
|
||||
}
|
||||
_ => streams.push(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,3 +1262,19 @@ fn repeated_content_references_share_one_decode_budget() {
|
||||
let data = crate::alt::page_content(&doc, &page);
|
||||
assert!(data.len() <= MAX_PAGE_DECODED + 300, "{} bytes", data.len());
|
||||
}
|
||||
|
||||
/// A figure whose marked content goes on in a stream past the page's decode budget is refused,
|
||||
/// not removed with that content still pointing at it.
|
||||
#[test]
|
||||
fn marking_decorative_refuses_content_past_the_decode_budget() {
|
||||
use pdfcraft_cos::{Dict, Object, ObjRef, Stream};
|
||||
let mut doc = figures_doc();
|
||||
let filler = doc.add(Stream::flate(Dict::new(), &vec![b' '; 1 << 20]));
|
||||
let last = doc.add(Stream::from_raw(Dict::new(), b"/Figure << /MCID 0 >> BDC 0 0 5 5 re f EMC".to_vec()));
|
||||
let mut contents = vec![Object::Ref(ObjRef::new(4, 0))];
|
||||
contents.extend(std::iter::repeat_n(Object::Ref(filler), 256));
|
||||
contents.push(Object::Ref(last));
|
||||
doc.update_dict(ObjRef::new(3, 0), |p| p.set(b"Contents".to_vec(), Object::Array(contents))).unwrap();
|
||||
assert!(mark_decorative(&mut doc, ObjRef::new(7, 0)).is_err());
|
||||
assert_eq!(figures(&doc).len(), 2, "the figure stays");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user