Robustness fixes and test images for the jpeg, tiff, pnm, gif, xpm and tga

loaders.
This commit is contained in:
Matthias Clasen 2001-09-14 22:04:55 +00:00
parent a5f9754350
commit 49b3e05a30
10 changed files with 5402 additions and 100 deletions

View File

@ -1,3 +1,34 @@
Fri Sep 14 22:53:45 2001 Matthias Clasen <matthiasc@poet.de>
* io-jpeg.c (gdk_pixbuf__jpeg_image_begin_load): Handle
out-of-memory situation better.
* io-pnm.c: Robustness fixes for pnm loader
* io-gif.c: Make gif loader survive TEST_RANDOMLY_MODIFY
* io-xpm.c (parse_color): detect very long color strings
All of the above from Matthias Clasen <matthiasc@poet.de>,
the remaining from Soeren Sandmann <sandmann@daimi.au.dk>.
* test-images.h: add tests:
- four valid ppm's, eight invalid (matthiasc@poet.de)
- one invalid xpm (matthiasc@poet.de)
- one valid tga, one invalid (sandmann@daimi.au.dk)
- one invalid tiff (sandmann@daimi.au.dk
* test-loaders.c: enable tests for ppm, png, gif, tga, tiff, xpm
* io-tiff.c (gdk_pixbuf__tiff_image_stop_load): TIFFClientOpen can
fail - detect it when it happens
* io-tga.c (gdk_pixbuf__tga_load_increment): Fail if there is too
much data in file
* gdk-pixbuf-io.c: moved wbmb check after ico check to avoid false
positives
Fri Sep 14 00:30:48 2001 Tim Janik <timj@gtk.org> Fri Sep 14 00:30:48 2001 Tim Janik <timj@gtk.org>
* Makefile.am: don't used BUILT_SOURCES to build marshal * Makefile.am: don't used BUILT_SOURCES to build marshal

View File

@ -228,12 +228,12 @@ static GdkPixbufModule file_formats [] = {
{ "pnm", pixbuf_check_pnm, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "pnm", pixbuf_check_pnm, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "ras", pixbuf_check_sunras, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "ras", pixbuf_check_sunras, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "bmp", pixbuf_check_bmp, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "bmp", pixbuf_check_bmp, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "wbmp", pixbuf_check_wbmp, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "xbm", pixbuf_check_xbm, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "xbm", pixbuf_check_xbm, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "tga", pixbuf_check_tga, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "tga", pixbuf_check_tga, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
/* Moved at the bottom, because it causes false positives against many /* Moved at the bottom, because it causes false positives against many
of my TGA files. */ of my TGA files. */
{ "ico", pixbuf_check_ico, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "ico", pixbuf_check_ico, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "wbmp", pixbuf_check_wbmp, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
}; };

View File

@ -613,6 +613,14 @@ lzw_read_byte (GifContext *context)
} }
while (code >= context->lzw_clear_code) { while (code >= context->lzw_clear_code) {
if ((code >= (1 << MAX_LZW_BITS))
|| (context->lzw_sp >= context->lzw_stack + ((1 << (MAX_LZW_BITS)) * 2 + 1))) {
g_set_error (context->error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Bad code encountered"));
return -2;
}
*(context->lzw_sp)++ = context->lzw_table[1][code]; *(context->lzw_sp)++ = context->lzw_table[1][code];
if (code == context->lzw_table[0][code]) { if (code == context->lzw_table[0][code]) {
@ -1038,7 +1046,7 @@ gif_init (GifContext *context)
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("File does not appear to be a GIF file")); _("File does not appear to be a GIF file"));
return -1; return -2;
} }
strncpy (version, (char *) buf + 3, 3); strncpy (version, (char *) buf + 3, 3);
@ -1051,7 +1059,7 @@ gif_init (GifContext *context)
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Version %s of the GIF file format is not supported"), _("Version %s of the GIF file format is not supported"),
version); version);
return -1; return -2;
} }
/* read the screen descriptor */ /* read the screen descriptor */

View File

@ -337,7 +337,16 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func,
/* create libjpeg structures */ /* create libjpeg structures */
jpeg_create_decompress (&context->cinfo); jpeg_create_decompress (&context->cinfo);
context->cinfo.src = (struct jpeg_source_mgr *) g_new0 (my_source_mgr, 1); context->cinfo.src = (struct jpeg_source_mgr *) g_try_malloc (sizeof (my_source_mgr));
if (!context->cinfo.src) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Couldn't allocate memory for loading JPEG file"));
return NULL;
}
memset (context->cinfo.src, 0, sizeof (my_source_mgr));
src = (my_src_ptr) context->cinfo.src; src = (my_src_ptr) context->cinfo.src;
context->cinfo.err = jpeg_std_error (&context->jerr.pub); context->cinfo.err = jpeg_std_error (&context->jerr.pub);

View File

@ -23,7 +23,6 @@
*/ */
#include <config.h> #include <config.h>
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -203,7 +202,7 @@ pnm_skip_whitespace (PnmIOBuffer *inbuf, GError **error)
return PNM_SUSPEND; return PNM_SUSPEND;
} }
} else if (!isspace (*inptr)) { } else if (!g_ascii_isspace (*inptr)) {
inbuf->byte = inptr; inbuf->byte = inptr;
inbuf->nbytes = (guint) (inend - inptr); inbuf->nbytes = (guint) (inend - inptr);
return PNM_OK; return PNM_OK;
@ -221,9 +220,10 @@ static gint
pnm_read_next_value (PnmIOBuffer *inbuf, guint *value, GError **error) pnm_read_next_value (PnmIOBuffer *inbuf, guint *value, GError **error)
{ {
register guchar *inptr, *word, *p; register guchar *inptr, *word, *p;
guchar *inend, buf[128]; guchar *inend, buf[129];
gchar *endptr; gchar *endptr;
gint retval; gint retval;
glong result;
g_return_val_if_fail (inbuf != NULL, PNM_FATAL_ERR); g_return_val_if_fail (inbuf != NULL, PNM_FATAL_ERR);
g_return_val_if_fail (inbuf->byte != NULL, PNM_FATAL_ERR); g_return_val_if_fail (inbuf->byte != NULL, PNM_FATAL_ERR);
@ -237,23 +237,24 @@ pnm_read_next_value (PnmIOBuffer *inbuf, guint *value, GError **error)
inptr = inbuf->byte; inptr = inbuf->byte;
/* copy this pnm 'word' into a temp buffer */ /* copy this pnm 'word' into a temp buffer */
for (p = inptr, word = buf; (p < inend) && !isspace (*p) && (p - inptr < 128); p++, word++) for (p = inptr, word = buf; (p < inend) && !g_ascii_isspace (*p) && (*p != '#') && (p - inptr < 128); p++, word++)
*word = *p; *word = *p;
*word = '\0'; *word = '\0';
/* hmmm, there must be more data to this 'word' */ /* hmmm, there must be more data to this 'word' */
if (!isspace (*p)) if (!g_ascii_isspace (*p) && (*p != '#') && (p - inptr < 128))
return PNM_SUSPEND; return PNM_SUSPEND;
/* get the value */ /* get the value */
*value = strtol (buf, &endptr, 10); result = strtol (buf, &endptr, 10);
if (*endptr != '\0') { if (*endptr != '\0' || result < 0) {
g_set_error (error, g_set_error (error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("PNM loader expected to find an integer, but didn't")); _("PNM loader expected to find an integer, but didn't"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
*value = result;
inbuf->byte = p; inbuf->byte = p;
inbuf->nbytes = (guint) (inend - p); inbuf->nbytes = (guint) (inend - p);
@ -281,7 +282,7 @@ pnm_read_header (PnmLoaderContext *context)
if (*inbuf->byte != 'P') { if (*inbuf->byte != 'P') {
g_set_error (context->error, g_set_error (context->error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("PNM file has an incorrect initial byte")); _("PNM file has an incorrect initial byte"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
@ -311,7 +312,7 @@ pnm_read_header (PnmLoaderContext *context)
default: default:
g_set_error (context->error, g_set_error (context->error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("PNM file is not in a recognized PNM subformat")); _("PNM file is not in a recognized PNM subformat"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
@ -336,7 +337,7 @@ pnm_read_header (PnmLoaderContext *context)
if (!width) { if (!width) {
g_set_error (context->error, g_set_error (context->error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("PNM file has an image width of 0")); _("PNM file has an image width of 0"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
@ -357,7 +358,7 @@ pnm_read_header (PnmLoaderContext *context)
if (!height) { if (!height) {
g_set_error (context->error, g_set_error (context->error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("PNM file has an image height of 0")); _("PNM file has an image height of 0"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
@ -380,10 +381,26 @@ pnm_read_header (PnmLoaderContext *context)
if (context->maxval == 0) { if (context->maxval == 0) {
g_set_error (context->error, g_set_error (context->error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("Maximum color value in PNM file is 0")); _("Maximum color value in PNM file is 0"));
return PNM_FATAL_ERR; return PNM_FATAL_ERR;
} }
if (context->maxval > 65535) {
g_set_error (context->error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("Maximum color value in PNM file is too large"));
return PNM_FATAL_ERR;
}
if (context->maxval > 255) {
g_set_error (context->error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_HEADER_CORRUPT,
_("Can't handle PNM files with maximum color values greater than 255"));
return PNM_FATAL_ERR;
}
} }
break; break;
default: default:
@ -677,7 +694,7 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error)
inbuf = &context.inbuf; inbuf = &context.inbuf;
while (!feof (f)) { while (TRUE) {
guint num_to_read; guint num_to_read;
/* keep buffer as full as possible */ /* keep buffer as full as possible */
@ -689,11 +706,14 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error)
nbytes = fread (inbuf->buffer + inbuf->nbytes, 1, num_to_read, f); nbytes = fread (inbuf->buffer + inbuf->nbytes, 1, num_to_read, f);
/* error checking */ /* error checking */
if (nbytes == 0 && ferror (f)) { if (nbytes == 0) {
/* we ran out of data? */ /* we ran out of data? */
if (context.pixbuf) if (context.pixbuf)
gdk_pixbuf_unref (context.pixbuf); gdk_pixbuf_unref (context.pixbuf);
g_warning ("io-pnm.c: Ran out of data.\n"); g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Premature end-of-file encountered"));
return NULL; return NULL;
} }
@ -713,23 +733,47 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error)
/* scan until we hit image data */ /* scan until we hit image data */
if (!context.did_prescan) { if (!context.did_prescan) {
switch (context.type) {
case PNM_FORMAT_PBM_RAW:
case PNM_FORMAT_PGM_RAW:
case PNM_FORMAT_PPM_RAW:
if (inbuf->nbytes <= 0)
continue;
/* raw formats require exactly one whitespace */
if (!g_ascii_isspace(*(inbuf->byte)))
{
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Raw PNM formats require exactly one whitespace before sample data"));
return NULL;
}
inbuf->nbytes--;
inbuf->byte++;
break;
default:
retval = pnm_skip_whitespace (inbuf, retval = pnm_skip_whitespace (inbuf,
context.error); context.error);
if (retval == PNM_FATAL_ERR) if (retval == PNM_FATAL_ERR)
return NULL; return NULL;
else if (retval == PNM_SUSPEND) else if (retval == PNM_SUSPEND)
continue; continue;
break;
}
context.did_prescan = TRUE; context.did_prescan = TRUE;
context.output_row = 0; context.output_row = 0;
context.output_col = 0; context.output_col = 0;
context.rowstride = context.width * 3; context.rowstride = context.width * 3;
context.pixels = g_malloc (context.height * context.width * 3); context.pixels = g_try_malloc (context.height * context.width * 3);
if (!context.pixels) { if (!context.pixels) {
/* Failed to allocate memory */ /* Failed to allocate memory */
g_warning ("Couldn't allocate pixel buf"); g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Can't allocate memory for loading PNM image"));
return NULL;
} }
} }
@ -773,7 +817,14 @@ gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func,
{ {
PnmLoaderContext *context; PnmLoaderContext *context;
context = g_new0 (PnmLoaderContext, 1); context = g_try_malloc (sizeof (PnmLoaderContext));
if (!context) {
g_set_error(error, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Insufficient memory to load PNM context struct"));
return NULL;
}
memset (context, 0, sizeof (PnmLoaderContext));
context->prepared_func = prepared_func; context->prepared_func = prepared_func;
context->updated_func = updated_func; context->updated_func = updated_func;
context->user_data = user_data; context->user_data = user_data;
@ -811,6 +862,11 @@ gdk_pixbuf__pnm_image_stop_load (gpointer data,
if (context->pixbuf) if (context->pixbuf)
gdk_pixbuf_unref (context->pixbuf); gdk_pixbuf_unref (context->pixbuf);
#if 0
/* We should ignore trailing newlines and we can't
generally complain about trailing stuff at all, since
pnm allows to put multiple images in a file
*/
if (context->inbuf.nbytes > 0) { if (context->inbuf.nbytes > 0) {
g_set_error (error, g_set_error (error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
@ -818,6 +874,7 @@ gdk_pixbuf__pnm_image_stop_load (gpointer data,
_("Unexpected end of PNM image data")); _("Unexpected end of PNM image data"));
retval = FALSE; retval = FALSE;
} }
#endif
g_free (context); g_free (context);
@ -895,14 +952,33 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data,
/* scan until we hit image data */ /* scan until we hit image data */
if (!context->did_prescan) { if (!context->did_prescan) {
switch (context->type) {
case PNM_FORMAT_PBM_RAW:
case PNM_FORMAT_PGM_RAW:
case PNM_FORMAT_PPM_RAW:
if (inbuf->nbytes <= 0)
continue;
/* raw formats require exactly one whitespace */
if (!g_ascii_isspace(*(inbuf->byte)))
{
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Raw PNM formats require exactly one whitespace before sample data"));
return FALSE;
}
inbuf->nbytes--;
inbuf->byte++;
break;
default:
retval = pnm_skip_whitespace (inbuf, retval = pnm_skip_whitespace (inbuf,
context->error); context->error);
if (retval == PNM_FATAL_ERR) if (retval == PNM_FATAL_ERR)
return FALSE; return FALSE;
else if (retval == PNM_SUSPEND) else if (retval == PNM_SUSPEND)
continue; continue;
break;
}
context->did_prescan = TRUE; context->did_prescan = TRUE;
context->output_row = 0; context->output_row = 0;
context->output_col = 0; context->output_col = 0;

View File

@ -17,6 +17,9 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
* *
*/
/*
* Some NOTES about the TGA loader (2001/06/07, nikke@swlibero.org) * Some NOTES about the TGA loader (2001/06/07, nikke@swlibero.org)
* *
* - The module doesn't currently provide support for TGA images where the * - The module doesn't currently provide support for TGA images where the
@ -117,6 +120,7 @@ struct _TGAColor {
struct _TGAContext { struct _TGAContext {
TGAHeader *hdr; TGAHeader *hdr;
guint rowstride; guint rowstride;
guint completed_lines;
gboolean run_length_encoded; gboolean run_length_encoded;
TGAColormap *cmap; TGAColormap *cmap;
@ -293,6 +297,7 @@ static gboolean fill_in_context(TGAContext *ctx, GError **err)
else if (ctx->hdr->type == TGA_TYPE_TRUECOLOR) else if (ctx->hdr->type == TGA_TYPE_TRUECOLOR)
ctx->rowstride = ctx->pbuf->rowstride; ctx->rowstride = ctx->pbuf->rowstride;
ctx->completed_lines = 0;
return TRUE; return TRUE;
} }
@ -724,9 +729,16 @@ static gboolean gdk_pixbuf__tga_load_increment(gpointer data,
if (!parse_rle_data(ctx, err)) if (!parse_rle_data(ctx, err))
return FALSE; return FALSE;
} else { } else {
while (ctx->in->size >= ctx->rowstride) while (ctx->in->size >= ctx->rowstride) {
if (ctx->completed_lines >= ctx->pbuf->height) {
g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED,
_("Excess data in file"));
return FALSE;
}
if (!parse_data_for_row(ctx, err)) if (!parse_data_for_row(ctx, err))
return FALSE; return FALSE;
ctx->completed_lines++;
}
} }
return TRUE; return TRUE;

View File

@ -257,9 +257,8 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
fd = fileno (f); fd = fileno (f);
tiff = TIFFFdOpen (fd, "libpixbuf-tiff", "r"); tiff = TIFFFdOpen (fd, "libpixbuf-tiff", "r");
if (!tiff) { if (!tiff || global_error) {
g_set_error (error, tiff_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Failed to open TIFF image")); _("Failed to open TIFF image"));
tiff_pop_handlers (); tiff_pop_handlers ();
@ -404,9 +403,8 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
tiff_seek, tiff_close, tiff_seek, tiff_close,
tiff_size, tiff_size,
tiff_map_file, tiff_unmap_file); tiff_map_file, tiff_unmap_file);
if (!tiff) { if (!tiff || global_error) {
g_set_error (error, tiff_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_FAILED, GDK_PIXBUF_ERROR_FAILED,
_("Failed to load TIFF image")); _("Failed to load TIFF image"));
retval = FALSE; retval = FALSE;
@ -418,10 +416,16 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
g_object_unref (G_OBJECT (pixbuf)); g_object_unref (G_OBJECT (pixbuf));
retval = pixbuf != NULL; retval = pixbuf != NULL;
TIFFClose (tiff); TIFFClose (tiff);
if (global_error)
{
tiff_set_error (error,
GDK_PIXBUF_ERROR_FAILED,
_("Failed to load TIFF image"));
retval = FALSE;
}
} }
if (global_error) g_assert (!global_error);
g_warning ("Error left set in TIFF loader\n");
g_free (context->buffer); g_free (context->buffer);
g_free (context); g_free (context);

View File

@ -1,3 +1,4 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* GdkPixbuf library - XPM image loader /* GdkPixbuf library - XPM image loader
* *
* Copyright (C) 1999 Mark Crichton * Copyright (C) 1999 Mark Crichton
@ -926,7 +927,7 @@ find_color(const char *name,
* Partial implementation of X color name parsing interface. * Partial implementation of X color name parsing interface.
* *
* Results: * Results:
* Returns non-zero on success. * Returns TRUE on success.
* *
* Side effects: * Side effects:
* None. * None.
@ -947,7 +948,8 @@ parse_color (const char *spec,
} }
i /= 3; i /= 3;
sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i); g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i);
if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) { if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) {
return FALSE; return FALSE;
} }
@ -977,20 +979,13 @@ parse_color (const char *spec,
} }
static gint static gint
xpm_seek_string (FILE *infile, const gchar *str, gint skip_comments) xpm_seek_string (FILE *infile, const gchar *str)
{ {
char instr[1024]; char instr[1024];
while (!feof (infile)) { while (!feof (infile)) {
if (fscanf (infile, "%1023s", instr) < 0) if (fscanf (infile, "%1023s", instr) < 0)
return FALSE; return FALSE;
if (skip_comments == TRUE && strcmp (instr, "/*") == 0) {
fscanf (infile, "%1023s", instr);
while (!feof (infile) && strcmp (instr, "*/") != 0)
fscanf (infile, "%1023s", instr);
fscanf (infile, "%1023s", instr);
}
if (strcmp (instr, str) == 0) if (strcmp (instr, str) == 0)
return TRUE; return TRUE;
} }
@ -1176,7 +1171,7 @@ file_buffer (enum buf_op op, gpointer handle)
switch (op) { switch (op) {
case op_header: case op_header:
if (xpm_seek_string (h->infile, "XPM", FALSE) != TRUE) if (xpm_seek_string (h->infile, "XPM") != TRUE)
break; break;
if (xpm_seek_char (h->infile, '{') != TRUE) if (xpm_seek_char (h->infile, '{') != TRUE)
@ -1258,11 +1253,35 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
return NULL; return NULL;
} }
sscanf (buffer, "%d %d %d %d", &w, &h, &n_col, &cpp); sscanf (buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
if (cpp >= 32) { if (w <= 0) {
g_set_error (error, g_set_error (error,
GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("XPM has more than 31 chars per pixel")); _("XPM file has image width <= 0"));
return NULL;
}
if (h <= 0) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("XPM file has image height <= 0"));
return NULL;
}
if (n_col <= 0) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("XPM file has invalid number of colors"));
return NULL;
}
if (cpp <= 0 || cpp >= 32) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("XPM has invalid number of chars per pixel"));
return NULL; return NULL;
} }
@ -1430,7 +1449,6 @@ gdk_pixbuf__xpm_image_begin_load (ModulePreparedNotifyFunc prepare_func,
XPMContext *context; XPMContext *context;
gint fd; gint fd;
g_warning ("load start");
context = g_new (XPMContext, 1); context = g_new (XPMContext, 1);
context->prepare_func = prepare_func; context->prepare_func = prepare_func;
context->update_func = update_func; context->update_func = update_func;

File diff suppressed because it is too large Load Diff

View File

@ -285,7 +285,7 @@ randomly_modify (const guchar *image, guint size, gboolean verbose)
#define TEST(bytes, data_is_ok) \ #define TEST(bytes, data_is_ok) \
do { \ do { \
g_print ("%-30s", " " #bytes " "); \ g_print ("%-40s", " " #bytes " "); \
fflush (stdout); \ fflush (stdout); \
if (test_loader (bytes, sizeof (bytes), data_is_ok)) \ if (test_loader (bytes, sizeof (bytes), data_is_ok)) \
g_print ("\tpassed\n"); \ g_print ("\tpassed\n"); \
@ -295,7 +295,7 @@ do { \
#define LOWMEMTEST(bytes) \ #define LOWMEMTEST(bytes) \
do { \ do { \
g_print ("%-30s", "memory " #bytes " "); \ g_print ("%-40s", "memory " #bytes " "); \
fflush (stdout); \ fflush (stdout); \
mem_test (bytes, sizeof (bytes)); \ mem_test (bytes, sizeof (bytes)); \
g_print ("\tpassed\n"); \ g_print ("\tpassed\n"); \
@ -304,19 +304,19 @@ do { \
#define TEST_RANDOM(header, n_img, verbose) \ #define TEST_RANDOM(header, n_img, verbose) \
do { \ do { \
static guchar h[] = { header }; \ static guchar h[] = { header }; \
g_print ("%-30s", "random " #header " "); \ g_print ("%-40s", "random " #header " "); \
fflush (stdout); \ fflush (stdout); \
assault (h, sizeof (h), n_img, verbose); \ assault (h, sizeof (h), n_img, verbose); \
g_print ("\tpassed\n"); \ g_print ("\tpassed\n"); \
} while (0); } while (0)
#define TEST_RANDOMLY_MODIFIED(image, verbose) \ #define TEST_RANDOMLY_MODIFIED(image, verbose) \
do { \ do { \
g_print ("%-30s", "randomly modified " #image " "); \ g_print ("%-40s", "randomly modified " #image " "); \
fflush (stdout); \ fflush (stdout); \
randomly_modify (image, sizeof (image), verbose); \ randomly_modify (image, sizeof (image), verbose); \
g_print ("\tpassed\n"); \ g_print ("\tpassed\n"); \
} while (0); } while (0)
@ -372,10 +372,24 @@ main (int argc, char **argv)
g_random_set_seed (seed); g_random_set_seed (seed);
g_type_init (); g_type_init ();
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
putenv ("GDK_PIXBUF_MODULEDIR="BUILT_MODULES_DIR); putenv ("GDK_PIXBUF_MODULEDIR="BUILT_MODULES_DIR);
TEST (valid_ppm_1, TRUE);
TEST (valid_ppm_2, TRUE);
TEST (valid_ppm_3, FALSE); /* image is valid, but we don't handle maxval > 255 */
TEST (valid_ppm_4, TRUE);
TEST (invalid_ppm_1, FALSE); /* this test fails to fail, because it's shorter than LOADER_HEADER_SIZE */
TEST (invalid_ppm_2, FALSE);
TEST (invalid_ppm_3, FALSE);
TEST (invalid_ppm_4, FALSE);
TEST (invalid_ppm_5, FALSE);
TEST (invalid_ppm_6, FALSE);
TEST (invalid_ppm_7, FALSE);
TEST (invalid_ppm_8, FALSE);
TEST (valid_gif_test, TRUE); TEST (valid_gif_test, TRUE);
TEST (gif_test_1, FALSE); TEST (gif_test_1, FALSE);
TEST (gif_test_2, FALSE); TEST (gif_test_2, FALSE);
@ -384,31 +398,39 @@ main (int argc, char **argv)
TEST (valid_png_test, TRUE); TEST (valid_png_test, TRUE);
TEST (png_test_1, FALSE); TEST (png_test_1, FALSE);
TEST (png_test_2, FALSE);
#if 0
TEST (valid_ico_test, TRUE); TEST (valid_ico_test, TRUE);
#endif
TEST (ico_test_1, FALSE); TEST (ico_test_1, FALSE);
#if 0
TEST (wbmp_test_1, FALSE);
TEST (wbmp_test_2, FALSE);
#endif
#if 0
TEST (png_test_2, FALSE);
#endif
TEST (valid_jpeg_test, TRUE); TEST (valid_jpeg_test, TRUE);
TEST (valid_tiff1_test, TRUE); TEST (valid_tiff1_test, TRUE);
TEST (tiff1_test_1, FALSE); TEST (tiff1_test_1, FALSE);
TEST (tiff1_test_2, FALSE);
TEST (valid_tga_test, TRUE);
TEST (tga_test_1, FALSE);
TEST (xpm_test_1, FALSE);
TEST_RANDOM (GIF_HEADER, 150, FALSE);
TEST_RANDOM (PNG_HEADER, 1100, FALSE);
TEST_RANDOM (JPEG_HEADER, 800, FALSE);
TEST_RANDOM (TIFF1_HEADER, 150, FALSE);
TEST_RANDOM (TIFF2_HEADER, 150, FALSE);
#define PNM_HEADER 'P', '6'
TEST_RANDOM (PNM_HEADER, 150, FALSE);
#if 0
TEST_RANDOMLY_MODIFIED (valid_gif_test, FALSE); /* these all break more or */
TEST_RANDOMLY_MODIFIED (valid_png_test, FALSE); /* less spectacularly, patched or not */
TEST_RANDOMLY_MODIFIED (valid_tiff1_test, FALSE); TEST_RANDOMLY_MODIFIED (valid_tiff1_test, FALSE);
#endif TEST_RANDOMLY_MODIFIED (valid_gif_test, FALSE);
TEST_RANDOMLY_MODIFIED (valid_png_test, FALSE);
TEST_RANDOMLY_MODIFIED (valid_tga_test, FALSE);
TEST_RANDOMLY_MODIFIED (valid_jpeg_test, FALSE); /* The jpeg loader does not break */
#if 0 #if 0
TEST_RANDOMLY_MODIFIED (valid_ico_test, TRUE); /* The ico loader does not seem to TEST_RANDOMLY_MODIFIED (valid_ico_test, TRUE); /* The ico loader does not seem to
* break, but the image tend to * break, but the image tend to
@ -416,16 +438,10 @@ main (int argc, char **argv)
* the wbmp loader is broken * the wbmp loader is broken
*/ */
#endif #endif
TEST_RANDOMLY_MODIFIED (valid_jpeg_test, FALSE); /* The jpeg loader does not break */
#if 0 #if 0
TEST_RANDOM (GIF_HEADER, 150, FALSE); TEST (wbmp_test_1, FALSE);
TEST_RANDOM (PNG_HEADER, 10000, FALSE); TEST (wbmp_test_2, FALSE);
TEST_RANDOM (JPEG_HEADER, 8000, FALSE);
TEST_RANDOM (TIFF1_HEADER, 150, FALSE);
TEST_RANDOM (TIFF2_HEADER, 150, FALSE);
#endif #endif
/* memory tests */ /* memory tests */
/* How do the loaders behave when memory is low? /* How do the loaders behave when memory is low?