diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2013-02-26 10:18:37 +0000 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2013-02-27 09:30:40 +0000 |
commit | 565f2ed54f53adc7bd6793a0e746ceb349843408 (patch) | |
tree | c3feef2dbbdfcb47d838e629590d944c3cce2912 | |
parent | 3e17bf71aa47e7fe52c7053ec5cf44836cf5bd03 (diff) |
caps_hash: don't crash if FORM_TYPE has no <value>
Previously there were a couple of ways this could crash:
* First, if you had a <field type='hidden' var='FORM_TYPE'> with no
<value> child, field->default_value would be NULL so
g_value_get_string (field->default_value)
would critical and return NULL and then you'll be in undefined hell.
* Having fixed that, the code to sort data forms by FORM_TYPE would also
crash because it happens before the FORM_TYPEs have been validated and
used g_value_get_string() without checking and then strcmp()ed the
possibly-NULL result.
I actually have a work-in-progress branch that makes this all a lot less
hairy by adding, among other things, a wocky_data_form_get_form_type()
function which can do the validation for us. But better to fix the
crashes before refactoring them away.
https://bugs.freedesktop.org/show_bug.cgi?id=61433
-rw-r--r-- | wocky/wocky-caps-hash.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/wocky/wocky-caps-hash.c b/wocky/wocky-caps-hash.c index 7bd2c43..01006a7 100644 --- a/wocky/wocky-caps-hash.c +++ b/wocky/wocky-caps-hash.c @@ -80,8 +80,17 @@ dataforms_cmp (gconstpointer a, else if (left_type != NULL && right_type == NULL) return 1; else /* left_type != NULL && right_type != NULL */ - return strcmp (g_value_get_string (left_type->default_value), - g_value_get_string (right_type->default_value)); + { + const gchar *left_value = NULL, *right_value = NULL; + + if (left_type->raw_value_contents != NULL) + left_value = left_type->raw_value_contents[0]; + + if (right_type->raw_value_contents != NULL) + right_value = right_type->raw_value_contents[0]; + + return g_strcmp0 (left_value, right_value); + } } static GPtrArray * @@ -190,16 +199,22 @@ wocky_caps_hash_compute_from_lists ( continue; } - form_name = g_value_get_string (field->default_value); - if (field->type != WOCKY_DATA_FORM_FIELD_TYPE_HIDDEN) { - DEBUG ("FORM_TYPE field of form '%s' is not hidden; " - "ignoring form and moving onto next one", - form_name); + DEBUG ("FORM_TYPE field is not hidden; " + "ignoring form and moving onto next one"); continue; } + if (field->raw_value_contents == NULL || + g_strv_length (field->raw_value_contents) != 1) + { + DEBUG ("FORM_TYPE field does not have exactly one value; failing"); + goto cleanup; + } + + form_name = field->raw_value_contents[0]; + if (g_hash_table_lookup (form_names, form_name) != NULL) { DEBUG ("error: there are multiple data forms with the " |