[devel] Reverted changes to call png_longjmp in contrib/gregbook

where it is not appropriate.  If mainprog->jmpbuf is used by setjmp,
then png_longjmp cannot be used.
Reversed patch to remove error handler when the jmp_buf is stored in the
main program structure, not the png_struct.
The error handler is needed because the default handler in libpng will
always use the jmp_buf in the library control structure; this is never
set.  The gregbook code is a useful example because, even though it
uses setjmp/longjmp, it shows how error handling can be implemented
using control mechanisms not directly supported by libpng.  The
technique will work correctly with mechanisms such as Microsoft
Structure Exceptions or C++ exceptions (compiler willing - note that gcc
does not by default support interworking of C and C++ error handling.)
This commit is contained in:
Glenn Randers-Pehrson 2010-06-28 20:17:48 -05:00
parent 6cac43c974
commit 73e28ef13d
9 changed files with 122 additions and 21 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.5.0beta33 - June 26, 2010 Libpng 1.5.0beta33 - June 29, 2010
This is not intended to be a public release. It will be replaced This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version. within a few weeks by a public version or by another test version.
@ -77,6 +77,7 @@ version 1.5.0beta10 [February 25, 2010]
version 1.5.0beta11 [March 6, 2010] version 1.5.0beta11 [March 6, 2010]
Removed checking for already-included setjmp.h from pngconf.h Removed checking for already-included setjmp.h from pngconf.h
Fixed inconsistent indentations and made numerous cosmetic changes. Fixed inconsistent indentations and made numerous cosmetic changes.
Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
version 1.5.0beta12 [March 9, 2010] version 1.5.0beta12 [March 9, 2010]
Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from
@ -225,7 +226,7 @@ version 1.5.0beta24 [May 7, 2010]
offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.
Added more blank lines for readability. Added more blank lines for readability.
version 1.5.0beta25 [June 26, 2010] version 1.5.0beta25 [June 29, 2010]
In pngpread.c: png_push_have_row() add check for new_row > height In pngpread.c: png_push_have_row() add check for new_row > height
Removed the now-redundant check for out-of-bounds new_row from example.c Removed the now-redundant check for out-of-bounds new_row from example.c
@ -251,16 +252,29 @@ version 1.5.0beta31 [June 26, 2010]
Revised pngpread.c patch of beta28 to avoid an endless loop. Revised pngpread.c patch of beta28 to avoid an endless loop.
Removed some trailing blanks. Removed some trailing blanks.
version 1.5.0beta32 [June 26, 2010] version 1.5.0beta32 [June 29, 2010]
Removed leftover scripts/options.patch and scripts/options.rej Removed leftover scripts/options.patch and scripts/options.rej
version 1.5.0beta32 [June 26, 2010] version 1.5.0beta32 [June 29, 2010]
Made FIXED and FLOATING options consistent in the APIs they enable and Made FIXED and FLOATING options consistent in the APIs they enable and
disable. Corrected scripts/options.awk to handle both command line disable. Corrected scripts/options.awk to handle both command line
options and options specified in the .dfa files. options and options specified in the .dfa files.
Changed char *msg to PNG_CONST char *msg in pngrutil.c Changed char *msg to PNG_CONST char *msg in pngrutil.c
Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or
floating point APIs, but not both. floating point APIs, but not both.
Reversed patch to remove error handler when the jmp_buf is stored in the
main program structure, not the png_struct.
The error handler is needed because the default handler in libpng will
always use the jmp_buf in the library control structure; this is never
set. The gregbook code is a useful example because, even though it
uses setjmp/longjmp, it shows how error handling can be implemented
using control mechanisms not directly supported by libpng. The
technique will work correctly with mechanisms such as Microsoft
Structure Exceptions or C++ exceptions (compiler willing - note that gcc
does not by default support interworking of C and C++ error handling.)
Reverted changes to call png_longjmp in contrib/gregbook where it is not
appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp
cannot be used.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net: Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
(subscription required; visit (subscription required; visit

16
CHANGES
View File

@ -2557,6 +2557,7 @@ version 1.5.0beta10 [February 25, 2010]
version 1.5.0beta11 [March 6, 2010] version 1.5.0beta11 [March 6, 2010]
Removed checking for already-included setjmp.h from pngconf.h Removed checking for already-included setjmp.h from pngconf.h
Fixed inconsistent indentations and made numerous cosmetic changes. Fixed inconsistent indentations and made numerous cosmetic changes.
Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
version 1.5.0beta12 [March 9, 2010] version 1.5.0beta12 [March 9, 2010]
Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from
@ -2736,13 +2737,26 @@ version 1.5.0beta31 [June 26, 2010]
version 1.5.0beta32 [June 26, 2010] version 1.5.0beta32 [June 26, 2010]
Removed leftover scripts/options.patch and scripts/options.rej Removed leftover scripts/options.patch and scripts/options.rej
version 1.5.0beta33 [June 26, 2010] version 1.5.0beta33 [June 29, 2010]
Made FIXED and FLOATING options consistent in the APIs they enable and Made FIXED and FLOATING options consistent in the APIs they enable and
disable. Corrected scripts/options.awk to handle both command line disable. Corrected scripts/options.awk to handle both command line
options and options specified in the .dfa files. options and options specified in the .dfa files.
Changed char *msg to PNG_CONST char *msg in pngrutil.c Changed char *msg to PNG_CONST char *msg in pngrutil.c
Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or
floating point APIs, but not both. floating point APIs, but not both.
Reversed patch to remove error handler when the jmp_buf is stored in the
main program structure, not the png_struct.
The error handler is needed because the default handler in libpng will
always use the jmp_buf in the library control structure; this is never
set. The gregbook code is a useful example because, even though it
uses setjmp/longjmp, it shows how error handling can be implemented
using control mechanisms not directly supported by libpng. The
technique will work correctly with mechanisms such as Microsoft
Structure Exceptions or C++ exceptions (compiler willing - note that gcc
does not by default support interworking of C and C++ error handling.)
Reverted changes to call png_longjmp in contrib/gregbook where it is not
appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp
cannot be used.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -66,6 +66,7 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass); png_uint_32 row_num, int pass);
static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr); static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
@ -101,7 +102,7 @@ int readpng2_init(mainprog_info *mainprog_ptr)
/* could also replace libpng warning-handler (final NULL), but no need: */ /* could also replace libpng warning-handler (final NULL), but no need: */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
NULL, NULL); readpng2_error_handler, NULL);
if (!png_ptr) if (!png_ptr)
return 4; /* out of memory */ return 4; /* out of memory */
@ -450,3 +451,41 @@ void readpng2_cleanup(mainprog_info *mainprog_ptr)
mainprog_ptr->png_ptr = NULL; mainprog_ptr->png_ptr = NULL;
mainprog_ptr->info_ptr = NULL; mainprog_ptr->info_ptr = NULL;
} }
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
{
mainprog_info *mainprog_ptr;
/* 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. */
fprintf(stderr, "readpng2 libpng error: %s\n", msg);
fflush(stderr);
mainprog_ptr = png_get_error_ptr(png_ptr);
if (mainprog_ptr == NULL) { /* we are completely hosed now */
fprintf(stderr,
"readpng2 severe error: jmpbuf not recoverable; terminating.\n");
fflush(stderr);
exit(99);
}
/* Now we have our data structure we can use the information in it
* to return control to our own higher level code (all the points
* where 'setjmp' is called in this file.) This will work with other
* error handling mechanisms as well - libpng always calls png_error
* when it can proceed no further, thus, so long as the error handler
* is intercepted, application code can do its own error recovery.
*/
longjmp(mainprog_ptr->jmpbuf, 1);
}

View File

@ -24,8 +24,6 @@
- 1.10: enabled "message window"/console (thanks to David Geldreich) - 1.10: enabled "message window"/console (thanks to David Geldreich)
- 2.00: dual-licensed (added GNU GPL) - 2.00: dual-licensed (added GNU GPL)
- 2.01: fixed improper display of usage screen on PNG error(s) - 2.01: fixed improper display of usage screen on PNG error(s)
- 2.02: removed special error-handling which is no longer needed
because of the new libpng png_longjmp() feature in libpng-1.5.0.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -26,8 +26,6 @@
- 1.14: added support for X resources (thanks to Gerhard Niklasch) - 1.14: added support for X resources (thanks to Gerhard Niklasch)
- 2.00: dual-licensed (added GNU GPL) - 2.00: dual-licensed (added GNU GPL)
- 2.01: fixed improper display of usage screen on PNG error(s) - 2.01: fixed improper display of usage screen on PNG error(s)
- 2.02: removed special error-handling which is no longer needed
because of the new libpng png_longjmp() feature in libpng-1.5.0.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -32,9 +32,7 @@
- 2.01: fixed 64-bit typo in readpng2.c - 2.01: fixed 64-bit typo in readpng2.c
- 2.02: fixed improper display of usage screen on PNG error(s); fixed - 2.02: fixed improper display of usage screen on PNG error(s); fixed
unexpected-EOF and file-read-error cases unexpected-EOF and file-read-error cases
- 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options; - 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options
removed special error-handling which is no longer needed
because of the new libpng png_longjmp() feature in libpng-1.5.0.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -41,8 +41,6 @@
unexpected-EOF and file-read-error cases; fixed Trace() cut-and- unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
paste bugs paste bugs
- 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
removed special error-handling which is no longer needed
because of the new libpng png_longjmp() feature in libpng-1.5.0.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
@ -786,8 +784,9 @@ static void rpng2_x_init(void)
if (rpng2_x_create_window()) { if (rpng2_x_create_window()) {
/* GRR TEMPORARY HACK: this is fundamentally no different from cases /* GRR TEMPORARY HACK: this is fundamentally no different from cases
* above; libpng should longjmp() back to us when png_ptr goes away. * above; libpng should call our error handler to longjmp() back to us
* If we/it segfault instead, seems like a libpng bug... */ * when png_ptr goes away. If we/it segfault instead, seems like a
* libpng bug... */
/* we're here via libpng callback, so if window fails, clean and bail */ /* we're here via libpng callback, so if window fails, clean and bail */
readpng2_cleanup(&rpng2_info); readpng2_cleanup(&rpng2_info);

View File

@ -29,8 +29,6 @@
- 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix - 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix
(see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff) (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)
- 2.00: dual-licensed (added GNU GPL) - 2.00: dual-licensed (added GNU GPL)
- 2.01: removed special error-handling which is no longer needed
because of the new libpng png_longjmp() feature in libpng-1.5.0.
[REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line [REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line
dose not work! In order to do something useful I needed to redirect dose not work! In order to do something useful I needed to redirect

View File

@ -60,6 +60,10 @@
#include "writepng.h" /* typedefs, common macros, public prototypes */ #include "writepng.h" /* typedefs, common macros, public prototypes */
/* local prototype */
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
void writepng_version_info(void) void writepng_version_info(void)
@ -86,7 +90,7 @@ int writepng_init(mainprog_info *mainprog_ptr)
/* could also replace libpng warning-handler (final NULL), but no need: */ /* could also replace libpng warning-handler (final NULL), but no need: */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
NULL, NULL); writepng_error_handler, NULL);
if (!png_ptr) if (!png_ptr)
return 4; /* out of memory */ return 4; /* out of memory */
@ -100,7 +104,8 @@ int writepng_init(mainprog_info *mainprog_ptr)
/* setjmp() must be called in every function that calls a PNG-writing /* setjmp() must be called in every function that calls a PNG-writing
* libpng function, unless an alternate error handler was installed-- * libpng function, unless an alternate error handler was installed--
* but compatible error handlers must either use longjmp() themselves * but compatible error handlers must either use longjmp() themselves
* (as in this program) or exit immediately, so here we go: */ * (as in this program) or some other method to return control to
* application code, so here we go: */
if (setjmp(mainprog_ptr->jmpbuf)) { if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
@ -355,3 +360,41 @@ void writepng_cleanup(mainprog_info *mainprog_ptr)
if (png_ptr && info_ptr) if (png_ptr && info_ptr)
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
} }
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
{
mainprog_info *mainprog_ptr;
/* 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. */
fprintf(stderr, "writepng libpng error: %s\n", msg);
fflush(stderr);
mainprog_ptr = png_get_error_ptr(png_ptr);
if (mainprog_ptr == NULL) { /* we are completely hosed now */
fprintf(stderr,
"writepng severe error: jmpbuf not recoverable; terminating.\n");
fflush(stderr);
exit(99);
}
/* Now we have our data structure we can use the information in it
* to return control to our own higher level code (all the points
* where 'setjmp' is called in this file.) This will work with other
* error handling mechanisms as well - libpng always calls png_error
* when it can proceed no further, thus, so long as the error handler
* is intercepted, application code can do its own error recovery.
*/
longjmp(mainprog_ptr->jmpbuf, 1);
}