diff options
author | Ryan Lortie <desrt@desrt.ca> | 2012-07-19 10:47:50 -0400 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2012-07-19 10:49:29 -0400 |
commit | bc02d65a6c8defcee64022ba2f9a2607495281f7 (patch) | |
tree | 055e6f5de2037cab0cf590b07398367f3fb912ad /engine | |
parent | d4cad3d9f47939491af91dc44348cd283e8eb9b8 (diff) | |
download | dconf-bc02d65a6c8defcee64022ba2f9a2607495281f7.tar.gz |
engine: improve robustness of profile parsing
Checking for 'u' or 's' is really insanely silly from a robustness
standpoint. Ensure that we properly have "user-db:" or "system-db:" and
that a non-empty database name is given, warning if not.
This was specifically causing annoying problems with the profile file
that gdm was installing, so add a copy of that file to our testcases.
Diffstat (limited to 'engine')
-rw-r--r-- | engine/dconf-engine-profile.c | 8 | ||||
-rw-r--r-- | engine/dconf-engine-source.c | 55 |
2 files changed, 43 insertions, 20 deletions
diff --git a/engine/dconf-engine-profile.c b/engine/dconf-engine-profile.c index 0413f32..7415406 100644 --- a/engine/dconf-engine-profile.c +++ b/engine/dconf-engine-profile.c @@ -100,6 +100,7 @@ dconf_engine_default_profile (gint *n_sources) static DConfEngineSource * dconf_engine_profile_handle_line (gchar *line) { + DConfEngineSource *source; gchar *end; /* remove whitespace at the front */ @@ -119,7 +120,12 @@ dconf_engine_profile_handle_line (gchar *line) *end = '\0'; - return dconf_engine_source_new (line); + source = dconf_engine_source_new (line); + + if (source == NULL) + g_warning ("unknown dconf database description: %s", line); + + return source; } static DConfEngineSource ** diff --git a/engine/dconf-engine-source.c b/engine/dconf-engine-source.c index 834644c..2fe58f4 100644 --- a/engine/dconf-engine-source.c +++ b/engine/dconf-engine-source.c @@ -76,27 +76,44 @@ dconf_engine_source_new (const gchar *description) { const DConfEngineSourceVTable *vtable; DConfEngineSource *source; - - switch (description[0]) - { - case 's': - vtable = &dconf_engine_source_system_vtable; - break; - - case 'u': - vtable = &dconf_engine_source_user_vtable; - break; - - default: - g_warning ("unknown dconf database description: %s", description); - return NULL; - } - + const gchar *colon; + + /* Source descriptions are of the form + * + * type:name + * + * Where type must currently be one of "user-db" or "system-db". + * + * We first find the colon. + */ + colon = strchr (description, ':'); + + /* Ensure that we have a colon and that a database name follows it. */ + if (colon == NULL || colon[1] == '\0') + return NULL; + + /* Check if the part before the colon is "user-db"... */ + if ((colon == description + 7) && memcmp (description, "user-db", 7) == 0) + vtable = &dconf_engine_source_user_vtable; + + /* ...or "system-db" */ + else if ((colon == description + 9) && memcmp (description, "system-db", 9) == 0) + vtable = &dconf_engine_source_system_vtable; + + /* If it's not either of those, we have failed. */ + else + return NULL; + + /* We have had a successful parse. + * + * - either user-db: or system-db: + * - non-NULL and non-empty database name + * + * Create the source. + */ source = g_malloc0 (vtable->instance_size); source->vtable = vtable; - source->name = strchr (description, ':'); - if (source->name) - source->name = g_strdup (source->name + 1); + source->name = g_strdup (colon + 1); source->vtable->init (source); return source; |