* Copyright © 2010 Codethink Limited
* Copyright © 2010 Novell, Inc.
*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
GHashTable *system_locks; /* Used as a set, owning the strings it contains */
gchar *prefix;
- gint prefix_len;
+ gsize prefix_len;
gchar *root_group;
- gint root_group_len;
+ gsize root_group_len;
GFile *file;
GFileMonitor *file_monitor;
last_slash = strrchr (key, '/');
+ /* Disallow empty group names or key names */
+ if (key_len == 0 ||
+ (last_slash != NULL &&
+ (*(last_slash + 1) == '\0' ||
+ last_slash == key)))
+ return FALSE;
+
if (kfsb->root_group)
{
/* if a root_group was specified, make sure the user hasn't given
* a path that ghosts that group name
*/
- if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0)
+ if (last_slash != NULL && last_slash - key >= 0 &&
+ (gsize) (last_slash - key) == kfsb->root_group_len &&
+ memcmp (key, kfsb->root_group, last_slash - key) == 0)
return FALSE;
}
else
}
if (basename)
- *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
+ {
+ if (last_slash != NULL)
+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
+ else
+ *basename = g_strdup (key);
+ }
return TRUE;
}
g_hash_table_unref (kfsb->system_locks);
g_free (kfsb->defaults_dir);
- g_file_monitor_cancel (kfsb->file_monitor);
- g_object_unref (kfsb->file_monitor);
+ if (kfsb->file_monitor)
+ {
+ g_file_monitor_cancel (kfsb->file_monitor);
+ g_object_unref (kfsb->file_monitor);
+ }
g_object_unref (kfsb->file);
- g_file_monitor_cancel (kfsb->dir_monitor);
- g_object_unref (kfsb->dir_monitor);
+ if (kfsb->dir_monitor)
+ {
+ g_file_monitor_cancel (kfsb->dir_monitor);
+ g_object_unref (kfsb->dir_monitor);
+ }
g_object_unref (kfsb->dir);
g_free (kfsb->root_group);
g_free (kfsb->prefix);
- G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)
- ->finalize (object);
+ G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object);
}
static void
g_keyfile_settings_backend_constructed (GObject *object)
{
GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);
+ GError *error = NULL;
const char *path;
if (kfsb->file == NULL)
if (g_mkdir_with_parents (path, 0700) == -1)
g_warning ("Failed to create %s: %s", path, g_strerror (errno));
- kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL);
- kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL);
+ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error);
+ if (!kfsb->file_monitor)
+ {
+ g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ g_signal_connect (kfsb->file_monitor, "changed",
+ G_CALLBACK (file_changed), kfsb);
+ }
+
+ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error);
+ if (!kfsb->dir_monitor)
+ {
+ g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ g_signal_connect (kfsb->dir_monitor, "changed",
+ G_CALLBACK (dir_changed), kfsb);
+ }
compute_checksum (kfsb->digest, NULL, 0);
- g_signal_connect (kfsb->file_monitor, "changed",
- G_CALLBACK (file_changed), kfsb);
- g_signal_connect (kfsb->dir_monitor, "changed",
- G_CALLBACK (dir_changed), kfsb);
-
g_keyfile_settings_backend_keyfile_writable (kfsb);
g_keyfile_settings_backend_keyfile_reload (kfsb);