summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Natterer <mitch@imendio.com>2007-04-24 13:47:14 +0000
committerMichael Natterer <mitch@src.gnome.org>2007-04-24 13:47:14 +0000
commit0c2ffdd3c5c055c9fdd2f2c397a7d0a882fc2bab (patch)
tree446142c609edf56b9e9178f8f8483b56887aeec6
parentefcb8a67c3e263a7c1c598549207138ef94a95bf (diff)
downloadglib-0c2ffdd3c5c055c9fdd2f2c397a7d0a882fc2bab.tar.gz
Merge from trunk:
2007-04-24 Michael Natterer <mitch@imendio.com> Merge from trunk: * 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=/branches/glib-2-12/; revision=5455
-rw-r--r--ChangeLog11
-rw-r--r--gobject/gparamspecs.c18
-rw-r--r--tests/gobject/paramspec-test.c73
3 files changed, 101 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 4b300e266..6fda9146b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-04-24 Michael Natterer <mitch@imendio.com>
+
+ Merge from trunk:
+
+ * 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-15 Tor Lillqvist <tml@novell.com>
* build: Include the build module using the svn:externals
diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
index 78bb7cb95..ea502b3d3 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 4f3c5b410..16ee3b19b 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 ();