Skip to content

Commit d2a3eff

Browse files
committed
Move more of the page header checks to the cups_raster_update function and add error messages for all detected issues.
1 parent fcb0bc8 commit d2a3eff

3 files changed

Lines changed: 80 additions & 14 deletions

File tree

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ libcups v3.0rc3 (YYYY-MM-DD)
99
- Updated `cupsSaveCredentials` to validate the input credentials, support
1010
using a saved private key from `cupsCreateCertificateRequest`, and support
1111
credential removal as documented.
12+
- Updated the raster functions to report more issues via
13+
`cupsRasterGetErrorString`.
1214

1315

1416
libcups v3.0rc2 (2024-10-15)

cups/raster-stream.c

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313
#include "debug-internal.h"
1414

1515

16+
//
17+
// Limits...
18+
//
19+
20+
#define _CUPS_MAX_BYTES_PER_LINE (16 * 1024 * 1024)
21+
#define _CUPS_MAX_BITS_PER_COLOR 16
22+
#define _CUPS_MAX_BITS_PER_PIXEL 240
23+
24+
1625
//
1726
// Private structures...
1827
//
@@ -838,7 +847,7 @@ cupsRasterReadHeader(
838847

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

841-
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);
850+
return (0);
842851
}
843852

844853

@@ -1540,6 +1549,9 @@ cups_raster_read(cups_raster_t *r, // I - Raster stream
15401549
static bool // O - `true` on success, `false` on failure
15411550
cups_raster_update(cups_raster_t *r) // I - Raster stream
15421551
{
1552+
bool ret = true; // Return value
1553+
1554+
15431555
if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 ||
15441556
r->header.cupsNumColors == 0)
15451557
{
@@ -1617,7 +1629,11 @@ cups_raster_update(cups_raster_t *r) // I - Raster stream
16171629

16181630
default :
16191631
// Unknown color space
1620-
return (false);
1632+
_cupsRasterAddError("Unknown color space in page header.");
1633+
1634+
r->header.cupsNumColors = 0;
1635+
ret = false;
1636+
break;
16211637
}
16221638

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

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

1668+
// Validate the page header...
1669+
if (r->header.cupsBytesPerLine == 0)
1670+
{
1671+
_cupsRasterAddError("Invalid raster line length 0.");
1672+
ret = false;
1673+
}
1674+
else if (r->header.cupsBytesPerLine > _CUPS_MAX_BYTES_PER_LINE)
1675+
{
1676+
_cupsRasterAddError("Raster line length %u is greater than %d bytes.", r->header.cupsBytesPerLine, _CUPS_MAX_BYTES_PER_LINE);
1677+
ret = false;
1678+
}
1679+
else if ((r->header.cupsBytesPerLine % r->bpp) != 0)
1680+
{
1681+
_cupsRasterAddError("Raster line length %u is not a multiple of the pixel size (%d).", r->header.cupsBytesPerLine, r->bpp);
1682+
ret = false;
1683+
}
1684+
1685+
if (r->header.cupsBitsPerColor == 0 || r->header.cupsBitsPerColor > _CUPS_MAX_BITS_PER_COLOR)
1686+
{
1687+
_cupsRasterAddError("Invalid bits per color %u.", r->header.cupsBitsPerColor);
1688+
ret = false;
1689+
}
1690+
1691+
if (r->header.cupsBitsPerPixel == 0 || r->header.cupsBitsPerPixel > _CUPS_MAX_BITS_PER_PIXEL)
1692+
{
1693+
_cupsRasterAddError("Invalid bits per pixel %u.", r->header.cupsBitsPerPixel);
1694+
ret = false;
1695+
}
1696+
1697+
if (r->header.cupsWidth == 0)
1698+
{
1699+
_cupsRasterAddError("Invalid raster width 0.");
1700+
ret = false;
1701+
}
1702+
1703+
if (r->header.cupsHeight == 0)
1704+
{
1705+
_cupsRasterAddError("Invalid raster height 0.");
1706+
ret = false;
1707+
}
1708+
16521709
// Allocate the compression buffer...
1653-
if (r->compressed)
1710+
if (ret && r->compressed)
16541711
{
16551712
free(r->pixels);
16561713

16571714
if ((r->pixels = calloc(r->header.cupsBytesPerLine, 1)) == NULL)
16581715
{
1716+
_cupsRasterAddError("Unable to allocate %u bytes for raster line: %s", r->header.cupsBytesPerLine, strerror(errno));
1717+
16591718
r->pcurrent = NULL;
16601719
r->pend = NULL;
16611720
r->count = 0;
1662-
1663-
return (false);
1721+
ret = false;
16641722
}
1723+
else
1724+
{
1725+
r->pcurrent = r->pixels;
1726+
r->pend = r->pixels + r->header.cupsBytesPerLine;
1727+
r->count = 0;
16651728

1666-
r->pcurrent = r->pixels;
1667-
r->pend = r->pixels + r->header.cupsBytesPerLine;
1668-
r->count = 0;
1669-
1670-
DEBUG_printf("4cups_raster_update: Allocated %u bytes at %p.", r->header.cupsBytesPerLine, r->pixels);
1729+
DEBUG_printf("4cups_raster_update: Allocated %u bytes at %p.", r->header.cupsBytesPerLine, r->pixels);
1730+
}
16711731
}
16721732

1673-
return (true);
1733+
return (ret);
16741734
}
16751735

16761736

cups/testraster.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// Raster test program routines for CUPS.
33
//
4-
// Copyright © 2021-2022 by OpenPrinting.
4+
// Copyright © 2021-2024 by OpenPrinting.
55
// Copyright © 2007-2019 by Apple Inc.
66
// Copyright © 1997-2007 by Easy Software Products.
77
//
@@ -67,6 +67,7 @@ do_ras_file(const char *filename) // I - Filename
6767
unsigned char *data; // Raster data
6868
int errors = 0; // Number of errors
6969
unsigned pages = 0; // Number of pages
70+
const char *errmsg; // Error message, if any
7071

7172

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

7879
if ((ras = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL)
7980
{
80-
printf("%s: cupsRasterOpen failed.\n", filename);
81+
printf("%s: cupsRasterOpen failed: %s\n", filename, cupsRasterGetErrorString());
8182
close(fd);
8283
return (1);
8384
}
@@ -107,7 +108,10 @@ do_ras_file(const char *filename) // I - Filename
107108
free(data);
108109
}
109110

110-
printf("EOF at %ld\n", (long)lseek(fd, SEEK_CUR, 0));
111+
if ((errmsg = cupsRasterGetErrorString()) != NULL)
112+
printf("Error at %ld: %s\n", (long)lseek(fd, SEEK_CUR, 0), errmsg);
113+
else
114+
printf("EOF at %ld\n", (long)lseek(fd, SEEK_CUR, 0));
111115

112116
cupsRasterClose(ras);
113117
close(fd);

0 commit comments

Comments
 (0)