mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 02:16:56 -06:00
PDF: write with craft-libs' krilla, which bounds decoded PNGs (#1240)
* PDF: write with craft-libs' krilla, which bounds decoded PNGs * PDF: pin craft-libs' krilla at 9f75d3dc
This commit is contained in:
Generated
+1
-2
@@ -2613,8 +2613,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "krilla"
|
name = "krilla"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/storytold/craft-libs?rev=9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef#9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef"
|
||||||
checksum = "27da593198b20eeba65caeb73c2bbeec3e53ab08fa549898312ce81c4fce5e33"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
|
|||||||
@@ -128,3 +128,8 @@ codegen-units = 1
|
|||||||
debug = false
|
debug = false
|
||||||
strip = true
|
strip = true
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
# craft-libs' vendored krilla 0.8.2: decoded PNGs are capped at 1 GiB and reserved fallibly, and a
|
||||||
|
# panic while drawing unwinds without aborting.
|
||||||
|
[patch.crates-io]
|
||||||
|
krilla = { git = "https://github.com/storytold/craft-libs", rev = "9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef" }
|
||||||
|
|||||||
@@ -271,3 +271,30 @@ fn sample_files() {
|
|||||||
std::fs::write(format!("{stem}-{}.pdf", i + 1), export_pdf(&d, &[*f], &PdfOptions::default()).unwrap()).unwrap();
|
std::fs::write(format!("{stem}-{}.pdf", i + 1), export_pdf(&d, &[*f], &PdfOptions::default()).unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A tiny PNG whose header claims 30,000 × 30,000 RGBA (3.6 GB decoded) is refused when it is read,
|
||||||
|
/// before anything is decoded: the PDF writer is craft-libs' patched krilla.
|
||||||
|
#[test]
|
||||||
|
fn a_png_that_decodes_too_large_is_refused() {
|
||||||
|
fn chunk(out: &mut Vec<u8>, kind: &[u8; 4], data: &[u8]) {
|
||||||
|
out.extend_from_slice(&u32::try_from(data.len()).unwrap().to_be_bytes());
|
||||||
|
let mut crc = flate2::Crc::new();
|
||||||
|
crc.update(kind);
|
||||||
|
crc.update(data);
|
||||||
|
out.extend_from_slice(kind);
|
||||||
|
out.extend_from_slice(data);
|
||||||
|
out.extend_from_slice(&crc.sum().to_be_bytes());
|
||||||
|
}
|
||||||
|
let mut ihdr = Vec::new();
|
||||||
|
ihdr.extend_from_slice(&30_000u32.to_be_bytes());
|
||||||
|
ihdr.extend_from_slice(&30_000u32.to_be_bytes());
|
||||||
|
ihdr.extend_from_slice(&[8, 6, 0, 0, 0]);
|
||||||
|
let mut z = flate2::write::ZlibEncoder::new(Vec::new(), flate2::Compression::default());
|
||||||
|
std::io::Write::write_all(&mut z, &[0; 64]).unwrap();
|
||||||
|
let mut png = b"\x89PNG\r\n\x1a\n".to_vec();
|
||||||
|
chunk(&mut png, b"IHDR", &ihdr);
|
||||||
|
chunk(&mut png, b"IDAT", &z.finish().unwrap());
|
||||||
|
chunk(&mut png, b"IEND", &[]);
|
||||||
|
const { assert!(krilla::CRAFT_UNWIND_SAFE_DROP) };
|
||||||
|
assert!(krilla::image::Image::from_png(krilla::Data::from(png), true).is_err());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user