[glib: 1/2] gvariant-parser: Fix pattern coalesce of M and *



commit 153f63d13e961b7ff49197cfd1d342fb8f39e8e1
Author: Tomasz Miąsko <>
Date:   Tue Feb 26 00:00:00 2019 +0000

    gvariant-parser: Fix pattern coalesce of M and *
    
    Previously pattern_coalesce incorrectly concluded that maybe type is not
    present when one pattern starts with `M` and other pattern with anything
    else than `M` or `m`. This is false when the other pattern is `*`, since
    it includes the maybe type.

 glib/gvariant-parser.c | 25 ++++++++-----------------
 glib/tests/gvariant.c  | 12 +++++++++++-
 2 files changed, 19 insertions(+), 18 deletions(-)
---
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 6061d614c..34a2763c4 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -418,6 +418,8 @@ pattern_copy (gchar       **out,
   while (brackets);
 }
 
+/* Returns the most general pattern that is subpattern of left and subpattern
+ * of right, or NULL if there is no such pattern. */
 static gchar *
 pattern_coalesce (const gchar *left,
                   const gchar *right)
@@ -458,7 +460,7 @@ pattern_coalesce (const gchar *left,
               *out++ = *(*the_other)++;
             }
 
-          else if (**one == 'M' && **the_other != 'm')
+          else if (**one == 'M' && **the_other != 'm' && **the_other != '*')
             {
               (*one)++;
             }
@@ -672,18 +674,7 @@ ast_array_get_pattern (AST    **array,
   gint i;
 
   /* Find the pattern which applies to all children in the array, by l-folding a
-   * coalesce operation. This will not always work: for example, the GVariant:
-   *    [[0], [], [nothing]]
-   * has patterns:
-   *    MaMN, Ma*, Mam*
-   * which pairwise coalesce as:
-   *    MaMN + Ma* = MaN
-   *    MaN + Mam* = (doesn’t coalesce)
-   *
-   * However, the pattern MamN coalesces with all three child patterns. Finding
-   * this pattern would require trying all O(n_items^2) pairs, though, which is
-   * expensive. Just let it fail, and require the user to provide type
-   * annotations.
+   * coalesce operation.
    */
   pattern = ast_get_pattern (array[0], error);
 
@@ -719,10 +710,10 @@ ast_array_get_pattern (AST    **array,
               gchar *tmp2;
               gchar *m;
 
-              /* if 'j' reaches 'i' then we failed to find the pair, which can
-               * happen due to only trying pairwise coalesces in order rather
-               * than between all pairs (see above). so just report an error
-               * for i. */
+              /* if 'j' reaches 'i' then we didn't find the pair that failed
+               * to coalesce. This shouldn't happen (see above), but just in
+               * case report an error:
+               */
               if (j >= i)
                 {
                   ast_set_error (array[i], error, NULL,
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index e5aec25bf..ce413bedf 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -3899,6 +3899,17 @@ test_parses (void)
     g_free (printed);
   }
 
+  /* pattern coalese of `MN` and `*` is `MN` */
+  {
+    GVariant *value = NULL;
+    GError *error = NULL;
+
+    value = g_variant_parse (NULL, "[[0], [], [nothing]]", NULL, NULL, &error);
+    g_assert_no_error (error);
+    g_assert_cmpstr (g_variant_get_type_string (value), ==, "aami");
+    g_variant_unref (value);
+  }
+
 #ifndef _MSC_VER
   /* inf/nan strings are C99 features which Visual C++ does not support */
   /* inf/nan mini test */
@@ -3943,7 +3954,6 @@ test_parse_failures (void)
     "[4, 5, '']",               "1-2,7-9:",        "common type",
     "[[4], [], ['']]",          "1-4,10-14:",      "common type",
     "[[], [4], ['']]",          "5-8,10-14:",      "common type",
-    "[[0], [], [nothing]]",     "10-19:",          "common type",
     "just",                     "4:",              "expected value",
     "nothing",                  "0-7:",            "unable to infer",
     "just [4, '']",             "6-7,9-11:",       "common type",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]