From: Michael Natterer Date: Tue, 24 Apr 2007 13:36:58 +0000 (+0000) Subject: don't free or modify static strings, dup them when needed and clear the X-Git-Tag: GLIB_2_13_1~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=325bd373d4d730d96aee740daed4bc2b70b8ea07;p=platform%2Fupstream%2Fglib.git don't free or modify static strings, dup them when needed and clear the 2007-04-24 Michael Natterer * gobject/gparamspecs.c (param_string_validate): don't free or modify static strings, dup them when needed and clear the G_VALUE_NOCOPY_CONTENTS flag. Fixes bug #432895. * tests/gobject/paramspec-test.c: test all GParamSpecString validations with static and allocated strings. svn path=/trunk/; revision=5454 --- diff --git a/ChangeLog b/ChangeLog index b7c92e6..a5b39c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-04-24 Michael Natterer + + * gobject/gparamspecs.c (param_string_validate): don't free or + modify static strings, dup them when needed and clear the + G_VALUE_NOCOPY_CONTENTS flag. Fixes bug #432895. + + * tests/gobject/paramspec-test.c: test all GParamSpecString + validations with static and allocated strings. + 2007-04-19 William Jon McCann * glib/gkeyfile.[ch]: (find_file_in_data_dirs), diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c index 78bb7cb..ea502b3 100644 --- a/gobject/gparamspecs.c +++ b/gobject/gparamspecs.c @@ -629,6 +629,12 @@ param_string_validate (GParamSpec *pspec, if (sspec->cset_first && !strchr (sspec->cset_first, string[0])) { + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = g_strdup (string); + string = value->data[0].v_pointer; + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + } string[0] = sspec->substitutor; changed++; } @@ -636,13 +642,23 @@ param_string_validate (GParamSpec *pspec, for (s = string + 1; *s; s++) if (!strchr (sspec->cset_nth, *s)) { + if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = g_strdup (string); + s = (gchar*) value->data[0].v_pointer + (s - string); + string = value->data[0].v_pointer; + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; + } *s = sspec->substitutor; changed++; } } if (sspec->null_fold_if_empty && string && string[0] == 0) { - g_free (value->data[0].v_pointer); + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) + g_free (value->data[0].v_pointer); + else + value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS; value->data[0].v_pointer = NULL; changed++; string = value->data[0].v_pointer; diff --git a/tests/gobject/paramspec-test.c b/tests/gobject/paramspec-test.c index 4f3c5b4..16ee3b1 100644 --- a/tests/gobject/paramspec-test.c +++ b/tests/gobject/paramspec-test.c @@ -71,6 +71,78 @@ test_param_spec_char (void) } static void +test_param_spec_string (void) +{ + GParamSpec *pspec; + GValue value = { 0, }; + gboolean modified; + + pspec = g_param_spec_string ("string", "nick", "blurb", + NULL, G_PARAM_READWRITE); + g_value_init (&value, G_TYPE_STRING); + + g_value_set_string (&value, "foobar"); + modified = g_param_value_validate (pspec, &value); + g_assert (!modified); + + g_value_set_string (&value, ""); + modified = g_param_value_validate (pspec, &value); + g_assert (!modified && g_value_get_string (&value) != NULL); + + /* test ensure_non_null */ + + G_PARAM_SPEC_STRING (pspec)->ensure_non_null = TRUE; + + g_value_set_string (&value, NULL); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value) != NULL); + + G_PARAM_SPEC_STRING (pspec)->ensure_non_null = FALSE; + + /* test null_fold_if_empty */ + + G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = TRUE; + + g_value_set_string (&value, ""); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value) == NULL); + + g_value_set_static_string (&value, ""); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value) == NULL); + + G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = FALSE; + + /* test cset_first */ + + G_PARAM_SPEC_STRING (pspec)->cset_first = g_strdup ("abc"); + G_PARAM_SPEC_STRING (pspec)->substitutor = '-'; + + g_value_set_string (&value, "ABC"); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value)[0] == '-'); + + g_value_set_static_string (&value, "ABC"); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value)[0] == '-'); + + /* test cset_nth */ + + G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc"); + + g_value_set_string (&value, "aBC"); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value)[1] == '-'); + + g_value_set_static_string (&value, "aBC"); + modified = g_param_value_validate (pspec, &value); + g_assert (modified && g_value_get_string (&value)[1] == '-'); + + g_value_unset (&value); + g_param_spec_unref (pspec); +} + +static void test_param_spec_override (void) { GParamSpec *ospec, *pspec; @@ -140,6 +212,7 @@ main (int argc, char *argv[]) g_type_init (); test_param_spec_char (); + test_param_spec_string (); test_param_spec_override (); test_param_spec_gtype ();