[dconf] change writer API to prefix keys with '/'



commit ffd5879dd12e48d5b1d4f3415a7eb7e86572b5a8
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Oct 6 15:40:15 2009 -0400

    change writer API to prefix keys with '/'
    
    add validation code to writer so we don't abort

 dconf/dconf-core.c          |    2 +-
 dconf/dconf-reader.c        |   12 ++++++++++++
 writer/dconf-dbus-writer.c  |   24 ++++++++++++++----------
 writer/dconf-writer-lock.c  |   27 +++++++++++++++++++++++++++
 writer/dconf-writer-merge.c |    7 +++++--
 writer/dconf-writer-unset.c |   34 ++++++++++++++++++++++++++++++++++
 writer/dconf-writer.c       |   31 +++++++++++++++++++++++++++++++
 writer/dconf-writer.h       |    7 +++++++
 8 files changed, 131 insertions(+), 13 deletions(-)
---
diff --git a/dconf/dconf-core.c b/dconf/dconf-core.c
index 58b980e..95059b4 100644
--- a/dconf/dconf-core.c
+++ b/dconf/dconf-core.c
@@ -64,7 +64,7 @@ dconf_demux_path (const gchar **path,
       if (g_str_has_prefix (*path, mount->prefix))
         {
           if (rel)
-            *path += strlen (mount->prefix);
+            *path += strlen (mount->prefix) - 1;
           return mount;
         }
     }
diff --git a/dconf/dconf-reader.c b/dconf/dconf-reader.c
index 814784c..1d2690c 100644
--- a/dconf/dconf-reader.c
+++ b/dconf/dconf-reader.c
@@ -264,6 +264,9 @@ dconf_reader_get (DConfReader  *reader,
   const volatile struct dir_entry *entry;
   char type;
 
+  g_assert (key[0] == '/');
+  key++;
+
   if (!dconf_reader_ensure_valid (reader))
     return;
 
@@ -355,6 +358,9 @@ dconf_reader_list (DConfReader *reader,
   guint32 index;
   gint i;
 
+  g_assert (path[0] == '/');
+  path++;
+
   if (!dconf_reader_ensure_valid (reader))
     return;
 
@@ -391,6 +397,9 @@ dconf_reader_get_writable (DConfReader *reader,
 {
   gboolean locked = FALSE;
 
+  g_assert (name[0] == '/');
+  name++;
+
   if (!dconf_reader_ensure_valid (reader))
     return TRUE;
 
@@ -436,6 +445,9 @@ dconf_reader_get_several_writable (DConfReader         *reader,
   const volatile struct dir_entry *entry;
   gboolean locked = FALSE;
 
+  g_assert (prefix[0] == '/');
+  prefix++;
+
   if (!dconf_reader_ensure_valid (reader))
     return TRUE;
 
diff --git a/writer/dconf-dbus-writer.c b/writer/dconf-dbus-writer.c
index 4c2782f..c029266 100644
--- a/writer/dconf-dbus-writer.c
+++ b/writer/dconf-dbus-writer.c
@@ -251,8 +251,12 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
       value = dconf_dbus_variant_to_gv (&iter);
       dbus_message_iter_next (&iter);
 
-      dconf_writer_set (writer->writer, key, value);
-      status = dconf_writer_sync (writer->writer, &error);
+      if ((status = dconf_writer_check_set (key, &error)))
+        {
+          dconf_writer_set (writer->writer, key, value);
+          status = dconf_writer_sync (writer->writer, &error);
+        }
+
       g_variant_unref (value);
 
       if (status == TRUE)
@@ -298,9 +302,9 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
 
       g_assert (names->len == values->len);
 
-      if (dconf_writer_check_merge (prefix,
-                                    (const gchar **) names->pdata,
-                                    names->len, &error))
+      if ((status = dconf_writer_check_merge (prefix,
+                                              (const gchar **) names->pdata,
+                                              names->len, &error)))
         {
           dconf_writer_merge (writer->writer, prefix,
                               (const gchar **) names->pdata,
@@ -308,8 +312,6 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
                               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]);
@@ -340,8 +342,9 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
       dbus_message_iter_get_basic (&iter, &locked);
       dbus_message_iter_next (&iter);
 
-      status = dconf_writer_set_locked (writer->writer,
-                                         key, locked, &error);
+      if ((status = dconf_writer_check_set_locked (key, &error)))
+        status = dconf_writer_set_locked (writer->writer,
+                                           key, locked, &error);
 
       return dconf_dbus_writer_reply (writer, status, NULL, error);
     }
@@ -356,7 +359,8 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
       dbus_message_iter_get_basic (&iter, &key);
       dbus_message_iter_next (&iter);
 
-      status = dconf_writer_unset (writer->writer, key, &error);
+      if ((status = dconf_writer_check_unset (key, &error)))
+        status = dconf_writer_unset (writer->writer, key, &error);
 
       return dconf_dbus_writer_reply (writer, status, &sequence, error);
     }
diff --git a/writer/dconf-writer-lock.c b/writer/dconf-writer-lock.c
index eff40b1..981b80d 100644
--- a/writer/dconf-writer-lock.c
+++ b/writer/dconf-writer-lock.c
@@ -54,6 +54,9 @@ dconf_writer_set_locked (DConfWriter  *writer,
 {
   volatile struct dir_entry *entry;
 
+  g_assert (name[0] == '/');
+  name++;
+
   if ((entry = dconf_writer_lookup (writer, name)) == NULL)
     {
       g_set_error (error, 0, 0, "Unable to lock non-existent entry.");
@@ -64,3 +67,27 @@ dconf_writer_set_locked (DConfWriter  *writer,
 
   return TRUE;
 }
+
+gboolean
+dconf_writer_check_set_locked (const gchar  *name,
+                               GError      **error)
+{
+  gint i;
+
+  if (name[0] != '/')
+    {
+      g_set_error (error, 0, 0,
+                   "name must start with a slash");
+      return FALSE;
+    }
+
+  for (i = 1; name[i]; i++)
+    if (name[i] == '/' && name[i - 1] == '/')
+      {
+        g_set_error (error, 0, 0,
+                     "name must not contain two adjacent slashes");
+        return FALSE;
+      }
+
+  return TRUE;
+}
diff --git a/writer/dconf-writer-merge.c b/writer/dconf-writer-merge.c
index fc2887e..adf4244 100644
--- a/writer/dconf-writer-merge.c
+++ b/writer/dconf-writer-merge.c
@@ -674,6 +674,9 @@ dconf_writer_merge (DConfWriter  *writer,
   volatile struct superblock *super = writer->data.super;
   guint32 index;
 
+  g_assert (prefix[0] == '/');
+  prefix++;
+
   index = dconf_writer_get_index (writer, &super->root_index, FALSE);
   dconf_writer_merge_index (writer, &index, prefix,
                             names, values, n_items, FALSE);
@@ -688,10 +691,10 @@ dconf_writer_check_merge (const gchar  *prefix,
 {
   gint i;
 
-  if (prefix[0] == '/')
+  if (prefix[0] != '/')
     {
       g_set_error (error, 0, 0,
-                   "prefix must not start with a slash");
+                   "prefix must start with a slash");
       return FALSE;
     }
 
diff --git a/writer/dconf-writer-unset.c b/writer/dconf-writer-unset.c
index f44d558..b59ca0a 100644
--- a/writer/dconf-writer-unset.c
+++ b/writer/dconf-writer-unset.c
@@ -66,6 +66,9 @@ dconf_writer_unset (DConfWriter  *writer,
   volatile struct superblock *super = writer->data.super;
   guint32 index;
 
+  g_assert (key[0] == '/');
+  key++;
+
   index = dconf_writer_get_index (writer, &super->root_index, FALSE);
   if (!dconf_writer_unset_index (writer, &index, key, error))
     return FALSE;
@@ -73,3 +76,34 @@ dconf_writer_unset (DConfWriter  *writer,
 
   return TRUE;
 }
+
+gboolean
+dconf_writer_check_unset (const gchar  *key,
+                          GError      **error)
+{
+  gint i;
+
+  if (key[0] != '/')
+    {
+      g_set_error (error, 0, 0,
+                   "key must start with a slash");
+      return FALSE;
+    }
+
+  for (i = 1; key[i]; i++)
+    if (key[i] == '/' && key[i - 1] == '/')
+      {
+        g_set_error (error, 0, 0,
+                     "key must not contain two adjacent slashes");
+        return FALSE;
+      }
+
+  if (key[i - 1] == '/')
+    {
+      g_set_error (error, 0, 0,
+                   "key must not end with a slash");
+      return FALSE;
+    }
+
+  return TRUE;
+}
diff --git a/writer/dconf-writer.c b/writer/dconf-writer.c
index 67f6289..eedf090 100644
--- a/writer/dconf-writer.c
+++ b/writer/dconf-writer.c
@@ -248,6 +248,37 @@ dconf_writer_set (DConfWriter  *writer,
   return dconf_writer_merge (writer, key, &empty_string, &value, 1);
 }
 
+gboolean
+dconf_writer_check_set (const gchar  *key,
+                        GError      **error)
+{
+  gint i;
+
+  if (key[0] != '/')
+    {
+      g_set_error (error, 0, 0,
+                   "key must start with a slash");
+      return FALSE;
+    }
+
+  for (i = 1; key[i]; i++)
+    if (key[i] == '/' && key[i - 1] == '/')
+      {
+        g_set_error (error, 0, 0,
+                     "key must not contain two adjacent slashes");
+        return FALSE;
+      }
+
+  if (key[i - 1] == '/')
+    {
+      g_set_error (error, 0, 0,
+                   "key must not end with a slash");
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 GVariant *
 dconf_writer_get_entry_value (DConfWriter                     *writer,
                               const volatile struct dir_entry *entry)
diff --git a/writer/dconf-writer.h b/writer/dconf-writer.h
index 3ec4fed..5db76f3 100644
--- a/writer/dconf-writer.h
+++ b/writer/dconf-writer.h
@@ -23,15 +23,22 @@ DConfWriter *           dconf_writer_new                                (const g
 void                    dconf_writer_set                                (DConfWriter  *writer,
                                                                          const gchar  *key,
                                                                          GVariant     *value);
+gboolean                dconf_writer_check_set                          (const gchar  *key,
+                                                                         GError      **error);
 
 gboolean                dconf_writer_unset                              (DConfWriter  *writer,
                                                                          const gchar  *key,
                                                                          GError      **error);
+gboolean                dconf_writer_check_unset                        (const gchar  *key,
+                                                                         GError      **error);
 
 gboolean                dconf_writer_set_locked                         (DConfWriter  *writer,
                                                                          const gchar  *key,
                                                                          gboolean      locked,
                                                                          GError      **error);
+gboolean                dconf_writer_check_set_locked                   (const gchar  *name,
+                                                                         GError      **error);
+
 
 void                    dconf_writer_merge                              (DConfWriter  *writer,
                                                                          const gchar  *prefix,



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