Skip to content

rastertops.c: Fail cleanly on truncated raster row read - #107

Merged
tillkamppeter merged 1 commit into
OpenPrinting:masterfrom
RonitMehta08:fix/rastertops-truncated-row-86
Nov 14, 2026
Merged

tillkamppeter merged 1 commit into
OpenPrinting:masterfrom
RonitMehta08:fix/rastertops-truncated-row-86

Conversation

@RonitMehta08

Copy link
Copy Markdown
Contributor

Summary

Fix truncated CUPS Raster row handling in ppd/rastertops.c so short pixel reads fail cleanly instead of compressing uninitialized heap memory into PostScript output.

Root Cause

  1. In write_flate() (ppd/rastertops.c), malloc(header.cupsBytesPerLine) was not checked for NULL, and the return value of cupsRasterReadPixels(ras, pixdata, header.cupsBytesPerLine) was ignored. When a raster stream was truncated after a page header (or mid-page), pixdata remained uninitialized (under ASan, filled with 0xbe) and was compressed straight into the PostScript FlateDecode stream. header.cupsBytesPerLine == 0 could also size stack VLAs to zero.
  2. In ppdFilterRasterToPS(), non-Z_OK returns from write_flate() logged via z_error(), did not call write_end_page(), and fell through to return (0);.

Changes

  • ppd/rastertops.c:
    • Reject header.cupsBytesPerLine == 0 || header.cupsHeight == 0 with Z_DATA_ERROR in write_flate() while keeping stack VLAs non-zero (line_bytes).
    • Check malloc() returns (Z_MEM_ERROR after deflateEnd()) and require cupsRasterReadPixels() to return header.cupsBytesPerLine bytes (free(pixdata), deflateEnd(), return Z_DATA_ERROR).
    • Free pixdata alongside convertedpix on fwrite() failure.
    • In ppdFilterRasterToPS(), propagate status = 1 and call write_end_page(&doc) before breaking out of the page loop when write_flate() returns non-Z_OK.
  • ppd/test_ppd_filter.c:
    • Add regression test T51 constructing a 2-page CUPS Raster document (marker payload on Page 1, truncated 0 pixel bytes after Page 2 header) and verifying ppdFilterRasterToPS() returns non-zero (rc=1) with 0 bytes in Page 2's image stream (using a NUL-safe find_bytes() helper since Page 1 Flate streams contain 0x00 bytes).

Verification

Built and tested on Ubuntu (CFLAGS="-g -O1 -fsanitize=address,undefined"):

  • Standalone reproduction before vs. after patch:
    • Before patch: ppdFilterRasterToPS returned rc=0 and wrote 12 zlib bytes inflating to 0xbe * 64 on Page 2.
    • After patch: ppdFilterRasterToPS returned rc=1 and wrote 0 bytes into Page 2's image stream.
  • Test suite (make check):
    • 13/13 modern test suites (test_ppd_localize, test_ppd_cache, test_ppd_ipp, test_ppd_mark, test_ppd_custom, test_ppd_attr, test_ppd_page, test_ppd_conflicts, test_ppd_emit, test_ppd_filter including T51 PASS (rc=1 page2_stream_bytes=0), test_ppd_generator, test_ppd_load_profile, test_ppd_thread) PASS with ASan + UBSan + LSan enabled (0 failures).
    • 14/14 total suites PASS under ASAN_OPTIONS=detect_leaks=0 make check (testppd has pre-existing leak warnings unrelated to this change).

Fixes #86

@RonitMehta08

Copy link
Copy Markdown
Contributor Author

Hi @tillkamppeter, these are my first PRs to libppd (#107, #108, #109, and #110), so the CI workflows are waiting for approval. Could you approve running them when you get a chance? Thanks!

Comment thread ppd/rastertops.c Fixed
In write_flate(), verify non-zero header dimensions and malloc() results, and require cupsRasterReadPixels() to return header.cupsBytesPerLine bytes before compressing each row. On short reads or OOM, free allocated buffers, call deflateEnd(), and return Z_DATA_ERROR or Z_MEM_ERROR so uninitialized heap bytes are never compressed into PostScript output. Also free pixdata on fwrite() error.

In ppdFilterRasterToPS(), propagate non-Z_OK status after z_error() and write_end_page() rather than returning 0.

Add regression test T51 in ppd/test_ppd_filter.c for a two-page raster stream truncated after page 2's header.

Fixes OpenPrinting#86

Signed-off-by: Ronit Mehta <ronitdmehta@gmail.com>
@RonitMehta08
RonitMehta08 force-pushed the fix/rastertops-truncated-row-86 branch from adba0ba to ec29df9 Compare November 14, 2026 12:33
@tillkamppeter
tillkamppeter merged commit 47aa1b4 into OpenPrinting:master Nov 14, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rastertops: a truncated row leaks residual heap data into PostScript

3 participants