diff options
author | Matthias Clasen <matthiasc@src.gnome.org> | 2002-03-25 00:15:00 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2002-03-25 00:15:00 +0000 |
commit | 2a8fc72b0dfd892fe6e47babc2a5a0de5a12e757 (patch) | |
tree | bfd94fd4ba4fb71d5a85104356cd12541d5138f2 /gdk-pixbuf/io-png.c | |
parent | ec1f7614ffdf849212c546c6e5f50d3b582db8a7 (diff) | |
download | gtk+-2a8fc72b0dfd892fe6e47babc2a5a0de5a12e757.tar.gz |
Changed signature to return success and set a GError parameter, adjusted
* io-png.c (setup_png_transformations): Changed signature to
return success and set a GError parameter, adjusted all callers.
Also work around a possible FPE in libpng and always check that
the new info is sane.
Diffstat (limited to 'gdk-pixbuf/io-png.c')
-rw-r--r-- | gdk-pixbuf/io-png.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c index aedd0be18b..c287654d12 100644 --- a/gdk-pixbuf/io-png.c +++ b/gdk-pixbuf/io-png.c @@ -32,20 +32,29 @@ -static void +static gboolean setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr, - gboolean *fatal_error_occurred, + GError **error, png_uint_32* width_p, png_uint_32* height_p, int* color_type_p) { png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_type; -#ifndef G_DISABLE_CHECKS int channels; -#endif /* Get the image info */ + /* Must check bit depth, since png_get_IHDR generates an + FPE on bit_depth 0. + */ + bit_depth = png_get_bit_depth (png_read_ptr, png_info_ptr); + if (bit_depth < 1 || bit_depth > 16) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Bits per channel of PNG image is invalid.")); + return FALSE; + } png_get_IHDR (png_read_ptr, png_info_ptr, &width, &height, &bit_depth, @@ -118,29 +127,42 @@ setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr, *height_p = height; *color_type_p = color_type; -#ifndef G_DISABLE_CHECKS /* Check that the new info is what we want */ + if (width == 0 || height == 0) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG has zero width or height.")); + return FALSE; + } + if (bit_depth != 8) { - g_warning("Bits per channel of transformed PNG is %d, not 8.", bit_depth); - *fatal_error_occurred = TRUE; - return; + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Bits per channel of transformed PNG is not 8.")); + return FALSE; } if ( ! (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) ) { - g_warning("Transformed PNG not RGB or RGBA."); - *fatal_error_occurred = TRUE; - return; + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG not RGB or RGBA.")); + return FALSE; } channels = png_get_channels(png_read_ptr, png_info_ptr); if ( ! (channels == 3 || channels == 4) ) { - g_warning("Transformed PNG has %d channels, must be 3 or 4.", channels); - *fatal_error_occurred = TRUE; - return; + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG has unsupported number of channels, must be 3 or 4.")); + return FALSE; } -#endif + return TRUE; } static void @@ -208,7 +230,6 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error) png_structp png_ptr; png_infop info_ptr, end_info; png_textp text_ptr; - gboolean failed = FALSE; gint i, ctype, bpp; png_uint_32 w, h; png_bytepp volatile rows = NULL; @@ -249,9 +270,7 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error) png_init_io (png_ptr, f); png_read_info (png_ptr, info_ptr); - setup_png_transformations(png_ptr, info_ptr, &failed, &w, &h, &ctype); - - if (failed) { + if (!setup_png_transformations(png_ptr, info_ptr, error, &w, &h, &ctype)) { png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); return NULL; } @@ -558,19 +577,16 @@ png_info_callback (png_structp png_read_ptr, int i, num_texts; int color_type; gboolean have_alpha = FALSE; - gboolean failed = FALSE; lc = png_get_progressive_ptr(png_read_ptr); if (lc->fatal_error_occurred) return; - setup_png_transformations(lc->png_read_ptr, - lc->png_info_ptr, - &failed, - &width, &height, &color_type); - - if (failed) { + if (!setup_png_transformations(lc->png_read_ptr, + lc->png_info_ptr, + lc->error, + &width, &height, &color_type)) { lc->fatal_error_occurred = TRUE; return; } |