[dconf] Bug 597505 - merge accepts bad input



commit bc1a7fdda8e563be1a03b17cfa4956f91991cd09
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Oct 6 10:13:39 2009 -0400

    Bug 597505 -  merge accepts bad input
    
    add a function to check for valid Merge input

 writer/dconf-dbus-writer.c  |   17 +++++--
 writer/dconf-writer-merge.c |   96 +++++++++++++++++++++++++++++++++++++++++++
 writer/dconf-writer.h       |    4 ++
 3 files changed, 112 insertions(+), 5 deletions(-)
---
diff --git a/writer/dconf-dbus-writer.c b/writer/dconf-dbus-writer.c
index 2eb33c9..4c2782f 100644
--- a/writer/dconf-dbus-writer.c
+++ b/writer/dconf-dbus-writer.c
@@ -298,11 +298,18 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
 
       g_assert (names->len == values->len);
 
-      dconf_writer_merge (writer->writer, prefix,
-                          (const gchar **) names->pdata,
-                          (GVariant **) values->pdata,
-                          names->len);
-      status = dconf_writer_sync (writer->writer, &error);
+      if (dconf_writer_check_merge (prefix,
+                                    (const gchar **) names->pdata,
+                                    names->len, &error))
+        {
+          dconf_writer_merge (writer->writer, prefix,
+                              (const gchar **) names->pdata,
+                              (GVariant **) values->pdata,
+                              names->len);
+          status = dconf_writer_sync (writer->writer, &error);
+        }
+      else
+        status = FALSE;
 
       for (i = 0; i < values->len; i++)
         g_variant_unref (values->pdata[i]);
diff --git a/writer/dconf-writer-merge.c b/writer/dconf-writer-merge.c
index 7550382..fc2887e 100644
--- a/writer/dconf-writer-merge.c
+++ b/writer/dconf-writer-merge.c
@@ -679,3 +679,99 @@ dconf_writer_merge (DConfWriter  *writer,
                             names, values, n_items, FALSE);
   dconf_writer_set_index (writer, &super->root_index, index, FALSE);
 }
+
+gboolean
+dconf_writer_check_merge (const gchar  *prefix,
+                          const gchar **names,
+                          gint          n_names,
+                          GError      **error)
+{
+  gint i;
+
+  if (prefix[0] == '/')
+    {
+      g_set_error (error, 0, 0,
+                   "prefix must not start with a slash");
+      return FALSE;
+    }
+
+  for (i = 1; prefix[i]; i++)
+    if (prefix[i] == '/' && prefix[i - 1] == '/')
+      {
+        g_set_error (error, 0, 0,
+                     "prefix must not contain two adjacent slashes");
+        return FALSE;
+      }
+
+  if (prefix[i - 1] == '/')
+    {
+      if (n_names < 1)
+        {
+          g_set_error (error, 0, 0,
+                       "if prefix ends with a slash then the item list "
+                       "must contain at least one item");
+          return FALSE;
+        }
+
+      for (i = 0; i < n_names; i++)
+        {
+          gint j;
+          
+          if (names[i][0] == '\0')
+            {
+              g_set_error (error, 0, 0,
+                           "if prefix ends with a slash then no key in the "
+                           "item list may be the empty string");
+              return FALSE;
+            }
+
+          if (names[i][0] == '/')
+            {
+              g_set_error (error, 0, 0,
+                           "no key in the item list may start with a slash");
+              return FALSE;
+            }
+
+          for (j = 1; names[i][j]; j++)
+            if (names[i][j] == '/' && names[i][j - 1] == '/')
+              {
+                g_set_error (error, 0, 0,
+                             "no key in the item list may contain two "
+                             "adjacent slashes");
+                return FALSE;
+              }
+
+          if (i > 0)
+            {
+              gint cmp = strcmp (names[i - 1], names[i]);
+
+              if (cmp == 0)
+                {
+                  g_set_error (error, 0, 0,
+                               "no two keys in the item list may be equal");
+                  return FALSE;
+                }
+
+              if (cmp > 0)
+                {
+                  g_set_error (error, 0, 0,
+                               "the keys in the item list must be sorted "
+                               "alphabetically (in ascii strcmp() order)");
+                  return FALSE;
+                }
+            }
+        }
+    }
+  else
+    {
+      if (n_names != 1 || names[0][0] != '\0')
+        {
+          g_set_error (error, 0, 0,
+                       "if prefix doesn't end with a slash then the item "
+                       "list must contain a single item: the empty string");
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
diff --git a/writer/dconf-writer.h b/writer/dconf-writer.h
index 0d4ee66..3ec4fed 100644
--- a/writer/dconf-writer.h
+++ b/writer/dconf-writer.h
@@ -43,5 +43,9 @@ gboolean                dconf_writer_sync                               (DConfWr
                                                                          GError      **error);
 
 void                    dconf_writer_dump                               (DConfWriter  *writer);
+gboolean                dconf_writer_check_merge                        (const gchar  *prefix,
+                                                                         const gchar **names,
+                                                                         gint          n_names,
+                                                                         GError      **error);
 
 #endif /* _dconf_writer_h_ */



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