Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 68 additions & 5 deletions cupsfilters/image-png.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@

#ifdef HAVE_LIBPNG
# include <png.h> // Portable Network Graphics (PNG) definitions
# include <setjmp.h>


//
// Custom error handler for libpng — longjmp() back to the setjmp()
// point in the caller instead of the default abort(), so a malformed
// PNG results in a graceful error return.
//

static void
cf_image_png_error_callback(png_structp png,
png_const_charp error_msg)
{
DEBUG_printf(("DEBUG: libpng error: %s\n", error_msg));
longjmp(png_jmpbuf(png), 1);
}


//
// Custom warning handler for libpng — log non-fatal issues
// and return normally so processing continues.
//

static void
cf_image_png_warning_callback(png_structp png,
png_const_charp warning_msg)
{
DEBUG_printf(("DEBUG: libpng warning: %s\n", warning_msg));
}


//
Expand Down Expand Up @@ -51,18 +80,52 @@ _cfImageReadPNG(
int bpp; // Bytes per pixel
int pass, // Current pass
passes; // Number of passes required
cf_ib_t *in, // Input pixels
*inptr, // Pointer into pixels
*out; // Output pixels
cf_ib_t * volatile in = NULL; // Input pixels (volatile for setjmp)
cf_ib_t *inptr; // Pointer into pixels
cf_ib_t * volatile out = NULL; // Output pixels (volatile for setjmp)
png_color_16 bg; // Background color


//
// Setup the PNG data structures...
// Setup the PNG data structures with custom error/warning handlers
// so that a malformed PNG causes an error return instead of abort().
// Errors during struct creation are handled internally by libpng
// and result in a NULL return. Errors in any png_*() call after
// setjmp() trigger our error callback which longjmp()s back.
//

pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
cf_image_png_error_callback,
cf_image_png_warning_callback);
if (pp == NULL)
{
fclose(fp);
return (1);
}

info = png_create_info_struct(pp);
if (info == NULL)
{
png_destroy_read_struct(&pp, NULL, NULL);
fclose(fp);
return (1);
}

//
// Error handling jump point — if any png_*() call below triggers
// png_error(), our callback longjmp()s back here. The 'in' and
// 'out' pointers are initialized to NULL so free() is safe here
// even if longjmp() reverts them (C11 §7.13.2.1).
//

if (setjmp(png_jmpbuf(pp)))
{
free(in);
free(out);
png_destroy_read_struct(&pp, &info, NULL);
fclose(fp);
return (1);
}

//
// Initialize the PNG read "engine"...
Expand Down
Loading