changeset 3839:320acec37716

[xemacs-hg @ 2007-02-21 10:49:30 by stephent] Fix error handling in png_instantiate. <871wkjn5in.fsf@uwakimon.sk.tsukuba.ac.jp>
author stephent
date Wed, 21 Feb 2007 10:49:33 +0000
parents ee97c4f8f57d
children 468d3e5fc353
files src/ChangeLog src/glyphs-eimage.c
diffstat 2 files changed, 31 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Feb 20 22:51:14 2007 +0000
+++ b/src/ChangeLog	Wed Feb 21 10:49:33 2007 +0000
@@ -1,3 +1,9 @@
+2007-02-17  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* glyphs-eimage.c (png_instantiate_unwind): Avoid recursion.
+	(png_instantiate): Initialize setjmp_buffer early, and avoid
+	recursive entry to error handler.
+
 2007-02-19  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* specifier.c (Fdevice_matching_specifier_tag_list):
--- a/src/glyphs-eimage.c	Tue Feb 20 22:51:14 2007 +0000
+++ b/src/glyphs-eimage.c	Wed Feb 21 10:49:33 2007 +0000
@@ -849,7 +849,13 @@
 
   free_opaque_ptr (unwind_obj);
   if (data->png_ptr)
-    png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
+    {
+      /* ensure we can't get here again */
+      png_structp tmp = data->png_ptr;
+      data->png_ptr = NULL;
+      png_destroy_read_struct (&tmp, &(data->info_ptr), (png_infopp)NULL);
+    }
+
   if (data->instream)
     retry_fclose (data->instream);
 
@@ -874,24 +880,36 @@
   png_structp png_ptr;
   png_infop info_ptr;
 
+  xzero (unwind);
+  record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
+
+  if (setjmp (png_err_stct.setjmp_buffer))
+    {
+      /* Something blew up:
+	 just display the error (cleanup happens in the unwind) */
+      signal_image_error_2 ("Error decoding PNG",
+			     build_string(png_err_stct.err_str),
+			     instantiator);
+    }
+
   /* Initialize all PNG structures */
-  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
+  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
+				    (void *) &png_err_stct,
 				    png_error_func, png_warning_func);
   if (!png_ptr)
     signal_image_error ("Error obtaining memory for png_read", instantiator);
+  unwind.png_ptr = png_ptr;
+
   info_ptr = png_create_info_struct (png_ptr);
   if (!info_ptr)
     {
+      unwind.png_ptr = NULL;	/* avoid re-calling png_destroy_read_struct
+				   when unwinding */
       png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
       signal_image_error ("Error obtaining memory for png_read", instantiator);
     }
-
-  xzero (unwind);
-  unwind.png_ptr = png_ptr;
   unwind.info_ptr = info_ptr;
 
-  record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
-
   /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
      this file, example.c from the libpng 0.81 distribution, and the
      pngtopnm sources. -WMP-
@@ -900,16 +918,6 @@
      and is no longer usable for previous versions. jh
   */
 
-  /* Set the jmp_buf return context for png_error ... if this returns !0, then
-     we ran into a problem somewhere, and need to clean up after ourselves. */
-  if (setjmp (png_err_stct.setjmp_buffer))
-    {
-      /* Something blew up: just display the error (cleanup happens in the unwind) */
-      signal_image_error_2 ("Error decoding PNG",
-			     build_string(png_err_stct.err_str),
-			     instantiator);
-    }
-
   /* Initialize the IO layer and read in header information */
   {
     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);