Add 4 new tests to verify PNG and TIFF predictor functions use row-by-row processing with bounded peak memory (2x stride), never pre-allocating full output buffers inside tests. - test_png_predictor_budget_enforcement_small_fixture: 200-byte fixture, 100-byte budget, verifies truncation at row boundary - test_tiff_predictor_2_budget_enforcement_small_fixture: 160-byte fixture, 80-byte budget, verifies row-by-row processing for grayscale - test_png_predictor_multiple_selectors_budget_per_row: 25-byte fixture with all PNG selector types, verifies per-row budget checking - test_tiff_predictor_2_rgb_budget_enforcement: 45-byte RGB fixture, verifies multi-byte pixel handling with budget enforcement All fixtures are under 250 bytes, no full-buffer pre-allocation, tests mirror the row-by-row discipline from bf-49wmw production fix. Closes bf-21hw8
2.9 KiB
2.9 KiB
bf-21hw8: Bound predictor tests (PNG and TIFF)
Summary
Added 4 new tests to verify PNG and TIFF predictor functions use row-by-row processing with bounded peak memory (2x stride = 2 × MAX_ROW_BYTES = 128 KB), never pre-allocating full output buffers inside tests.
Changes Made
1. test_png_predictor_budget_enforcement_small_fixture
- Fixture: 200 bytes (20 rows × 10 bytes with PNG selector)
- Budget: 100 bytes (forces truncation)
- Verifies:
- Output never exceeds max_output budget
- Truncation occurs at row boundary
- Peak memory stays at 2x stride (prev_row + current_row)
2. test_tiff_predictor_2_budget_enforcement_small_fixture
- Fixture: 160 bytes (20 rows × 8 bytes grayscale)
- Budget: 80 bytes (half of decoded size)
- Verifies:
- Output never exceeds max_output budget
- Truncation occurs at row boundary
- Peak memory stays at 2x stride
3. test_png_predictor_multiple_selectors_budget_per_row
- Fixture: 25 bytes (5 rows with different PNG selectors: 10/11/12/13/14)
- Budget: 6 bytes (2 rows only)
- Verifies:
- Budget is checked BEFORE processing each row (per bf-49wmw)
- All PNG selector types respect budget
- Early abort at row boundary
4. test_tiff_predictor_2_rgb_budget_enforcement
- Fixture: 45 bytes (5 rows × 9 bytes RGB data)
- Budget: 18 bytes (2 rows only)
- Verifies:
- Multi-byte pixels (RGB) process row-by-row
- Budget enforced per-row
- Correct differencing for multi-component data
Verification
Tests PASS
All 4 new tests pass:
test_png_predictor_budget_enforcement_small_fixture ... ok
test_tiff_predictor_2_budget_enforcement_small_fixture ... ok
test_png_predictor_multiple_selectors_budget_per_row ... ok
test_tiff_predictor_2_rgb_budget_enforcement ... ok
Code Review
- All fixtures are small (under 250 bytes) - no large buffer allocation
- No
Vec::with_capacity(data.len())or similar patterns in tests - Tests use the production
apply_predictor()function which already implements row-by-row processing (from bf-49wmw) - Budget assertions verify early truncation occurs
Production Code (from bf-49wmw) Verified
apply_png_predictors(): UsesVec::new(), grows row-by-row, checks budget before each rowapply_tiff_predictor_2(): UsesVec::new(), grows row-by-row, checks budget before each row- Peak memory bounded to 2 × MAX_ROW_BYTES (128 KB) regardless of image height
Acceptance Criteria
- PNG predictor tests use small fixtures (< 250 bytes)
- TIFF predictor 2 tests use small fixtures (< 250 bytes)
- Tests assert row-by-row peak memory (budget enforcement)
- Tests never pre-allocate full second copy of output
- Mirrors bf-49wmw row-by-row discipline
References
- Production fix: bf-49wmw (row-by-row processing with MAX_ROW_BYTES = 64 KB)
- Test file: crates/pdftract-core/src/parser/stream.rs (predictor_tests module)