[gimp/gimp-2-10] Issue #4392: Gimp Segmentation Fault triggered by Glib GParamSpec...



commit 4550fc1bfacd36e4d9c6f375b366c2e88885af46
Author: Jehan <jehan girinstud io>
Date:   Tue Dec 24 01:22:13 2019 +0100

    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;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]