[glib: 4/19] gparam: Tighten up property name validation



commit 30e630c9df792cf36cdb1cceb3daefbde1dc898a
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Nov 12 19:34:05 2019 +0000

    gparam: Tighten up property name validation
    
    Inline with the stricter version of the property naming rules from the
    documentation, tighten up the validation of property names at
    installation time.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 gobject/gparam.c      | 35 +++++++++++++++++++++++------------
 gobject/tests/param.c | 23 +++++++++++++++++++++++
 2 files changed, 46 insertions(+), 12 deletions(-)
---
diff --git a/gobject/gparam.c b/gobject/gparam.c
index 89820a543..b336125e4 100644
--- a/gobject/gparam.c
+++ b/gobject/gparam.c
@@ -358,6 +358,8 @@ g_param_spec_get_blurb (GParamSpec *pspec)
   return NULL;
 }
 
+/* @key must have already been validated with is_valid()
+ * Modifies @key in place. */
 static void
 canonicalize_key (gchar *key)
 {
@@ -367,28 +369,37 @@ canonicalize_key (gchar *key)
     {
       gchar c = *p;
       
-      if (c != '-' &&
-         (c < '0' || c > '9') &&
-         (c < 'A' || c > 'Z') &&
-         (c < 'a' || c > 'z'))
-       *p = '-';
+      if (c == '_')
+        *p = '-';
     }
 }
 
+/* @key must have already been validated with is_valid() */
 static gboolean
 is_canonical (const gchar *key)
+{
+  return (strchr (key, '_') == NULL);
+}
+
+static gboolean
+is_valid_property_name (const gchar *key)
 {
   const gchar *p;
 
+  /* First character must be a letter. */
+  if ((key[0] < 'A' || key[0] > 'Z') &&
+      (key[0] < 'a' || key[0] > 'z'))
+    return FALSE;
+
   for (p = key; *p != 0; p++)
     {
-      gchar c = *p;
+      const gchar c = *p;
       
-      if (c != '-' &&
-         (c < '0' || c > '9') &&
-         (c < 'A' || c > 'Z') &&
-         (c < 'a' || c > 'z'))
-       return FALSE;
+      if (c != '-' && c != '_' &&
+          (c < '0' || c > '9') &&
+          (c < 'A' || c > 'Z') &&
+          (c < 'a' || c > 'z'))
+        return FALSE;
     }
 
   return TRUE;
@@ -428,7 +439,7 @@ g_param_spec_internal (GType        param_type,
   
   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL);
   g_return_val_if_fail (name != NULL, NULL);
-  g_return_val_if_fail ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'), NULL);
+  g_return_val_if_fail (is_valid_property_name (name), NULL);
   g_return_val_if_fail (!(flags & G_PARAM_STATIC_NAME) || is_canonical (name), NULL);
   
   pspec = (gpointer) g_type_create_instance (param_type);
diff --git a/gobject/tests/param.c b/gobject/tests/param.c
index d7b5c5b92..93c3f4b94 100644
--- a/gobject/tests/param.c
+++ b/gobject/tests/param.c
@@ -109,6 +109,26 @@ test_param_strings (void)
   g_param_spec_unref (p);
 }
 
+static void
+test_param_invalid_name (gconstpointer test_data)
+{
+  const gchar *invalid_name = test_data;
+
+  g_test_summary ("Test that properties cannot be created with invalid names");
+
+  if (g_test_subprocess ())
+    {
+      GParamSpec *p;
+      p = g_param_spec_int (invalid_name, "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
+      g_param_spec_unref (p);
+      return;
+    }
+
+  g_test_trap_subprocess (NULL, 0, 0);
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*CRITICAL*is_valid_property_name (name)*");
+}
+
 static void
 test_param_convert (void)
 {
@@ -836,6 +856,9 @@ main (int argc, char *argv[])
 
   g_test_add_func ("/param/value", test_param_value);
   g_test_add_func ("/param/strings", test_param_strings);
+  g_test_add_data_func ("/param/invalid-name/colon", "my_int:hello", test_param_invalid_name);
+  g_test_add_data_func ("/param/invalid-name/first-char", "7zip", test_param_invalid_name);
+  g_test_add_data_func ("/param/invalid-name/empty", "", test_param_invalid_name);
   g_test_add_func ("/param/qdata", test_param_qdata);
   g_test_add_func ("/param/validate", test_param_validate);
   g_test_add_func ("/param/convert", test_param_convert);


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