|
1 Security fix from upstream which can be deleted once we update to 3.20.4 |
|
2 |
|
3 From c1ac983bf3bdbd7d8ab4ab34208f1f399bdacbfc Mon Sep 17 00:00:00 2001 |
|
4 From: Felix Riemann <[email protected]> |
|
5 Date: Sun, 14 Feb 2016 18:50:43 +0100 |
|
6 Subject: EogPrintPreview: Fix possible integer overflow |
|
7 |
|
8 This removes code copied from GDK that was susceptiple to a possible |
|
9 integer overflow (cf. CVE-2013-7447), although the code only worked |
|
10 on images too small to trigger the overflow. GDK provides a (fixed) |
|
11 variant of the code with the same features nowadays, so just use that. |
|
12 |
|
13 https://bugzilla.gnome.org/show_bug.cgi?id=762028 |
|
14 --- |
|
15 src/eog-print-preview.c | 96 ++----------------------------------------------- |
|
16 1 file changed, 3 insertions(+), 93 deletions(-) |
|
17 |
|
18 diff --git a/src/eog-print-preview.c b/src/eog-print-preview.c |
|
19 index 3710dff..cfd9db1 100644 |
|
20 --- a/src/eog-print-preview.c |
|
21 +++ b/src/eog-print-preview.c |
|
22 @@ -701,98 +701,6 @@ create_preview_buffer (EogPrintPreview *preview) |
|
23 return pixbuf; |
|
24 } |
|
25 |
|
26 -/* |
|
27 - Function inspired from gdk_cairo_set_source_pixbuf (). The main reason is |
|
28 - that I want to save the cairo_surface_t created from the scaled buffer to |
|
29 - improve performance. |
|
30 -*/ |
|
31 -static cairo_surface_t * |
|
32 -create_surface_from_pixbuf (GdkPixbuf *pixbuf) |
|
33 -{ |
|
34 - gint width = gdk_pixbuf_get_width (pixbuf); |
|
35 - gint height = gdk_pixbuf_get_height (pixbuf); |
|
36 - guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); |
|
37 - int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); |
|
38 - int n_channels = gdk_pixbuf_get_n_channels (pixbuf); |
|
39 - int cairo_stride; |
|
40 - guchar *cairo_pixels; |
|
41 - cairo_format_t format; |
|
42 - cairo_surface_t *surface; |
|
43 - static const cairo_user_data_key_t key; |
|
44 - int j; |
|
45 - |
|
46 - if (n_channels == 3) |
|
47 - format = CAIRO_FORMAT_RGB24; |
|
48 - else |
|
49 - format = CAIRO_FORMAT_ARGB32; |
|
50 - |
|
51 - cairo_stride = cairo_format_stride_for_width (format, width); |
|
52 - cairo_pixels = g_malloc (height * cairo_stride); |
|
53 - surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, |
|
54 - format, |
|
55 - width, height, cairo_stride); |
|
56 - cairo_surface_set_user_data (surface, &key, |
|
57 - cairo_pixels, (cairo_destroy_func_t)g_free); |
|
58 - |
|
59 - for (j = height; j; j--) |
|
60 - { |
|
61 - guchar *p = gdk_pixels; |
|
62 - guchar *q = cairo_pixels; |
|
63 - |
|
64 - if (n_channels == 3) |
|
65 - { |
|
66 - guchar *end = p + 3 * width; |
|
67 - |
|
68 - while (p < end) |
|
69 - { |
|
70 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN |
|
71 - q[0] = p[2]; |
|
72 - q[1] = p[1]; |
|
73 - q[2] = p[0]; |
|
74 -#else |
|
75 - q[1] = p[0]; |
|
76 - q[2] = p[1]; |
|
77 - q[3] = p[2]; |
|
78 -#endif |
|
79 - p += 3; |
|
80 - q += 4; |
|
81 - } |
|
82 - } |
|
83 - else |
|
84 - { |
|
85 - guchar *end = p + 4 * width; |
|
86 - guint t1,t2,t3; |
|
87 - |
|
88 -#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END |
|
89 - |
|
90 - while (p < end) |
|
91 - { |
|
92 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN |
|
93 - MULT(q[0], p[2], p[3], t1); |
|
94 - MULT(q[1], p[1], p[3], t2); |
|
95 - MULT(q[2], p[0], p[3], t3); |
|
96 - q[3] = p[3]; |
|
97 -#else |
|
98 - q[0] = p[3]; |
|
99 - MULT(q[1], p[0], p[3], t1); |
|
100 - MULT(q[2], p[1], p[3], t2); |
|
101 - MULT(q[3], p[2], p[3], t3); |
|
102 -#endif |
|
103 - |
|
104 - p += 4; |
|
105 - q += 4; |
|
106 - } |
|
107 - |
|
108 -#undef MULT |
|
109 - } |
|
110 - |
|
111 - gdk_pixels += gdk_rowstride; |
|
112 - cairo_pixels += cairo_stride; |
|
113 - } |
|
114 - |
|
115 - return surface; |
|
116 -} |
|
117 - |
|
118 static void |
|
119 create_surface (EogPrintPreview *preview) |
|
120 { |
|
121 @@ -806,7 +714,9 @@ create_surface (EogPrintPreview *preview) |
|
122 |
|
123 pixbuf = create_preview_buffer (preview); |
|
124 if (pixbuf) { |
|
125 - priv->surface = create_surface_from_pixbuf (pixbuf); |
|
126 + priv->surface = |
|
127 + gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, |
|
128 + gtk_widget_get_window (GTK_WIDGET (preview))); |
|
129 g_object_unref (pixbuf); |
|
130 } |
|
131 priv->flag_create_surface = FALSE; |