GSettings: fix check for delaying backend subscription
[platform/upstream/glib.git] / gio / gkeyfilesettingsbackend.c
index a53777f..8eb7681 100644 (file)
@@ -13,9 +13,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors: Vincent Untz <vuntz@gnome.org>
  *          Ryan Lortie <desrt@desrt.ca>
@@ -32,7 +30,6 @@
 #include "gsimplepermission.h"
 #include "gsettingsbackend.h"
 
-#include "gioalias.h"
 
 #define G_TYPE_KEYFILE_SETTINGS_BACKEND      (g_keyfile_settings_backend_get_type ())
 #define G_KEYFILE_SETTINGS_BACKEND(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst),      \
@@ -169,7 +166,7 @@ convert_path (GKeyfileSettingsBackend  *kfsb,
   return TRUE;
 }
 
-gboolean
+static gboolean
 path_is_valid (GKeyfileSettingsBackend *kfsb,
                const gchar             *path)
 {
@@ -294,7 +291,7 @@ g_keyfile_settings_backend_check_one (gpointer key,
 }
 
 static gboolean
-g_keyfile_settings_backend_write_many (GSettingsBackend *backend,
+g_keyfile_settings_backend_write_tree (GSettingsBackend *backend,
                                        GTree            *tree,
                                        gpointer          origin_tag)
 {
@@ -340,19 +337,6 @@ g_keyfile_settings_backend_write (GSettingsBackend *backend,
 }
 
 static void
-g_keyfile_settings_backend_reset_path (GSettingsBackend *backend,
-                                       const gchar      *path,
-                                       gpointer          origin_tag)
-{
-  GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend);
-
-  if (set_to_keyfile (kfsb, path, NULL))
-    g_keyfile_settings_backend_keyfile_write (kfsb);
-
-  g_settings_backend_path_changed (backend, path, origin_tag);
-}
-
-static void
 g_keyfile_settings_backend_reset (GSettingsBackend *backend,
                                   const gchar      *key,
                                   gpointer          origin_tag)
@@ -400,12 +384,24 @@ keyfile_to_tree (GKeyfileSettingsBackend *kfsb,
       gint j;
 
       is_root_group = g_strcmp0 (kfsb->root_group, groups[i]) == 0;
+
+      /* reject group names that will form invalid key names */
+      if (!is_root_group &&
+          (g_str_has_prefix (groups[i], "/") ||
+           g_str_has_suffix (groups[i], "/") || strstr (groups[i], "//")))
+        continue;
+
       keys = g_key_file_get_keys (keyfile, groups[i], NULL, NULL);
+      g_assert (keys != NULL);
 
       for (j = 0; keys[j]; j++)
         {
           gchar *path, *value;
 
+          /* reject key names with slashes in them */
+          if (strchr (keys[j], '/'))
+            continue;
+
           if (is_root_group)
             path = g_strdup_printf ("%s%s", kfsb->prefix, keys[j]);
           else
@@ -535,14 +531,14 @@ g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class)
 
   class->read = g_keyfile_settings_backend_read;
   class->write = g_keyfile_settings_backend_write;
-  class->write_keys = g_keyfile_settings_backend_write_many;
+  class->write_tree = g_keyfile_settings_backend_write_tree;
   class->reset = g_keyfile_settings_backend_reset;
-  class->reset_path = g_keyfile_settings_backend_reset_path;
   class->get_writable = g_keyfile_settings_backend_get_writable;
   class->get_permission = g_keyfile_settings_backend_get_permission;
   /* No need to implement subscribed/unsubscribe: the only point would be to
    * stop monitoring the file when there's no GSettings anymore, which is no
-   * big win. */
+   * big win.
+   */
 }
 
 static void
@@ -554,7 +550,9 @@ file_changed (GFileMonitor      *monitor,
 {
   GKeyfileSettingsBackend *kfsb = user_data;
 
-  g_keyfile_settings_backend_keyfile_reload (kfsb);
+  /* Ignore file deletions, let the GKeyFile content remain in tact. */
+  if (event_type != G_FILE_MONITOR_EVENT_DELETED)
+    g_keyfile_settings_backend_keyfile_reload (kfsb);
 }
 
 static void
@@ -575,7 +573,6 @@ dir_changed (GFileMonitor       *monitor,
  * @root_path: the path under which all settings keys appear
  * @root_group: (allow-none): the group name corresponding to
  *              @root_path, or %NULL
- * Returns: a keyfile-backed #GSettingsBackend
  *
  * Creates a keyfile-backed #GSettingsBackend.
  *
@@ -591,10 +588,10 @@ dir_changed (GFileMonitor       *monitor,
  * "toplevel", then settings the key "/apps/example/enabled" to a value
  * of %TRUE will cause the following to appear in the keyfile:
  *
- * <programlisting>
+ * |[
  *   [toplevel]
- *   foo=true
- * </programlisting>
+ *   enabled=true
+ * ]|
  *
  * If @root_group is %NULL then it is not permitted to store keys
  * directly below the @root_path.
@@ -602,13 +599,13 @@ dir_changed (GFileMonitor       *monitor,
  * For keys not stored directly below @root_path (ie: in a sub-path),
  * the name of the subpath (with the final slash stripped) is used as
  * the name of the keyfile group.  To continue the example, if
- * were stored in "/apps/example/profiles/default/font-size" were set to
+ * "/apps/example/profiles/default/font-size" were set to
  * 12 then the following would appear in the keyfile:
  *
- * <programlisting>
+ * |[
  *   [profiles/default]
  *   font-size=12
- * </programlisting>
+ * ]|
  *
  * The backend will refuse writes (and return writability as being
  * %FALSE) for keys outside of @root_path and, in the event that
@@ -616,6 +613,13 @@ dir_changed (GFileMonitor       *monitor,
  * Writes will also be refused if the backend detects that it has the
  * inability to rewrite the keyfile (ie: the containing directory is not
  * writable).
+ *
+ * There is no checking done for your key namespace clashing with the
+ * syntax of the key file format.  For example, if you have '[' or ']'
+ * characters in your path names or '=' in your key names you may be in
+ * trouble.
+ *
+ * Returns: (transfer full): a keyfile-backed #GSettingsBackend
  **/
 GSettingsBackend *
 g_keyfile_settings_backend_new (const gchar *filename,
@@ -638,8 +642,8 @@ g_keyfile_settings_backend_new (const gchar *filename,
   kfsb->dir = g_file_get_parent (kfsb->file);
   g_file_make_directory_with_parents (kfsb->dir, NULL, NULL);
 
-  kfsb->file_monitor = g_file_monitor_file (kfsb->file, 0, NULL, NULL);
-  kfsb->dir_monitor = g_file_monitor_file (kfsb->dir, 0, NULL, NULL);
+  kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL);
+  kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL);
 
   kfsb->prefix_len = strlen (root_path);
   kfsb->prefix = g_strdup (root_path);
@@ -662,6 +666,3 @@ g_keyfile_settings_backend_new (const gchar *filename,
 
   return G_SETTINGS_BACKEND (kfsb);
 }
-
-#define __G_KEYFILE_SETTINGS_BACKEND_C__
-#include "gioaliasdef.c"