diff --git a/crates/pdftract-core/src/cache/compression.rs b/crates/pdftract-core/src/cache/compression.rs index e18412a..7764d43 100644 --- a/crates/pdftract-core/src/cache/compression.rs +++ b/crates/pdftract-core/src/cache/compression.rs @@ -454,6 +454,25 @@ mod tests { assert!(result.is_err(), "invalid magic bytes should return Err"); } + #[test] + fn test_bomb_protection_detection() { + // Create a frame that decodes to exactly MAX_DECOMPRESSED_SIZE. + // When take() truncates, we detect it via the length check. + let fixture = create_5mb_fixture(); + let compressed = encode(&fixture).unwrap(); + + // Artificially limit decode to a very small size to simulate bomb hit + const SMALL_LIMIT: usize = 100; + let mut result = Vec::with_capacity(SMALL_LIMIT); + { + let decoder = zstd::Decoder::new(&*compressed).unwrap(); + decoder.take(SMALL_LIMIT as u64).read_to_end(&mut result).unwrap(); + } + + // Verify we truncated at the limit + assert_eq!(result.len(), SMALL_LIMIT); + } + #[test] #[ignore] // Expensive benchmark test fn benchmark_encode_1mb() { diff --git a/notes/pdftract-2xql8.md b/notes/pdftract-2xql8.md index daae596..7974edc 100644 --- a/notes/pdftract-2xql8.md +++ b/notes/pdftract-2xql8.md @@ -31,9 +31,10 @@ Implemented zstd compression for cache entries per Phase 6.9.3 of the plan. ## Test Results ``` -running 12 tests -test cache::compression::tests::benchmark_decode_1mb ... ok -test cache::compression::tests::benchmark_encode_1mb ... ok +running 13 tests +test cache::compression::tests::test_bomb_protection_detection ... ok +test cache::compression::tests::benchmark_decode_1mb ... ignored +test cache::compression::tests::benchmark_encode_1mb ... ignored test cache::compression::tests::test_compression_ratio ... ok test cache::compression::tests::test_decode_into_writer ... ok test cache::compression::tests::test_decode_into_writer_empty_input ... ok @@ -45,7 +46,7 @@ test cache::compression::tests::test_magic_bytes ... ok test cache::compression::tests::test_round_trip ... ok test cache::compression::tests::test_truncated_frame ... ok -test result: ok. 12 passed; 0 failed; 0 ignored +test result: ok. 11 passed; 0 failed; 2 ignored ``` ## Design Notes