value: Refactor parsing lists to allow trailing comas
authorThibault Saunier <tsaunier@igalia.com>
Wed, 11 Mar 2020 18:19:45 +0000 (15:19 -0300)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 12 Mar 2020 14:50:20 +0000 (14:50 +0000)
Before that commit `{test, }` wouldn't be accepted as an array
because of the trailing coma, the commit fixes that.

At the same time, the code has been refactored to avoid special casing
the first element of the list, making `{,}` or `<,>` valid lists.

gst/gstvalue.c
tests/check/gst/gstvalue.c

index 4b396cd..30f5b77 100644 (file)
@@ -2440,28 +2440,18 @@ _priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
 
   while (g_ascii_isspace (*s))
     s++;
-  if (*s == end) {
-    s++;
-    *after = s;
-    return TRUE;
-  }
-
-  ret = _priv_gst_value_parse_value (s, &s, &list_value, type);
-  if (!ret)
-    return FALSE;
-
-  g_array_append_val (array, list_value);
-
-  while (g_ascii_isspace (*s))
-    s++;
 
   while (*s != end) {
-    if (*s != ',')
-      return FALSE;
-    s++;
-
-    while (g_ascii_isspace (*s))
+    if (*s == ',') {
       s++;
+      while (g_ascii_isspace (*s))
+        s++;
+
+      if (*s == ',')
+        return FALSE;
+
+      continue;
+    }
 
     memset (&list_value, 0, sizeof (list_value));
     ret = _priv_gst_value_parse_value (s, &s, &list_value, type);
@@ -2469,8 +2459,12 @@ _priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
       return FALSE;
 
     g_array_append_val (array, list_value);
+
     while (g_ascii_isspace (*s))
       s++;
+
+    if (*s != ',' && *s != end)
+      return FALSE;
   }
 
   s++;
index 4c898c7..eb1634d 100644 (file)
@@ -3435,6 +3435,42 @@ GST_START_TEST (test_serialize_null_aray)
 
 GST_END_TEST;
 
+GST_START_TEST (test_deserialize_array)
+{
+  GValue value = { 0 };
+  const gchar *strings[] = {
+    "{ test, }",
+    "{ , }",
+    "{ test,, }",
+    "{ , , }",
+  };
+  gint results_size[] = { 1, 0, -1, -1 };       /* -1 means deserialization should fail */
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
+    /* Workaround a bug in our parser that would lead to segfaults
+     * when deserializing container types using static strings */
+    gchar *str = g_strdup (strings[i]);
+    g_value_init (&value, GST_TYPE_LIST);
+
+    if (results_size[i] == -1) {
+      fail_if (gst_value_deserialize (&value, str),
+          "Should not be able to deserialize %s (%d) as list", str, i);
+    } else {
+      fail_unless (gst_value_deserialize (&value, str),
+          "could not deserialize %s (%d)", str, i);
+      fail_unless (gst_value_list_get_size (&value) == results_size[i],
+          "Wrong array size: %d. expected %d",
+          gst_value_array_get_size (&value), results_size[i]);
+    }
+
+    g_value_unset (&value);
+    g_free (str);
+  }
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_value_suite (void)
 {
@@ -3455,6 +3491,7 @@ gst_value_suite (void)
   tcase_add_test (tc_chain, test_deserialize_gtype);
   tcase_add_test (tc_chain, test_deserialize_gtype_failures);
   tcase_add_test (tc_chain, test_deserialize_bitmask);
+  tcase_add_test (tc_chain, test_deserialize_array);
   tcase_add_test (tc_chain, test_serialize_flags);
   tcase_add_test (tc_chain, test_deserialize_flags);
   tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);