aboutsummaryrefslogtreecommitdiffstats
path: root/community/gimp/0001-Issue-4392-Gimp-Segmentation-Fault-triggered-by-Glib.patch
blob: dc0c029b39e8613d2fab977ae255be68847dcb86 (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
From 4550fc1bfacd36e4d9c6f375b366c2e88885af46 Mon Sep 17 00:00:00 2001
From: Jehan <jehan@girinstud.io>
Date: Tue, 24 Dec 2019 01:22:13 +0100
Subject: [PATCH] Issue #4392: Gimp Segmentation Fault triggered by Glib
 GParamSpec...

... property name validation.
GLib tightened its GParamSpec name validation, as it used to only check
that the first letter was a letter, which triggered this issue, though
the crash could have also happened with the former lax rules too (commit
30e630c9df792cf36cdb1cceb3daefbde1dc898a).

I opened a merge request in GLib to make the validation code into a
public function. In the meantime, let's just copy-paste the validation
code into ours and when a plug-in attempts to create a procedure with
invalid parameter or return value names, GIMP will just output an error
and refuse to install the procedure instead of crashing.
See: https://gitlab.gnome.org/GNOME/glib/merge_requests/1302
---
 app/plug-in/gimpplugin-message.c | 77 +++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 10 deletions(-)

diff --git a/app/plug-in/gimpplugin-message.c b/app/plug-in/gimpplugin-message.c
index fd2abcd904..a397f83adb 100644
--- a/app/plug-in/gimpplugin-message.c
+++ b/app/plug-in/gimpplugin-message.c
@@ -76,6 +76,7 @@ static void gimp_plug_in_handle_proc_uninstall   (GimpPlugIn      *plug_in,
 static void gimp_plug_in_handle_extension_ack    (GimpPlugIn      *plug_in);
 static void gimp_plug_in_handle_has_init         (GimpPlugIn      *plug_in);
 
+static gboolean gimp_plug_in_is_valid_property_name (const gchar  *name);
 
 /*  public functions  */
 
@@ -861,22 +862,48 @@ gimp_plug_in_handle_proc_install (GimpPlugIn    *plug_in,
 
   for (i = 0; i < proc_install->nparams; i++)
     {
-      GParamSpec *pspec =
-        gimp_pdb_compat_param_spec (plug_in->manager->gimp,
-                                    proc_install->params[i].type,
-                                    proc_install->params[i].name,
-                                    proc_install->params[i].description);
+      GParamSpec *pspec;
+
+      if (! gimp_plug_in_is_valid_property_name (proc_install->params[i].name))
+        {
+          gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
+                        "Plug-in \"%s\"\n(%s)\n"
+                        "attempted to install procedure \"%s\" with "
+                        "invalid parameter name \"%s\".",
+                        gimp_object_get_name (plug_in),
+                        gimp_file_get_utf8_name (plug_in->file),
+                        canonical, proc_install->params[i].name);
+          g_object_unref (procedure);
+          return;
+        }
+      pspec = gimp_pdb_compat_param_spec (plug_in->manager->gimp,
+                                          proc_install->params[i].type,
+                                          proc_install->params[i].name,
+                                          proc_install->params[i].description);
 
       gimp_procedure_add_argument (procedure, pspec);
     }
 
   for (i = 0; i < proc_install->nreturn_vals; i++)
     {
-      GParamSpec *pspec =
-        gimp_pdb_compat_param_spec (plug_in->manager->gimp,
-                                    proc_install->return_vals[i].type,
-                                    proc_install->return_vals[i].name,
-                                    proc_install->return_vals[i].description);
+      GParamSpec *pspec;
+
+      if (! gimp_plug_in_is_valid_property_name (proc_install->return_vals[i].name))
+        {
+          gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
+                        "Plug-in \"%s\"\n(%s)\n"
+                        "attempted to install procedure \"%s\" with "
+                        "invalid return value name \"%s\".",
+                        gimp_object_get_name (plug_in),
+                        gimp_file_get_utf8_name (plug_in->file),
+                        canonical, proc_install->return_vals[i].name);
+          g_object_unref (procedure);
+          return;
+        }
+      pspec = gimp_pdb_compat_param_spec (plug_in->manager->gimp,
+                                          proc_install->return_vals[i].type,
+                                          proc_install->return_vals[i].name,
+                                          proc_install->return_vals[i].description);
 
       gimp_procedure_add_return_value (procedure, pspec);
     }
@@ -979,3 +1006,33 @@ gimp_plug_in_handle_has_init (GimpPlugIn *plug_in)
       gimp_plug_in_close (plug_in, TRUE);
     }
 }
+
+/*
+ * XXX: this function should be removed when/if it becomes public in
+ * glib, i.e. when this patch is merged:
+ * https://gitlab.gnome.org/GNOME/glib/merge_requests/1302
+ * See #4392.
+ */
+static gboolean
+gimp_plug_in_is_valid_property_name (const gchar *name)
+{
+  const gchar *p;
+
+  /* First character must be a letter. */
+  if ((name[0] < 'A' || name[0] > 'Z') &&
+      (name[0] < 'a' || name[0] > 'z'))
+    return FALSE;
+
+  for (p = name; *p != 0; p++)
+    {
+      const gchar c = *p;
+
+      if (c != '-' && c != '_' &&
+          (c < '0' || c > '9') &&
+          (c < 'A' || c > 'Z') &&
+          (c < 'a' || c > 'z'))
+        return FALSE;
+    }
+
+  return TRUE;
+}