pnm loader fixes and tests
- From: Matthias Clasen <matthiasc poet de>
- To: gtk-devel-list gnome org
- Subject: pnm loader fixes and tests
- Date: Tue, 28 Aug 2001 14:19:20 +0200
Is it ok to commit the following fixes for the pnm loader
together with the tests contained in
http://bugzilla.gnome.org/showattachment.cgi?attach_id=953
? This patch addresses the initial whitespace problem and
a few other problems with invalid pnms.
Matthias
Index: io-pnm.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk-pixbuf/io-pnm.c,v
retrieving revision 1.23
diff -u -3 -p -u -r1.23 io-pnm.c
--- io-pnm.c 2001/07/18 04:25:03 1.23
+++ io-pnm.c 2001/08/28 13:05:53
@@ -224,6 +224,7 @@ pnm_read_next_value (PnmIOBuffer *inbuf,
guchar *inend, buf[128];
gchar *endptr;
gint retval;
+ glong result;
g_return_val_if_fail (inbuf != NULL, PNM_FATAL_ERR);
g_return_val_if_fail (inbuf->byte != NULL, PNM_FATAL_ERR);
@@ -237,24 +238,25 @@ pnm_read_next_value (PnmIOBuffer *inbuf,
inptr = inbuf->byte;
/* 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) && !isspace (*p) && (*p != '#') &&
(p - inptr < 128); p++, word++)
*word = *p;
*word = '\0';
/* hmmm, there must be more data to this 'word' */
- if (!isspace (*p))
- return PNM_SUSPEND;
+ if (!isspace (*p) && (*p != '#'))
+ return PNM_SUSPEND;
/* get the value */
- *value = strtol (buf, &endptr, 10);
- if (*endptr != '\0') {
+ result = strtol (buf, &endptr, 10);
+ if (*endptr != '\0' || result < 0) {
g_set_error (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("PNM loader expected to find an integer, but didn't"));
return PNM_FATAL_ERR;
}
-
+ *value = result;
+
inbuf->byte = p;
inbuf->nbytes = (guint) (inend - p);
@@ -380,10 +382,26 @@ pnm_read_header (PnmLoaderContext *conte
if (context->maxval == 0) {
g_set_error (context->error,
GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+ _("Maximum color value in PNM file is 0"));
+ return PNM_FATAL_ERR;
+ }
+
+ if (context->maxval > 65535) {
+ g_set_error (context->error,
+ GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
- _("Maximum color value in PNM file is 0"));
+ _("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_CORRUPT_IMAGE,
+ _("Can't handle PNM files with maximum color values greater than
255"));
+ return PNM_FATAL_ERR;
+ }
}
break;
default:
@@ -677,7 +695,7 @@ gdk_pixbuf__pnm_image_load (FILE *f, GEr
inbuf = &context.inbuf;
- while (!feof (f)) {
+ while (TRUE) {
guint num_to_read;
/* keep buffer as full as possible */
@@ -689,11 +707,14 @@ gdk_pixbuf__pnm_image_load (FILE *f, GEr
nbytes = fread (inbuf->buffer + inbuf->nbytes, 1, num_to_read, f);
/* error checking */
- if (nbytes == 0 && ferror (f)) {
+ if (nbytes == 0) {
/* we ran out of data? */
if (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;
}
@@ -713,13 +734,33 @@ gdk_pixbuf__pnm_image_load (FILE *f, GEr
/* scan until we hit image data */
if (!context.did_prescan) {
- retval = pnm_skip_whitespace (inbuf,
- context.error);
- if (retval == PNM_FATAL_ERR)
- return NULL;
- else if (retval == PNM_SUSPEND)
- continue;
-
+ 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 (!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,
+ context.error);
+ if (retval == PNM_FATAL_ERR)
+ return NULL;
+ else if (retval == PNM_SUSPEND)
+ continue;
+ break;
+ }
context.did_prescan = TRUE;
context.output_row = 0;
context.output_col = 0;
@@ -895,14 +936,33 @@ gdk_pixbuf__pnm_image_load_increment (gp
/* scan until we hit image data */
if (!context->did_prescan) {
- retval = pnm_skip_whitespace (inbuf,
- context->error);
-
- if (retval == PNM_FATAL_ERR)
- return FALSE;
- else if (retval == PNM_SUSPEND)
- continue;
-
+ 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 (!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,
+ context->error);
+ if (retval == PNM_FATAL_ERR)
+ return NULL;
+ else if (retval == PNM_SUSPEND)
+ continue;
+ break;
+ }
context->did_prescan = TRUE;
context->output_row = 0;
context->output_col = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]