mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Charge and bound EPS image sample planes on import
Squashed from #3821 onto main.
This commit is contained in:
@@ -1093,6 +1093,11 @@ impl Interp<'_> {
|
||||
let row = row_bits.div_ceil(8);
|
||||
// Several sources are read in turn, a row at a time each (zeros past their ends).
|
||||
let sources = if multi { &s.sources[..] } else { s.sources.get(..1).ok_or(PsError::Ps("undefined", "DataSource".into()))? };
|
||||
if sources.len() > n {
|
||||
return ps_err("rangecheck", "DataSource");
|
||||
}
|
||||
let plane = row.checked_mul(s.h).filter(|p| *p <= MAX_DATA).ok_or(PsError::Limit("decoded data is too large"))?;
|
||||
self.alloc(plane.saturating_mul(sources.len()))?;
|
||||
let mut planes = self.read_sources(sources, row * s.h, if multi { row } else { row * s.h })?;
|
||||
for p in &mut planes {
|
||||
p.resize(row * s.h, 0);
|
||||
|
||||
@@ -1131,3 +1131,34 @@ fn search_in_a_loop_runs_out_of_the_budget() {
|
||||
let make = "/h 4194304 string def /n 2097152 string def n 2097152 1 sub 1 put";
|
||||
runs_out_of_budget(&format!("{make} {{ h n search {{ pop pop pop }} {{ pop }} ifelse }} loop"));
|
||||
}
|
||||
|
||||
/// #3568: an image dictionary with more data sources than colour components is a `rangecheck`.
|
||||
#[test]
|
||||
fn an_image_with_more_data_sources_than_components_is_refused() {
|
||||
let sources = "<80> ".repeat(64);
|
||||
let e = import(&eps(&format!(
|
||||
"/DeviceGray setcolorspace << /ImageType 1 /Width 64 /Height 64 /BitsPerComponent 8 /MultipleDataSources true \
|
||||
/ImageMatrix [64 0 0 64 0 0] /DataSource [{sources}] >> image"
|
||||
)))
|
||||
.unwrap_err();
|
||||
assert!(e.contains("rangecheck") && e.contains("DataSource"), "{e}");
|
||||
}
|
||||
|
||||
/// #3568: every data source's plane is charged against the memory budget, not only the RGBA
|
||||
/// output: two large four-source images together go over it.
|
||||
#[test]
|
||||
fn the_planes_of_multi_source_images_are_charged() {
|
||||
let image = "/DeviceCMYK setcolorspace << /ImageType 1 /Width 8192 /Height 8192 /BitsPerComponent 8 \
|
||||
/MultipleDataSources true /ImageMatrix [8192 0 0 8192 0 0] /DataSource [<80> <80> <80> <80>] >> image\n";
|
||||
let r = import(&eps(&image.repeat(2))).unwrap();
|
||||
assert!(r.warnings.iter().any(|w| w.contains("too much memory")), "{:?}", r.warnings);
|
||||
}
|
||||
|
||||
/// #3568: a single sample plane over the data limit is refused.
|
||||
#[test]
|
||||
fn an_oversized_image_plane_is_refused() {
|
||||
let e = import(&eps("/DeviceCMYK setcolorspace << /ImageType 1 /Width 8192 /Height 8192 /BitsPerComponent 16 \
|
||||
/ImageMatrix [8192 0 0 8192 0 0] /DataSource <80> >> image"))
|
||||
.unwrap_err();
|
||||
assert!(e.contains("too large"), "{e}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user