Hello,

The attached patch fixes the random segfaults from chimera when loading
PNG files. The libpng interface used by image/png.c was deprecated, I
updated it to the newer one.

I've been able to display http://www.debian.org/ other pages correctly,
while they previously crashed chimera2.

Thanks for packaging chimera, it's a great browser !

-- 
Jeremie Koenig <[EMAIL PROTECTED]>
diff -ru chimera2-2.0a19/debian/substvars chimera2-2.0a19.jk/debian/substvars
--- chimera2-2.0a19/debian/substvars    2005-08-09 00:18:08.293491385 +0200
+++ chimera2-2.0a19.jk/debian/substvars 2005-08-09 00:13:40.221457000 +0200
@@ -1 +1 @@
-shlibs:Depends=libc6 (>= 2.2.1-2), libjpeg62, libpng2, libxaw7 (>= 4.0.1-1), 
xlibs (>= 4.0.1-11), zlib1g (>= 1:1.1.3)
+shlibs:Depends=libc6 (>= 2.3.2.ds1-21), libice6 | xlibs (>> 4.1.0), libjpeg62, 
libpng12-0 (>= 1.2.8rel), libsm6 | xlibs (>> 4.1.0), libx11-6 | xlibs (>> 
4.1.0), libxaw7 (>> 4.1.0), libxext6 | xlibs (>> 4.1.0), libxmu6 | xlibs (>> 
4.1.0), libxpm4 | xlibs (>> 4.1.0), libxt6 | xlibs (>> 4.1.0), zlib1g (>= 
1:1.2.1)
Seulement dans chimera2-2.0a19.jk/image: .png.c.swo
Seulement dans chimera2-2.0a19.jk/image: .png.c.swp
diff -ru chimera2-2.0a19/image/png.c chimera2-2.0a19.jk/image/png.c
--- chimera2-2.0a19/image/png.c 1999-03-29 04:23:46.000000000 +0200
+++ chimera2-2.0a19.jk/image/png.c      2005-08-09 00:27:54.250138526 +0200
@@ -60,33 +60,49 @@
     int orig_depth = 0;
     pngState *png = (pngState *) png_get_progressive_ptr(state);
 
-    if (info->bit_depth < 8 && (PNG_COLOR_TYPE_RGB == info->color_type ||
-            PNG_COLOR_TYPE_RGB_ALPHA == info->color_type))
+    png_byte   bit_depth = png_get_bit_depth(state, info),
+               color_type = png_get_color_type(state, info);
+    png_uint_32 width = png_get_image_width(state, info),
+               height = png_get_image_height(state, info),
+               valid_tRNS = png_get_valid(state, info, PNG_INFO_tRNS),
+               valid_gAMA = png_get_valid(state, info, PNG_INFO_gAMA);
+    png_colorp palette;
+    png_color_16p trans_values;
+    png_bytep trans;
+    int num_palette, num_trans;
+    double gamma;
+    
+    png_get_PLTE(state, info, &palette, &num_palette);
+    png_get_tRNS(state, info, &trans, &num_trans, &trans_values);
+    png_get_gAMA(state, info, &gamma);
+
+    if (bit_depth < 8 && (PNG_COLOR_TYPE_RGB == color_type ||
+            PNG_COLOR_TYPE_RGB_ALPHA == color_type))
         png_set_expand(state);
 
     /* I wish the frame's background colour was available here */
-    if (info->color_type & PNG_COLOR_MASK_ALPHA) {
+    if (color_type & PNG_COLOR_MASK_ALPHA) {
         png_color_16 bg;
         int gflag = PNG_BACKGROUND_GAMMA_SCREEN;
         double gval = 1.0;
         int expand = 0;
 
         bg.red = bg.green = bg.blue = bg.gray = 0;
-        if (PNG_COLOR_TYPE_PALETTE == info->color_type)
+        if (PNG_COLOR_TYPE_PALETTE == color_type)
             png_set_expand(state);
 
         png_set_background(state, &bg, gflag, expand, gval);
     }
 
-    if (info->bit_depth < 8 && (info->bit_depth > 1 ||
-            PNG_COLOR_TYPE_GRAY != info->color_type)) {
-        if (PNG_COLOR_TYPE_GRAY == info->color_type)
-            orig_depth = info->bit_depth;
+    if (bit_depth < 8 && (bit_depth > 1 ||
+            PNG_COLOR_TYPE_GRAY != color_type)) {
+        if (PNG_COLOR_TYPE_GRAY == color_type)
+            orig_depth = bit_depth;
         png_set_packing(state);
     }
  
     /* tell libpng to strip 16 bit depth files down to 8 bits */
-    if (info->bit_depth > 8)
+    if (bit_depth > 8)
         png_set_strip_16(state);
 
     png_set_interlace_handling(state);
@@ -95,18 +111,18 @@
     png_read_update_info(state, info);
 
     /* allocate the memory to hold the image using the fields of png_info. */
-    if (PNG_COLOR_TYPE_GRAY == info->color_type && 1 == info->bit_depth) {
-        png->image = newBitImage(info->width, info->height);
+    if (PNG_COLOR_TYPE_GRAY == color_type && 1 == bit_depth) {
+        png->image = newBitImage(width, height);
        if (!png->image) {
            png->done = image_error;
            return;
        }
 
         png_set_invert_mono(state);
-    } else if (PNG_COLOR_TYPE_PALETTE == info->color_type) {
+    } else if (PNG_COLOR_TYPE_PALETTE == color_type) {
         int i;
 
-        png->image = newRGBImage(info->width, info->height, info->bit_depth);
+        png->image = newRGBImage(width, height, bit_depth);
        if (!png->image) {
            png->done = image_error;
            return;
@@ -115,28 +131,28 @@
         png->image->rgb.red = png->cmap[0];
         png->image->rgb.green = png->cmap[1];
         png->image->rgb.blue = png->cmap[2];
-        for (i = 0; i < info->num_palette; ++i) {
-            png->image->rgb.red[i] = info->palette[i].red << 8;
-            png->image->rgb.green[i] = info->palette[i].green << 8;
-            png->image->rgb.blue[i] = info->palette[i].blue << 8;
+        for (i = 0; i < num_palette; ++i) {
+            png->image->rgb.red[i] = palette[i].red << 8;
+            png->image->rgb.green[i] = palette[i].green << 8;
+            png->image->rgb.blue[i] = palette[i].blue << 8;
         }
-        png->image->rgb.used = info->num_palette;
-        if (info->valid & PNG_INFO_tRNS) {
+        png->image->rgb.used = num_palette;
+        if (valid_tRNS) {
             int val, i;
 
             val = 0;
-            for (i = 0; i < info->num_trans; ++i) {
-                if (info->trans[i] < info->trans[val])
+            for (i = 0; i < num_trans; ++i) {
+                if (trans[i] < trans[val])
                     val = i;
             }
             png->image->transparent = val;
         }
-    } else if (PNG_COLOR_TYPE_GRAY == info->color_type) {
+    } else if (PNG_COLOR_TYPE_GRAY == color_type) {
         int i;
-        int depth = orig_depth ? orig_depth : info->bit_depth;
+        int depth = orig_depth ? orig_depth : bit_depth;
         int maxval = (1 << depth) - 1;
 
-        png->image = newRGBImage(info->width, info->height, depth);
+        png->image = newRGBImage(width, height, depth);
        if (!png->image) {
            png->done = image_error;
            return;
@@ -153,10 +169,10 @@
         }
         png->image->rgb.used = maxval + 1;
 
-        if (info->valid & PNG_INFO_tRNS)
-            png->image->transparent = info->trans_values.gray;
+        if (valid_tRNS)
+            png->image->transparent = trans_values->gray;
     } else {
-        png->image = newTrueImage(info->width, info->height);
+        png->image = newTrueImage(width, height);
        if (!png->image) {
            png->done = image_error;
            return;
@@ -164,10 +180,11 @@
 
     }
 
-    if (info->valid & PNG_INFO_gAMA && png->image->type != IBITMAP)
-        png->image->gamma = 1.0 / info->gamma;
+    if (valid_gAMA && png->image->type != IBITMAP)
+        png->image->gamma = 1.0 / gamma;
 
-    assert((png->image->width * png->image->pixlen + 7) / 8 == info->rowbytes);
+    assert((png->image->width * png->image->pixlen + 7) / 8
+                   == png_get_rowbytes(state, info));
 }
 
 
@@ -177,6 +194,7 @@
 {
     pngState *png;
     byte *old_row;
+    int rowbytes;
 
     if (!new_row)
         return;
@@ -185,6 +203,7 @@
     if (!png->image)
        return;
 
+    rowbytes = png_get_rowbytes(png->state, png->info);
     old_row = png->image->data + png->image->bytes_per_line * row_num;
 
     png_progressive_combine_row(state, old_row, new_row);
@@ -192,12 +211,12 @@
         /* I can't say I'm too fond of this endian business. */
 #ifdef CHIMERA_LITTLE_ENDIAN
         if (IBITMAP == png->image->type)
-           lc_reverse_byte(old_row, png->info->rowbytes);
+           lc_reverse_byte(old_row, rowbytes);
 #endif
         (png->lineProc)(png->closure, row_num, row_num);
 #ifdef CHIMERA_LITTLE_ENDIAN
         if (IBITMAP == png->image->type)
-           lc_reverse_byte(old_row,png->info->rowbytes);
+           lc_reverse_byte(old_row, rowbytes);
 #endif
     }
 }
@@ -223,14 +242,9 @@
         return;
 
     if (png->state) {
-        png_read_destroy(png->state, png->info, (png_info *) 0);
-        free_mem(png->state);
+        png_destroy_read_struct(&png->state, &png->info, NULL);
         png->state = 0;
-    }
-
-    if (png->info) {
-        free_mem(png->info);
-        png->info = 0;
+       png->info = 0;
     }
 
     if (png->image) {
@@ -275,28 +289,17 @@
     memset(png, 0, sizeof(pngState));
     png->lineProc = lineProc;
     png->closure = closure;
-    png->state = (png_struct *) alloc_mem(sizeof(png_struct));
-    if (!png->state)
-        return;
-
-    png->info = (png_info *) alloc_mem(sizeof(png_info));
-    if (!png->info) {
-        free_mem(png->state);
-        return;
-    }
+    png->state = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
+    png->info = png_create_info_struct(png->state);
+    assert(png->state && png->info);
 
     if (setjmp(png->state->jmpbuf)) {
-        png_read_destroy(png->state, png->info, (png_info *) 0);
-        free_mem(png->state);
-        free_mem(png->info);
+        png_destroy_read_struct(&png->state, &png->info, NULL);
         png->state = 0;
         png->info = 0;
         return;
     }
 
-    png_info_init(png->info);
-    png_read_init(png->state);
-
     png_set_progressive_read_fn(png->state, (void *) png, lf_info_callback,
         lf_row_callback, lf_end_callback);
     png->done = image_need_data;

Reply via email to