summaryrefslogtreecommitdiff
path: root/graphics/gimp/patches/patch-plug-ins_common_file-xwd.c
blob: 776b1093fae3aaa77f1cf44f762a3933ce74af31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
$NetBSD: patch-plug-ins_common_file-xwd.c,v 1.1.2.2 2014/05/22 13:55:53 tron Exp $

Sanity check colormap size (CVE-2013-1913), valid range is 0 .. 256.
Sanity check # of colors and map entries (CVE-2013-1978)

The number of colors in an image shouldn't be higher than the number of
colormap entries. Additionally, consolidate post error cleanup in
load_image().

From 
https://git.gnome.org/browse/gimp/patch/?id=32ae0f83e5748299641cceaabe3f80f1b3afd03e
and
https://git.gnome.org/browse/gimp/patch/?id=23f685931e5f000dd033a45c60c1e60d7f78caf4

--- plug-ins/common/file-xwd.c.orig	2013-11-10 15:37:53.000000000 +0000
+++ plug-ins/common/file-xwd.c
@@ -424,9 +424,9 @@ static gint32
 load_image (const gchar  *filename,
             GError      **error)
 {
-  FILE            *ifp;
+  FILE            *ifp = NULL;
   gint             depth, bpp;
-  gint32           image_ID;
+  gint32           image_ID = -1;
   L_XWDFILEHEADER  xwdhdr;
   L_XWDCOLOR      *xwdcolmap = NULL;
 
@@ -436,7 +436,7 @@ load_image (const gchar  *filename,
       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                    _("Could not open '%s' for reading: %s"),
                    gimp_filename_to_utf8 (filename), g_strerror (errno));
-      return -1;
+      goto out;
     }
 
   read_xwd_header (ifp, &xwdhdr);
@@ -445,8 +445,7 @@ load_image (const gchar  *filename,
       g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                    _("Could not read XWD header from '%s'"),
                    gimp_filename_to_utf8 (filename));
-      fclose (ifp);
-      return -1;
+      goto out;
     }
 
 #ifdef XWD_COL_WAIT_DEBUG
@@ -461,8 +460,25 @@ load_image (const gchar  *filename,
   /* Position to start of XWDColor structures */
   fseek (ifp, (long)xwdhdr.l_header_size, SEEK_SET);
 
+  /* Guard against insanely huge color maps -- gimp_image_set_colormap() only
+   * accepts colormaps with 0..256 colors anyway. */
+   if (xwdhdr.l_colormap_entries > 256)
+     {
+       g_message (_("'%s':\nIllegal number of colormap entries: %ld"),
+		  gimp_filename_to_utf8 (filename),
+		  (long)xwdhdr.l_colormap_entries);
+       goto out;
+     }
+
   if (xwdhdr.l_colormap_entries > 0)
     {
+      if (xwdhdr.l_colormap_entries < xwdhdr.l_ncolors)
+      {
+        g_message (_("'%s':\nNumber of colormap entries < number of colors"),
+		   gimp_filename_to_utf8 (filename));
+        goto out;
+      }
+
       xwdcolmap = g_new (L_XWDCOLOR, xwdhdr.l_colormap_entries);
 
       read_xwd_cols (ifp, &xwdhdr, xwdcolmap);
@@ -482,9 +498,7 @@ load_image (const gchar  *filename,
       if (xwdhdr.l_file_version != 7)
         {
           g_message (_("Can't read color entries"));
-          g_free (xwdcolmap);
-          fclose (ifp);
-          return (-1);
+          goto out;
         }
     }
 
@@ -492,9 +506,7 @@ load_image (const gchar  *filename,
     {
       g_message (_("'%s':\nNo image width specified"),
                  gimp_filename_to_utf8 (filename));
-      g_free (xwdcolmap);
-      fclose (ifp);
-      return (-1);
+      goto out;
     }
 
   if (xwdhdr.l_pixmap_width > GIMP_MAX_IMAGE_SIZE
@@ -502,27 +514,21 @@ load_image (const gchar  *filename,
     {
       g_message (_("'%s':\nImage width is larger than GIMP can handle"),
                  gimp_filename_to_utf8 (filename));
-      g_free (xwdcolmap);
-      fclose (ifp);
-      return (-1);
+      goto out;
     }
 
   if (xwdhdr.l_pixmap_height <= 0)
     {
       g_message (_("'%s':\nNo image height specified"),
                  gimp_filename_to_utf8 (filename));
-      g_free (xwdcolmap);
-      fclose (ifp);
-      return (-1);
+      goto out;
     }
 
   if (xwdhdr.l_pixmap_height > GIMP_MAX_IMAGE_SIZE)
     {
       g_message (_("'%s':\nImage height is larger than GIMP can handle"),
                  gimp_filename_to_utf8 (filename));
-      g_free (xwdcolmap);
-      fclose (ifp);
-      return (-1);
+      goto out;
     }
 
   gimp_progress_init_printf (_("Opening '%s'"),
@@ -571,11 +577,6 @@ load_image (const gchar  *filename,
     }
   gimp_progress_update (1.0);
 
-  fclose (ifp);
-
-  if (xwdcolmap)
-    g_free (xwdcolmap);
-
   if (image_ID == -1 && ! (error && *error))
     g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                  _("XWD-file %s has format %d, depth %d and bits per pixel %d. "
@@ -583,6 +584,17 @@ load_image (const gchar  *filename,
                  gimp_filename_to_utf8 (filename),
                  (gint) xwdhdr.l_pixmap_format, depth, bpp);
 
+out:
+  if (ifp)
+    {
+      fclose (ifp);
+    }
+
+  if (xwdcolmap)
+    {
+      g_free (xwdcolmap);
+    }
+
   return image_ID;
 }