Skip to content

Commit

Permalink
Move more of the page header checks to the cups_raster_update functio…
Browse files Browse the repository at this point in the history
…n and add error messages for all detected issues.
  • Loading branch information
michaelrsweet committed Oct 21, 2024
1 parent fcb0bc8 commit d2a3eff
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ libcups v3.0rc3 (YYYY-MM-DD)
- Updated `cupsSaveCredentials` to validate the input credentials, support
using a saved private key from `cupsCreateCertificateRequest`, and support
credential removal as documented.
- Updated the raster functions to report more issues via
`cupsRasterGetErrorString`.


libcups v3.0rc2 (2024-10-15)
Expand Down
82 changes: 71 additions & 11 deletions cups/raster-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
#include "debug-internal.h"


//
// Limits...
//

#define _CUPS_MAX_BYTES_PER_LINE (16 * 1024 * 1024)
#define _CUPS_MAX_BITS_PER_COLOR 16
#define _CUPS_MAX_BITS_PER_PIXEL 240


//
// Private structures...
//
Expand Down Expand Up @@ -838,7 +847,7 @@ cupsRasterReadHeader(

memcpy(h, &r->header, sizeof(cups_page_header_t));

return (r->header.cupsBitsPerPixel > 0 && r->header.cupsBitsPerPixel <= 240 && r->header.cupsBitsPerColor > 0 && r->header.cupsBitsPerColor <= 16 && r->header.cupsBytesPerLine > 0 && r->header.cupsBytesPerLine <= 0x7fffffff && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0);
return (0);
}


Expand Down Expand Up @@ -1540,6 +1549,9 @@ cups_raster_read(cups_raster_t *r, // I - Raster stream
static bool // O - `true` on success, `false` on failure
cups_raster_update(cups_raster_t *r) // I - Raster stream
{
bool ret = true; // Return value


if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 ||
r->header.cupsNumColors == 0)
{
Expand Down Expand Up @@ -1617,7 +1629,11 @@ cups_raster_update(cups_raster_t *r) // I - Raster stream

default :
// Unknown color space
return (false);
_cupsRasterAddError("Unknown color space in page header.");

r->header.cupsNumColors = 0;
ret = false;
break;
}

DEBUG_printf("4cups_raster_update: cupsNumColors=%u", r->header.cupsNumColors);
Expand Down Expand Up @@ -1649,28 +1665,72 @@ cups_raster_update(cups_raster_t *r) // I - Raster stream

DEBUG_printf("4cups_raster_update: remaining=%u", r->remaining);

// Validate the page header...
if (r->header.cupsBytesPerLine == 0)
{
_cupsRasterAddError("Invalid raster line length 0.");
ret = false;
}
else if (r->header.cupsBytesPerLine > _CUPS_MAX_BYTES_PER_LINE)
{
_cupsRasterAddError("Raster line length %u is greater than %d bytes.", r->header.cupsBytesPerLine, _CUPS_MAX_BYTES_PER_LINE);
ret = false;
}
else if ((r->header.cupsBytesPerLine % r->bpp) != 0)
{
_cupsRasterAddError("Raster line length %u is not a multiple of the pixel size (%d).", r->header.cupsBytesPerLine, r->bpp);
ret = false;
}

if (r->header.cupsBitsPerColor == 0 || r->header.cupsBitsPerColor > _CUPS_MAX_BITS_PER_COLOR)
{
_cupsRasterAddError("Invalid bits per color %u.", r->header.cupsBitsPerColor);
ret = false;
}

if (r->header.cupsBitsPerPixel == 0 || r->header.cupsBitsPerPixel > _CUPS_MAX_BITS_PER_PIXEL)
{
_cupsRasterAddError("Invalid bits per pixel %u.", r->header.cupsBitsPerPixel);
ret = false;
}

if (r->header.cupsWidth == 0)
{
_cupsRasterAddError("Invalid raster width 0.");
ret = false;
}

if (r->header.cupsHeight == 0)
{
_cupsRasterAddError("Invalid raster height 0.");
ret = false;
}

// Allocate the compression buffer...
if (r->compressed)
if (ret && r->compressed)
{
free(r->pixels);

if ((r->pixels = calloc(r->header.cupsBytesPerLine, 1)) == NULL)
{
_cupsRasterAddError("Unable to allocate %u bytes for raster line: %s", r->header.cupsBytesPerLine, strerror(errno));

r->pcurrent = NULL;
r->pend = NULL;
r->count = 0;

return (false);
ret = false;
}
else
{
r->pcurrent = r->pixels;
r->pend = r->pixels + r->header.cupsBytesPerLine;
r->count = 0;

r->pcurrent = r->pixels;
r->pend = r->pixels + r->header.cupsBytesPerLine;
r->count = 0;

DEBUG_printf("4cups_raster_update: Allocated %u bytes at %p.", r->header.cupsBytesPerLine, r->pixels);
DEBUG_printf("4cups_raster_update: Allocated %u bytes at %p.", r->header.cupsBytesPerLine, r->pixels);
}
}

return (true);
return (ret);
}


Expand Down
10 changes: 7 additions & 3 deletions cups/testraster.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Raster test program routines for CUPS.
//
// Copyright © 2021-2022 by OpenPrinting.
// Copyright © 2021-2024 by OpenPrinting.
// Copyright © 2007-2019 by Apple Inc.
// Copyright © 1997-2007 by Easy Software Products.
//
Expand Down Expand Up @@ -67,6 +67,7 @@ do_ras_file(const char *filename) // I - Filename
unsigned char *data; // Raster data
int errors = 0; // Number of errors
unsigned pages = 0; // Number of pages
const char *errmsg; // Error message, if any


if ((fd = open(filename, O_RDONLY)) < 0)
Expand All @@ -77,7 +78,7 @@ do_ras_file(const char *filename) // I - Filename

if ((ras = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL)
{
printf("%s: cupsRasterOpen failed.\n", filename);
printf("%s: cupsRasterOpen failed: %s\n", filename, cupsRasterGetErrorString());
close(fd);
return (1);
}
Expand Down Expand Up @@ -107,7 +108,10 @@ do_ras_file(const char *filename) // I - Filename
free(data);
}

printf("EOF at %ld\n", (long)lseek(fd, SEEK_CUR, 0));
if ((errmsg = cupsRasterGetErrorString()) != NULL)
printf("Error at %ld: %s\n", (long)lseek(fd, SEEK_CUR, 0), errmsg);
else
printf("EOF at %ld\n", (long)lseek(fd, SEEK_CUR, 0));

cupsRasterClose(ras);
close(fd);
Expand Down

0 comments on commit d2a3eff

Please sign in to comment.