Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-updates-src > by-pkgid > d29742c85f8ae1f24138a86adad7f9da > files > 1

gthumb-3.7.2-2.1.mga7.src.rpm

From 14860321ce3235d420498c4f81f21003d1fb78f4 Mon Sep 17 00:00:00 2001
From: Paolo Bacchilega <paobac@src.gnome.org>
Date: Mon, 16 Dec 2019 21:25:16 +0100
Subject: [PATCH] jpeg loader: crash when the original size is too big for a
 cairo surface

Do not scan more than CAIRO_MAX_IMAGE_SIZE lines.
---
 .../cairo_io/cairo-image-surface-jpeg.c       | 45 ++++++++++++++-----
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/extensions/cairo_io/cairo-image-surface-jpeg.c b/extensions/cairo_io/cairo-image-surface-jpeg.c
index 3453d5a1..8ab26fd2 100644
--- a/extensions/cairo_io/cairo-image-surface-jpeg.c
+++ b/extensions/cairo_io/cairo-image-surface-jpeg.c
@@ -155,6 +155,8 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 	JpegInfoFlags		       info_flags;
 	gboolean                       load_scaled;
 	GthTransform                   orientation;
+	int                            output_width;
+	int                            output_height;
 	int                            destination_width;
 	int                            destination_height;
 	int                            line_start;
@@ -171,6 +173,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 	unsigned char                 *surface_row;
 	JSAMPARRAY                     buffer;
 	int                            buffer_stride;
+	int                            scanned_lines;
 	JDIMENSION                     n_lines;
 	JSAMPARRAY                     buffer_row;
 	int                            l;
@@ -263,9 +266,11 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 	jpeg_start_decompress (&srcinfo);
 
+	output_width = MIN (srcinfo.output_width, CAIRO_MAX_IMAGE_SIZE);
+	output_height = MIN (srcinfo.output_height, CAIRO_MAX_IMAGE_SIZE);
 	_cairo_image_surface_transform_get_steps (CAIRO_FORMAT_ARGB32,
-						  MIN (srcinfo.output_width, CAIRO_MAX_IMAGE_SIZE),
-						  MIN (srcinfo.output_height, CAIRO_MAX_IMAGE_SIZE),
+						  output_width,
+						  output_height,
 						  orientation,
 						  &destination_width,
 						  &destination_height,
@@ -294,6 +299,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 	_cairo_metadata_set_has_alpha (metadata, FALSE);
 	surface_data = _cairo_image_surface_flush_and_get_data (surface);
 	surface_row = surface_data + line_start;
+	scanned_lines = 0;
 
 	switch (srcinfo.out_color_space) {
 	case JCS_CMYK:
@@ -304,11 +310,13 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 			CMYK_table_init ();
 			cmyk_tab = CMYK_Tab;
 
-			while (srcinfo.output_scanline < srcinfo.output_height) {
+			while (srcinfo.output_scanline < output_height) {
 				if (g_cancellable_is_cancelled (cancellable))
 					goto stop_loading;
 
 				n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+				if (scanned_lines + n_lines > output_height)
+					n_lines = output_height - scanned_lines;
 
 				buffer_row = buffer;
 				for (l = 0; l < n_lines; l++) {
@@ -318,7 +326,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 					if (g_cancellable_is_cancelled (cancellable))
 						goto stop_loading;
 
-					for (x = 0; x < srcinfo.output_width; x++) {
+					for (x = 0; x < output_width; x++) {
 						if (srcinfo.saw_Adobe_marker) {
 							c = p_buffer[0];
 							m = p_buffer[1];
@@ -345,6 +353,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 					surface_row += line_step;
 					buffer_row += buffer_stride;
+					scanned_lines += 1;
 				}
 			}
 		}
@@ -352,11 +361,13 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 	case JCS_GRAYSCALE:
 		{
-			while (srcinfo.output_scanline < srcinfo.output_height) {
+			while (srcinfo.output_scanline < output_height) {
 				if (g_cancellable_is_cancelled (cancellable))
 					goto stop_loading;
 
 				n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+				if (scanned_lines + n_lines > output_height)
+					n_lines = output_height - scanned_lines;
 
 				buffer_row = buffer;
 				for (l = 0; l < n_lines; l++) {
@@ -366,7 +377,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 					if (g_cancellable_is_cancelled (cancellable))
 						goto stop_loading;
 
-					for (x = 0; x < srcinfo.output_width; x++) {
+					for (x = 0; x < output_width; x++) {
 						r = g = b = p_buffer[0];
 						pixel = CAIRO_RGBA_TO_UINT32 (r, g, b, 0xff);
 						memcpy (p_surface, &pixel, sizeof (guint32));
@@ -377,6 +388,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 					surface_row += line_step;
 					buffer_row += buffer_stride;
+					scanned_lines += 1;
 				}
 			}
 		}
@@ -384,11 +396,13 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 	case JCS_RGB:
 		{
-			while (srcinfo.output_scanline < srcinfo.output_height) {
+			while (srcinfo.output_scanline < output_height) {
 				if (g_cancellable_is_cancelled (cancellable))
 					goto stop_loading;
 
 				n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+				if (scanned_lines + n_lines > output_height)
+					n_lines = output_height - scanned_lines;
 
 				buffer_row = buffer;
 				for (l = 0; l < n_lines; l++) {
@@ -398,7 +412,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 					if (g_cancellable_is_cancelled (cancellable))
 						goto stop_loading;
 
-					for (x = 0; x < srcinfo.output_width; x++) {
+					for (x = 0; x < output_width; x++) {
 						r = p_buffer[0];
 						g = p_buffer[1];
 						b = p_buffer[2];
@@ -411,6 +425,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 					surface_row += line_step;
 					buffer_row += buffer_stride;
+					scanned_lines += 1;
 				}
 			}
 		}
@@ -431,11 +446,13 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 			g_cr_tab = YCbCr_G_Cr_Tab;
 			b_cb_tab = YCbCr_B_Cb_Tab;
 
-			while (srcinfo.output_scanline < srcinfo.output_height) {
+			while (srcinfo.output_scanline < output_height) {
 				if (g_cancellable_is_cancelled (cancellable))
 					goto stop_loading;
 
 				n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+				if (scanned_lines + n_lines > output_height)
+					n_lines = output_height - scanned_lines;
 
 				buffer_row = buffer;
 				for (l = 0; l < n_lines; l++) {
@@ -445,7 +462,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 					if (g_cancellable_is_cancelled (cancellable))
 						goto stop_loading;
 
-					for (x = 0; x < srcinfo.output_width; x++) {
+					for (x = 0; x < output_width; x++) {
 						Y = p_buffer[0];
 						Cb = p_buffer[1];
 						Cr = p_buffer[2];
@@ -462,6 +479,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 					surface_row += line_step;
 					buffer_row += buffer_stride;
+					scanned_lines += 1;
 				}
 			}
 		}
@@ -486,11 +504,13 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 			CMYK_table_init ();
 			cmyk_tab = CMYK_Tab;
 
-			while (srcinfo.output_scanline < srcinfo.output_height) {
+			while (srcinfo.output_scanline < output_height) {
 				if (g_cancellable_is_cancelled (cancellable))
 					goto stop_loading;
 
 				n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+				if (scanned_lines + n_lines > output_height)
+					n_lines = output_height - scanned_lines;
 
 				buffer_row = buffer;
 				for (l = 0; l < n_lines; l++) {
@@ -500,7 +520,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 					if (g_cancellable_is_cancelled (cancellable))
 						goto stop_loading;
 
-					for (x = 0; x < srcinfo.output_width; x++) {
+					for (x = 0; x < output_width; x++) {
 						Y = p_buffer[0];
 						Cb = p_buffer[1];
 						Cr = p_buffer[2];
@@ -524,6 +544,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream  *istream,
 
 					surface_row += line_step;
 					buffer_row += buffer_stride;
+					scanned_lines += 1;
 				}
 			}
 		}
-- 
2.24.1