mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-07 13:23:22 +00:00
EPS import: bound and charge the filter chain over a pending file
This commit is contained in:
committed by
bflatastic
parent
38bac1114b
commit
bb03081a70
@@ -7,6 +7,8 @@ use super::{
|
||||
|
||||
/// Most bytes one filter or image reads.
|
||||
pub(super) const MAX_DATA: usize = 1 << 28;
|
||||
/// The longest chain of filters over one pending file (real programs stack two or three).
|
||||
const MAX_FILTER_CHAIN: usize = 64;
|
||||
|
||||
/// Most pixels an image may have.
|
||||
const MAX_PIXELS: usize = 1 << 26;
|
||||
@@ -294,7 +296,16 @@ impl Interp<'_> {
|
||||
let pending = match &*f.borrow() {
|
||||
Stream::Current => Some((vec![], None)),
|
||||
Stream::Buf { .. } if running => Some((vec![], Some(f.clone()))),
|
||||
Stream::Pending { chain, from } => Some((chain.clone(), from.clone())),
|
||||
Stream::Pending { chain, from } => {
|
||||
// Cloning the chain copies each filter's delimiter: bound and charge it.
|
||||
if chain.len() >= MAX_FILTER_CHAIN {
|
||||
return Err(PsError::Limit("too many filters over one file"));
|
||||
}
|
||||
let copied = chain.iter().map(|c| c.sub.1.len() + 1).sum::<usize>();
|
||||
self.alloc(copied)?;
|
||||
self.spend((copied / 256) as u64)?;
|
||||
Some((chain.clone(), from.clone()))
|
||||
}
|
||||
Stream::Buf { .. } => None,
|
||||
};
|
||||
match pending {
|
||||
|
||||
@@ -391,6 +391,14 @@ fn work_on_the_longest_dash_pattern_ends_soon() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_chain_of_filters_over_the_program_is_bounded() {
|
||||
let r = read_soon("0 0 10 10 rectfill currentfile 100 { 0 (x) /SubFileDecode filter } repeat pop 20 20 10 10 rectfill");
|
||||
assert!(r.warnings.iter().any(|w| w.contains("too many filters")), "{:?}", r.warnings);
|
||||
let r = read_soon("0 0 10 10 rectfill currentfile 3 { 0 (x) /SubFileDecode filter } repeat pop 20 20 10 10 rectfill");
|
||||
assert!(r.warnings.is_empty(), "{:?}", r.warnings);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn procedures_bind_def_loops_and_dictionaries() {
|
||||
let r = read(
|
||||
|
||||
Reference in New Issue
Block a user