[devel] Make the 'png_jmpbuf' macro expand to a call that records the correct

    longjmp function as well as returning a pointer to the setjmp
    jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'.
    (John Bowler)
diff --git a/ANNOUNCE b/ANNOUNCE
index 69cfb7f..60dee3b 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -699,6 +699,10 @@
     after png_write_IEND().  See 1.4.0beta32, 1.4.0beta50 changes above
     and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES.  Someone needs this
     feature but I don't remember who.
+  Make the 'png_jmpbuf' macro expand to a call that records the correct
+    longjmp function as well as returning a pointer to the setjmp
+    jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'.
+    (John Bowler)
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index 7a3e456..33e2c38 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2386,6 +2386,10 @@
     to png_flush() after png_write_IEND().  See 1.4.0beta32, 1.4.0beta50
     changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES.  Someone
     needs this feature but I don't remember who.
+  Make the 'png_jmpbuf' macro expand to a call that records the correct
+    longjmp function as well as returning a pointer to the setjmp
+    jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'.
+    (John Bowler)
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/png.h b/png.h
index 37034c6..e0e833f 100644
--- a/png.h
+++ b/png.h
@@ -1,7 +1,7 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.4.0beta103 - November 20, 2009
+ * libpng version 1.4.0beta103 - November 21, 2009
  * Copyright (c) 1998-2009 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -11,7 +11,7 @@
  * Authors and maintainers:
  *  libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *  libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *  libpng versions 0.97, January 1998, through 1.4.0beta103 - November 20, 2009: Glenn
+ *  libpng versions 0.97, January 1998, through 1.4.0beta103 - November 21, 2009: Glenn
  *  See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
@@ -163,7 +163,7 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.4.0beta103, November 20, 2009, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.4.0beta103, November 21, 2009, are
  * Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
  * distributed according to the same disclaimer and license as libpng-1.2.5
  * with the following individual added to the list of Contributing Authors:
@@ -339,7 +339,7 @@
 /* Version information for png.h - this should match the version in png.c */
 #define PNG_LIBPNG_VER_STRING "1.4.0beta103"
 #define PNG_HEADER_VERSION_STRING \
-   " libpng version 1.4.0beta103 - November 20, 2009\n"
+   " libpng version 1.4.0beta103 - November 21, 2009\n"
 
 #define PNG_LIBPNG_VER_SONUM   14
 #define PNG_LIBPNG_VER_DLLNUM  14
@@ -1010,6 +1010,13 @@
 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
 typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
 #endif
+#ifdef PNG_SETJMP_SUPPORTED
+/* This must match the function definition in <setjmp.h>, and the
+ * application must include this before png.h to obtain the definition
+ * of jmp_buf.
+ */
+typedef void (PNGAPI *png_longjmp_ptr) PNGARG((jmp_buf, int));
+#endif
 
 /* Transform masks for the high-level interface */
 #define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
@@ -1049,7 +1056,8 @@
 struct png_struct_def
 {
 #ifdef PNG_SETJMP_SUPPORTED
-   jmp_buf jmpbuf;            /* used in png_error */
+   jmp_buf jmpbuf PNG_DEPSTRUCT;            /* used in png_error */
+   png_longjmp_ptr longjmp_fn PNG_DEPSTRUCT;/* setjmp non-local goto function. */
 #endif
    png_error_ptr error_fn PNG_DEPSTRUCT;    /* function for printing errors and aborting */
    png_error_ptr warning_fn PNG_DEPSTRUCT;  /* function for printing warnings */
@@ -1380,6 +1388,26 @@
    PNGARG((png_structp png_ptr, png_size_t size));
 #endif
 
+/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
+ * match up.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+/* This function returns the jmp_buf built in to *png_ptr.  It must be
+ * supplied with an appropriate 'longjmp' function to use on that jmp_buf
+ * unless the default error function is overridden in which case NULL is
+ * acceptable.  The size of the jmp_buf is checked against the actual size
+ * allocated by the library - the call will return NULL on a mismatch
+ * indicating an ABI mismatch.
+ */
+extern PNG_EXPORT(jmp_buf*, png_set_longjmp_fn)
+   PNGARG((png_structp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+#  define png_jmpbuf(png_ptr) \
+   (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf)))
+#else
+#  define png_jmpbuf(png_ptr) \
+   (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
+#endif
+
 /* Reset the compression stream */
 extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
 
diff --git a/pngconf.h b/pngconf.h
index 3fb0461..3693c26 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,7 +1,7 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.4.0beta103 - November 20, 2009
+ * libpng version 1.4.0beta103 - November 21, 2009
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1998-2009 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@@ -1352,13 +1352,6 @@
  * functions that are passed far data must be model-independent.
  */
 
-#ifdef PNG_SETJMP_SUPPORTED
-#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
-#else
-#  define png_jmpbuf(png_ptr) \
-   (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
-#endif
-
 /* memory model/platform independent fns */
 #ifndef PNG_ABORT
 #  ifdef _WINDOWS_
diff --git a/pngerror.c b/pngerror.c
index 3c9c72d..d7efd603 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -1,7 +1,7 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.4.0 [November 20, 2009]
+ * Last changed in libpng 1.4.0 [November 21, 2009]
  * Copyright (c) 1998-2009 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -229,6 +229,21 @@
 #endif
 #endif /* PNG_READ_SUPPORTED */
 
+#ifdef PNG_SETJMP_SUPPORTED
+/* This API only exists if ANSI-C style error handling is used, otherwise
+ * it is necessary for png_default_error to be overridden.
+ */
+jmp_buf* PNGAPI
+png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)
+{
+   if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
+      return NULL;
+
+   png_ptr->longjmp_fn = longjmp_fn;
+   return &png_ptr->jmpbuf;
+}
+#endif
+
 /* This is the default error handling function.  Note that replacements for
  * this function MUST NOT RETURN, or the program will likely crash.  This
  * function is used by default, or if the program supplies NULL for the
@@ -273,16 +288,16 @@
 #endif
 
 #ifdef PNG_SETJMP_SUPPORTED
-   if (png_ptr)
+   if (png_ptr && png_ptr->longjmp_fn)
    {
 #  ifdef USE_FAR_KEYWORD
    {
       jmp_buf jmpbuf;
       png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
-      longjmp(jmpbuf, 1);
+      png_ptr->longjmp_fn(jmpbuf, 1);
    }
 #  else
-   longjmp(png_ptr->jmpbuf, 1);
+   png_ptr->longjmp_fn(png_ptr->jmpbuf, 1);
 #  endif
    }
 #endif
diff --git a/pngread.c b/pngread.c
index 5d942d6..e5591cf 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,7 +1,7 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.4.0 [November 20, 2009]
+ * Last changed in libpng 1.4.0 [November 21, 2009]
  * Copyright (c) 1998-2009 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -78,9 +78,12 @@
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
 #else
-   if (setjmp(png_ptr->jmpbuf))
+   if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
 #endif
       PNG_ABORT();
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf));
+#endif
 #endif /* PNG_SETJMP_SUPPORTED */
 
 #ifdef PNG_USER_MEM_SUPPORTED
diff --git a/pngwrite.c b/pngwrite.c
index 3fdf78c..9165a84 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -503,7 +503,10 @@
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
 #else
-   if (setjmp(png_ptr->jmpbuf))
+   if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */
+#endif
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf));
 #endif
       PNG_ABORT();
 #endif