pnm loader fixes and tests



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]