From 10f850710d6dd071d55cec591aba0acd0e57a705 Mon Sep 17 00:00:00 2001 From: "dp%netscape.com" Date: Fri, 27 Aug 1999 04:09:01 +0000 Subject: [PATCH] This patch improves the PNG error-handling. Primarily it fixes a very subtle compile-time error involving the jmp_buf struct, which can be different sizes depending on what macros are defined. Since libpng and Mozilla are not necessarily compiled at the same time (at least during development), the only way to guarantee that their concept of jmp_buf is consistent is to avoid using it at all in one of them; specifically, replace libpng's default error-handler with essentially the same thing within Mozilla. (This will likely be required in a future version of libpng, btw.) --- modules/libimg/pngcom/ipng.cpp | 63 +++++++++++++++++++++++++++------- modules/libimg/pngcom/ipng.h | 23 +++++++------ 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/modules/libimg/pngcom/ipng.cpp b/modules/libimg/pngcom/ipng.cpp index c135a21e442..3acf4eb5c47 100644 --- a/modules/libimg/pngcom/ipng.cpp +++ b/modules/libimg/pngcom/ipng.cpp @@ -31,10 +31,11 @@ static void png_set_dims(il_container *, png_structp); +static void info_callback(png_structp png_ptr, png_infop info); static void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass); static void end_callback(png_structp png_ptr, png_infop info); -static void info_callback(png_structp png_ptr, png_infop info); +static void il_png_error_handler(png_structp png_ptr, png_const_charp msg); @@ -69,23 +70,28 @@ il_png_init(il_container *ic) int il_png_write(il_container *ic, const unsigned char *buf, int32 len) { - ipng_structp ipng_p; - - png_structp png_ptr; - png_infop info_ptr; + ipng_structp ipng_p; + png_structp png_ptr; + png_infop info_ptr; - /*------*/ + PR_ASSERT(ic != NULL); ipng_p = (ipng_structp)ic->ds; + + if (ipng_p->state == PNG_ERROR) + return -1; + if(ipng_p->state == PNG_INIT ){ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, ipng_p, + il_png_error_handler, NULL); ipng_p->pngs_p = png_ptr; /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); ipng_p->info_p = info_ptr; if (info_ptr == NULL){ - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - return -1; + png_destroy_read_struct(&png_ptr, NULL, NULL); + ipng_p->state = PNG_ERROR; + return -1; } png_set_progressive_read_fn(png_ptr, (void *)buf, info_callback, row_callback, end_callback); @@ -96,10 +102,13 @@ il_png_write(il_container *ic, const unsigned char *buf, int32 len) } /* note addition of ic to png structure.... */ png_ptr->io_ptr = ic; - if (setjmp(png_ptr->jmpbuf)) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return -1; + + if (setjmp(ipng_p->jmpbuf)) { + png_destroy_read_struct(&ipng_p->pngs_p, &ipng_p->info_p, NULL); + ipng_p->state = PNG_ERROR; + return -1; } + png_process_data( png_ptr, info_ptr, (unsigned char *)buf, len ); ipng_p->state = PNG_CONTINUE; @@ -329,3 +338,33 @@ end_callback(png_structp png_ptr, png_infop info) ic->imgdcb->ImgDCBFlushImage(); } + + + +static void +il_png_error_handler(png_structp png_ptr, png_const_charp msg) +{ + ipng_structp ipng_p; + + /* This function, aside from the extra step of retrieving the "error + * pointer" (below) and the fact that it exists within the application + * rather than within libpng, is essentially identical to libpng's + * default error handler. The second point is critical: since both + * setjmp() and longjmp() are called from the same code, they are + * guaranteed to have compatible notions of how big a jmp_buf is, + * regardless of whether _BSD_SOURCE or anything else has (or has not) + * been defined. Adapted from readpng2_error_handler() in "PNG: The + * Definitive Guide" (O'Reilly, 1999). */ + + fprintf(stderr, "nspng libpng error: %s\n", msg); + fflush(stderr); + + ipng_p = (ipng_structp)png_get_error_ptr(png_ptr); + if (ipng_p == NULL) { /* we are completely hosed now */ + fprintf(stderr, "nspng severe error: jmpbuf not recoverable.\n"); + fflush(stderr); + PR_ASSERT(ipng_p != NULL); /* instead of exit(99); */ + } + + longjmp(ipng_p->jmpbuf, 1); +} diff --git a/modules/libimg/pngcom/ipng.h b/modules/libimg/pngcom/ipng.h index 827c7fff6cb..96d4eba7949 100644 --- a/modules/libimg/pngcom/ipng.h +++ b/modules/libimg/pngcom/ipng.h @@ -20,26 +20,29 @@ typedef enum { - PNG_ERROR, - PNG_INIT, + PNG_ERROR, + PNG_INIT, PNG_CONTINUE, PNG_DELAY, - PNG_FINISH, - PNG_DONE + PNG_FINISH, + PNG_DONE } png_state; typedef struct ipng_str { - png_state state; /* Decoder FSM state */ + png_state state; /* Decoder FSM state */ - int rows_per_chunk; +/* int rows_per_chunk; NOT USED (similar variable in jpeg_struct) */ void *delay_timeout; uint32 delay_time; - png_struct *pngs_p; - png_infop info_p; - /* One scanline's worth of post-processed sample data */ + png_structp pngs_p; + png_infop info_p; + jmp_buf jmpbuf; /* use ours, not libpng's, for consistency */ + + /* One scanline's worth of post-processed sample data */ + + il_container *ic; - il_container *ic; } ipng_struct, *ipng_structp;