gvalue: Do copy non-interned strings

The G_VALUE_NOCOPY_CONTENTS for strings can only be used when collecting them
and not when copying them.

Instead only avoid copies for strings that are interned.

Fixes #2141
This commit is contained in:
Edward Hervey 2020-06-23 10:30:55 +00:00 committed by Philip Withnall
parent aa46b2405f
commit e21ab81ce0
3 changed files with 6 additions and 5 deletions

View File

@ -171,7 +171,8 @@ void g_value_register_transform_func (GType src_type,
* *
* If passed to G_VALUE_COLLECT(), allocated data won't be copied * If passed to G_VALUE_COLLECT(), allocated data won't be copied
* but used verbatim. This does not affect ref-counted types like * but used verbatim. This does not affect ref-counted types like
* objects. * objects. This does not affect usage of g_value_copy(), the data will
* be copied if it is not ref-counted.
*/ */
#define G_VALUE_NOCOPY_CONTENTS (1 << 27) #define G_VALUE_NOCOPY_CONTENTS (1 << 27)

View File

@ -264,7 +264,7 @@ static void
value_copy_string (const GValue *src_value, value_copy_string (const GValue *src_value,
GValue *dest_value) GValue *dest_value)
{ {
if (src_value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) if (src_value->data[1].v_uint & G_VALUE_INTERNED_STRING)
{ {
dest_value->data[0].v_pointer = src_value->data[0].v_pointer; dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
dest_value->data[1].v_uint = src_value->data[1].v_uint; dest_value->data[1].v_uint = src_value->data[1].v_uint;
@ -272,7 +272,7 @@ value_copy_string (const GValue *src_value,
else else
{ {
dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
dest_value->data[1].v_uint = src_value->data[1].v_uint; /* Don't copy over *any* flags, we're restarting from scratch */
} }
} }

View File

@ -148,11 +148,11 @@ test_value_string (void)
g_assert_cmpstr (str2, ==, static1); g_assert_cmpstr (str2, ==, static1);
g_free (str2); g_free (str2);
/* Copying a static string gvalue should *not* copy the contents */ /* Copying a static string gvalue should *actually* copy the contents */
g_value_init (&copy, G_TYPE_STRING); g_value_init (&copy, G_TYPE_STRING);
g_value_copy (&value, &copy); g_value_copy (&value, &copy);
copystr = g_value_get_string (&copy); copystr = g_value_get_string (&copy);
g_assert_true (copystr == static1); g_assert_true (copystr != static1);
g_value_unset (&copy); g_value_unset (&copy);
/* Setting a new string should change the contents */ /* Setting a new string should change the contents */