gstvalue: Don't loop forever when serializing invalid flag

The serialization code would loop forever if an invalid flag was sent into it.

With unit test for this corner case.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2986>
This commit is contained in:
Olivier Crête 2022-08-01 14:00:20 -04:00 committed by Tim-Philipp Müller
parent 8a81e5b9ff
commit 1d32310089
2 changed files with 42 additions and 8 deletions

View file

@ -4178,7 +4178,16 @@ gst_value_serialize_gflags (const GValue * value)
result = g_strdup (""); result = g_strdup ("");
while (flags) { while (flags) {
fl = g_flags_get_first_value (klass, flags); fl = g_flags_get_first_value (klass, flags);
if (fl != NULL) { if (fl == NULL) {
if (flags) {
g_critical ("Could not serialize invalid flags 0x%x of type %s",
flags, G_VALUE_TYPE_NAME (value));
g_free (result);
result = g_strdup ("0");
}
break;
}
tmp = g_strconcat (result, (first ? "" : "+"), fl->value_name, NULL); tmp = g_strconcat (result, (first ? "" : "+"), fl->value_name, NULL);
g_free (result); g_free (result);
result = tmp; result = tmp;
@ -4187,7 +4196,6 @@ gst_value_serialize_gflags (const GValue * value)
/* clear flag */ /* clear flag */
flags &= ~fl->value; flags &= ~fl->value;
} }
}
g_type_class_unref (klass); g_type_class_unref (klass);
return result; return result;

View file

@ -447,6 +447,31 @@ GST_START_TEST (test_serialize_flags)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_serialize_flags_invalid)
{
GValue value = { 0 };
gchar *string;
g_value_init (&value, GST_TYPE_SEEK_FLAGS);
/* Invalid value */
g_value_set_flags (&value, 1 << 20);
ASSERT_CRITICAL (string = gst_value_serialize (&value));
fail_if (string == NULL, "could not serialize invalid flags");
fail_unless (strcmp (string, "0") == 0,
"resulting value is %s, not 0, for invalid flags", string);
g_free (string);
/* Valid & invalid value */
g_value_set_flags (&value, GST_SEEK_FLAG_FLUSH | 1 << 20);
ASSERT_CRITICAL (string = gst_value_serialize (&value));
fail_if (string == NULL, "could not serialize invalid flags");
fail_unless (strcmp (string, "0") == 0,
"resulting value is %s, not 0, for invalid flags", string);
g_free (string);
}
GST_END_TEST;
GST_START_TEST (test_deserialize_flags) GST_START_TEST (test_deserialize_flags)
{ {
@ -3937,6 +3962,7 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_bitmask); tcase_add_test (tc_chain, test_deserialize_bitmask);
tcase_add_test (tc_chain, test_deserialize_array); tcase_add_test (tc_chain, test_deserialize_array);
tcase_add_test (tc_chain, test_serialize_flags); tcase_add_test (tc_chain, test_serialize_flags);
tcase_add_test (tc_chain, test_serialize_flags_invalid);
tcase_add_test (tc_chain, test_deserialize_flags); tcase_add_test (tc_chain, test_deserialize_flags);
tcase_add_test (tc_chain, test_serialize_deserialize_format_enum); tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);
tcase_add_test (tc_chain, test_serialize_deserialize_value_array); tcase_add_test (tc_chain, test_serialize_deserialize_value_array);