Commit 74495943 authored by Jacob Boerema's avatar Jacob Boerema
Browse files

app: check for invalid offsets when loading XCF files

More safety checks for detecting broken xcf files, also based on examining
issue #8230.

After reading an offset where layer, channel, etc. data is stored, we
add a check to make sure that offset is not before where we read the
offset value. Because the data is always written after the offset that
points to it.

(cherry picked from commit a8428692)
parent e7d4b580
Pipeline #405286 passed with stages
in 31 minutes and 33 seconds
......@@ -485,6 +485,13 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
if (offset < saved_pos)
{
GIMP_LOG (XCF, "Invalid layer offset: %" G_GOFFSET_FORMAT
" at offset: %" G_GOFFSET_FORMAT, offset, saved_pos);
goto error;
}
/* seek to the layer offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
......@@ -625,6 +632,13 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
if (offset < saved_pos)
{
GIMP_LOG (XCF, "Invalid channel offset: %" G_GOFFSET_FORMAT
" at offset: % "G_GOFFSET_FORMAT, offset, saved_pos);
goto error;
}
/* seek to the channel offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
......@@ -634,6 +648,7 @@ xcf_load_image (Gimp *gimp,
if (!channel)
{
n_broken_channels++;
GIMP_LOG (XCF, "Failed to load channel.");
if (! xcf_seek_pos (info, saved_pos, NULL))
goto error;
......@@ -1891,6 +1906,7 @@ xcf_load_layer (XcfInfo *info,
const Babl *format;
gboolean is_fs_drawable;
gchar *name;
goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
......@@ -2008,6 +2024,7 @@ xcf_load_layer (XcfInfo *info,
}
/* read the hierarchy and layer mask offsets */
cur_offset = info->cp;
xcf_read_offset (info, &hierarchy_offset, 1);
xcf_read_offset (info, &layer_mask_offset, 1);
......@@ -2017,6 +2034,11 @@ xcf_load_layer (XcfInfo *info,
*/
if (! gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
if (hierarchy_offset < cur_offset)
{
GIMP_LOG (XCF, "Invalid layer hierarchy offset!");
goto error;
}
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
......@@ -2040,6 +2062,11 @@ xcf_load_layer (XcfInfo *info,
/* read in the layer mask */
if (layer_mask_offset != 0)
{
if (layer_mask_offset < cur_offset)
{
GIMP_LOG (XCF, "Invalid layer mask offset!");
goto error;
}
if (! xcf_seek_pos (info, layer_mask_offset, NULL))
goto error;
......@@ -2096,6 +2123,7 @@ xcf_load_channel (XcfInfo *info,
gboolean is_fs_drawable;
gchar *name;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
......@@ -2128,9 +2156,16 @@ xcf_load_channel (XcfInfo *info,
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */
/* read the hierarchy offset */
cur_offset = info->cp;
xcf_read_offset (info, &hierarchy_offset, 1);
if (hierarchy_offset < cur_offset)
{
GIMP_LOG (XCF, "Invalid hierarchy offset!");
goto error;
}
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
......@@ -2174,6 +2209,7 @@ xcf_load_layer_mask (XcfInfo *info,
gboolean is_fs_drawable;
gchar *name;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
......@@ -2207,9 +2243,16 @@ xcf_load_layer_mask (XcfInfo *info,
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */
/* read the hierarchy offset */
cur_offset = info->cp;
xcf_read_offset (info, &hierarchy_offset, 1);
if (hierarchy_offset < cur_offset)
{
GIMP_LOG (XCF, "Invalid hierarchy offset!");
goto error;
}
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
......@@ -2247,6 +2290,7 @@ xcf_load_buffer (XcfInfo *info,
gint width;
gint height;
gint bpp;
goffset cur_offset;
format = gegl_buffer_get_format (buffer);
......@@ -2262,8 +2306,15 @@ xcf_load_buffer (XcfInfo *info,
bpp != babl_format_get_bytes_per_pixel (format))
return FALSE;
cur_offset = info->cp;
xcf_read_offset (info, &offset, 1); /* top level */
if (offset < cur_offset)
{
GIMP_LOG (XCF, "Invalid buffer offset!");
return FALSE;
}
/* seek to the level offset */
if (! xcf_seek_pos (info, offset, NULL))
return FALSE;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment