Commit 9729b868 authored by Joerg Fellmann's avatar Joerg Fellmann

Fixed crash in case of some malformed jpegs

With certain malformed jpegs the call to jpeg_finish_decompress
caused a long jump back to stop_loading. This jump overwrote the
value of the surface pointer which should be NULL which in turn 
caused a cairo assert when trying to get a reference to a surface
with ref_count = 0.

Also moved the cleanup of in_buffer out of the !finished scope, 
as it seems this would otherwise be a potential leak.
parent 48edd08b
......@@ -183,7 +183,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
unsigned char *p_buffer;
int x;
gboolean read_all_scanlines = FALSE;
gboolean finished = FALSE;
volatile gboolean finished = FALSE;
image = gth_image_new ();
surface = NULL;
......@@ -564,59 +564,62 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
stop_loading:
if (surface != NULL) {
cairo_surface_mark_dirty (surface);
if (! finished) {
finished = TRUE;
if (! g_cancellable_is_cancelled (cancellable)) {
int original_width;
int original_height;
if (surface != NULL) {
cairo_surface_mark_dirty (surface);
/* Set the original dimensions */
if (! g_cancellable_is_cancelled (cancellable)) {
int original_width;
int original_height;
if ((orientation == GTH_TRANSFORM_ROTATE_90)
|| (orientation == GTH_TRANSFORM_ROTATE_270)
|| (orientation == GTH_TRANSFORM_TRANSPOSE)
|| (orientation == GTH_TRANSFORM_TRANSVERSE))
{
original_width = srcinfo.image_height;
original_height = srcinfo.image_width;
}
else {
original_width = srcinfo.image_width;
original_height = srcinfo.image_height;
}
/* Set the original dimensions */
_cairo_metadata_set_original_size (metadata, original_width, original_height);
if ((orientation == GTH_TRANSFORM_ROTATE_90)
|| (orientation == GTH_TRANSFORM_ROTATE_270)
|| (orientation == GTH_TRANSFORM_TRANSPOSE)
|| (orientation == GTH_TRANSFORM_TRANSVERSE))
{
original_width = srcinfo.image_height;
original_height = srcinfo.image_width;
}
else {
original_width = srcinfo.image_width;
original_height = srcinfo.image_height;
}
if (original_width_p != NULL)
*original_width_p = original_width;
if (original_height_p != NULL)
*original_height_p = original_height;
if (loaded_original_p != NULL)
*loaded_original_p = ! load_scaled;
_cairo_metadata_set_original_size (metadata, original_width, original_height);
/*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); FIXME*/
/* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace", jpeg_color_space_name (srcinfo.jpeg_color_space)); */
if (original_width_p != NULL)
*original_width_p = original_width;
if (original_height_p != NULL)
*original_height_p = original_height;
if (loaded_original_p != NULL)
*loaded_original_p = ! load_scaled;
gth_image_set_cairo_surface (image, surface);
}
else
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
/*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); FIXME*/
/* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace", jpeg_color_space_name (srcinfo.jpeg_color_space)); */
cairo_surface_destroy (surface);
surface = NULL; /* ignore other jpeg errors */
}
gth_image_set_cairo_surface (image, surface);
}
else
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
cairo_surface_destroy (surface);
surface = NULL; /* ignore other jpeg errors */
}
if (! finished) {
finished = TRUE;
if (read_all_scanlines)
jpeg_finish_decompress (&srcinfo);
else
jpeg_abort_decompress (&srcinfo);
jpeg_destroy_decompress (&srcinfo);
g_free (in_buffer);
}
g_free (in_buffer);
return image;
}
......
Markdown is supported
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