When greeted with a cheerfully corrupt poli^M^M^M^MXCF file, GIMP will 1)

Wed Nov 17 22:45:35 GMT 1999  Adam D. Moss <adam@gimp.org>

	* app/xcf.c: When greeted with a cheerfully corrupt poli^M^M^M^MXCF
	file, GIMP will 1) live a long and fruitful life rather than crash
	and burn, and 2) read as much as is reasonable and issue a
	warning about only being able to partially load the file.
This commit is contained in:
GMT 1999 Adam D. Moss 1999-11-17 22:50:54 +00:00 committed by Adam D. Moss
parent df8b445be6
commit 875217fc9f
3 changed files with 129 additions and 10 deletions

View File

@ -1,3 +1,10 @@
Wed Nov 17 22:45:35 GMT 1999 Adam D. Moss <adam@gimp.org>
* app/xcf.c: When greeted with a cheerfully corrupt poli^M^M^M^MXCF
file, GIMP will 1) live a long and fruitful life rather than crash
and burn, and 2) read as much as is reasonable and issue a
warning about only being able to partially load the file.
Wed Nov 17 17:48:50 CET 1999 Marc Lehmann <pcg@goof.com>
* libgimp/*: Updated header comment from LGPL2.0 to LGPL2.1, where

View File

@ -1641,6 +1641,7 @@ xcf_load_image (XcfInfo *info)
int width;
int height;
int image_type;
int num_successful_elements = 0;
/* read in the image width, height and type */
info->cp += xcf_read_int32 (info->fp, (guint32*) &width, 1);
@ -1654,7 +1655,7 @@ xcf_load_image (XcfInfo *info)
/* read the image properties */
if (!xcf_load_image_props (info, gimage))
goto error;
goto hard_error;
while (1)
{
@ -1680,6 +1681,8 @@ xcf_load_image (XcfInfo *info)
if (!layer)
goto error;
num_successful_elements++;
/* add the layer to the image if its not the floating selection */
if (layer != info->floating_sel)
gimage_add_layer (gimage, layer, g_slist_length (gimage->layers));
@ -1714,6 +1717,8 @@ xcf_load_image (XcfInfo *info)
if (!channel)
goto error;
num_successful_elements++;
/* add the channel to the image if its not the selection */
if (channel != gimage->selection_mask)
gimage_add_channel (gimage, channel, -1);
@ -1734,7 +1739,16 @@ xcf_load_image (XcfInfo *info)
return gimage;
error:
error:
if (num_successful_elements == 0)
goto hard_error;
g_message("XCF: This file is corrupt! I have loaded as much\nof it as I can, but it is incomplete.");
return gimage;
hard_error:
g_message("XCF: This file is corrupt! I could not even\nsalvage any partial image data from it.");
gimage_delete (gimage);
return NULL;
}
@ -2557,7 +2571,8 @@ xcf_load_tile_rle (XcfInfo *info,
int length;
int bpp;
int i, j;
guchar *xcfdata, *xcfodata;
int nmemb_read_successfully;
guchar *xcfdata, *xcfodata, *xcfdatalimit;
data = tile_data_pointer (tile, 0, 0);
bpp = tile_bpp (tile);
@ -2566,8 +2581,12 @@ xcf_load_tile_rle (XcfInfo *info,
/* we have to use fread instead of xcf_read_* because we may be
reading past the end of the file here */
info->cp += fread ((char*) xcfdata, sizeof (char), data_length, info->fp);
nmemb_read_successfully = fread ((char*) xcfdata, sizeof (char),
data_length, info->fp);
info->cp += nmemb_read_successfully;
xcfdatalimit = &xcfodata[nmemb_read_successfully - 1];
for (i = 0; i < bpp; i++)
{
data = (guchar*)tile_data_pointer (tile, 0, 0) + i;
@ -2576,6 +2595,11 @@ xcf_load_tile_rle (XcfInfo *info,
while (size > 0)
{
if (xcfdata > xcfdatalimit)
{
goto bogus_rle;
}
val = *xcfdata++;
length = val;
@ -2584,6 +2608,11 @@ xcf_load_tile_rle (XcfInfo *info,
length = 255 - (length - 1);
if (length == 128)
{
if (xcfdata >= xcfdatalimit)
{
goto bogus_rle;
}
length = (*xcfdata << 8) + xcfdata[1];
xcfdata += 2;
}
@ -2591,6 +2620,16 @@ xcf_load_tile_rle (XcfInfo *info,
count += length;
size -= length;
if (size < 0)
{
goto bogus_rle;
}
if (&xcfdata[length-1] > xcfdatalimit)
{
goto bogus_rle;
}
while (length-- > 0)
{
*data = *xcfdata++;
@ -2602,6 +2641,11 @@ xcf_load_tile_rle (XcfInfo *info,
length += 1;
if (length == 128)
{
if (xcfdata >= xcfdatalimit)
{
goto bogus_rle;
}
length = (*xcfdata << 8) + xcfdata[1];
xcfdata += 2;
}
@ -2610,7 +2654,14 @@ xcf_load_tile_rle (XcfInfo *info,
size -= length;
if (size < 0)
g_message (_("xcf: uh oh! xcf rle tile loading error: %d"), count);
{
goto bogus_rle;
}
if (xcfdata > xcfdatalimit)
{
goto bogus_rle;
}
val = *xcfdata++;
@ -2624,6 +2675,11 @@ xcf_load_tile_rle (XcfInfo *info,
}
g_free(xcfodata);
return TRUE;
bogus_rle:
if (xcfodata)
g_free(xcfodata);
return FALSE;
}

View File

@ -1641,6 +1641,7 @@ xcf_load_image (XcfInfo *info)
int width;
int height;
int image_type;
int num_successful_elements = 0;
/* read in the image width, height and type */
info->cp += xcf_read_int32 (info->fp, (guint32*) &width, 1);
@ -1654,7 +1655,7 @@ xcf_load_image (XcfInfo *info)
/* read the image properties */
if (!xcf_load_image_props (info, gimage))
goto error;
goto hard_error;
while (1)
{
@ -1680,6 +1681,8 @@ xcf_load_image (XcfInfo *info)
if (!layer)
goto error;
num_successful_elements++;
/* add the layer to the image if its not the floating selection */
if (layer != info->floating_sel)
gimage_add_layer (gimage, layer, g_slist_length (gimage->layers));
@ -1714,6 +1717,8 @@ xcf_load_image (XcfInfo *info)
if (!channel)
goto error;
num_successful_elements++;
/* add the channel to the image if its not the selection */
if (channel != gimage->selection_mask)
gimage_add_channel (gimage, channel, -1);
@ -1734,7 +1739,16 @@ xcf_load_image (XcfInfo *info)
return gimage;
error:
error:
if (num_successful_elements == 0)
goto hard_error;
g_message("XCF: This file is corrupt! I have loaded as much\nof it as I can, but it is incomplete.");
return gimage;
hard_error:
g_message("XCF: This file is corrupt! I could not even\nsalvage any partial image data from it.");
gimage_delete (gimage);
return NULL;
}
@ -2557,7 +2571,8 @@ xcf_load_tile_rle (XcfInfo *info,
int length;
int bpp;
int i, j;
guchar *xcfdata, *xcfodata;
int nmemb_read_successfully;
guchar *xcfdata, *xcfodata, *xcfdatalimit;
data = tile_data_pointer (tile, 0, 0);
bpp = tile_bpp (tile);
@ -2566,8 +2581,12 @@ xcf_load_tile_rle (XcfInfo *info,
/* we have to use fread instead of xcf_read_* because we may be
reading past the end of the file here */
info->cp += fread ((char*) xcfdata, sizeof (char), data_length, info->fp);
nmemb_read_successfully = fread ((char*) xcfdata, sizeof (char),
data_length, info->fp);
info->cp += nmemb_read_successfully;
xcfdatalimit = &xcfodata[nmemb_read_successfully - 1];
for (i = 0; i < bpp; i++)
{
data = (guchar*)tile_data_pointer (tile, 0, 0) + i;
@ -2576,6 +2595,11 @@ xcf_load_tile_rle (XcfInfo *info,
while (size > 0)
{
if (xcfdata > xcfdatalimit)
{
goto bogus_rle;
}
val = *xcfdata++;
length = val;
@ -2584,6 +2608,11 @@ xcf_load_tile_rle (XcfInfo *info,
length = 255 - (length - 1);
if (length == 128)
{
if (xcfdata >= xcfdatalimit)
{
goto bogus_rle;
}
length = (*xcfdata << 8) + xcfdata[1];
xcfdata += 2;
}
@ -2591,6 +2620,16 @@ xcf_load_tile_rle (XcfInfo *info,
count += length;
size -= length;
if (size < 0)
{
goto bogus_rle;
}
if (&xcfdata[length-1] > xcfdatalimit)
{
goto bogus_rle;
}
while (length-- > 0)
{
*data = *xcfdata++;
@ -2602,6 +2641,11 @@ xcf_load_tile_rle (XcfInfo *info,
length += 1;
if (length == 128)
{
if (xcfdata >= xcfdatalimit)
{
goto bogus_rle;
}
length = (*xcfdata << 8) + xcfdata[1];
xcfdata += 2;
}
@ -2610,7 +2654,14 @@ xcf_load_tile_rle (XcfInfo *info,
size -= length;
if (size < 0)
g_message (_("xcf: uh oh! xcf rle tile loading error: %d"), count);
{
goto bogus_rle;
}
if (xcfdata > xcfdatalimit)
{
goto bogus_rle;
}
val = *xcfdata++;
@ -2624,6 +2675,11 @@ xcf_load_tile_rle (XcfInfo *info,
}
g_free(xcfodata);
return TRUE;
bogus_rle:
if (xcfodata)
g_free(xcfodata);
return FALSE;
}