From 153f63d13e961b7ff49197cfd1d342fb8f39e8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <> Date: Tue, 26 Feb 2019 00:00:00 +0000 Subject: [PATCH] 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",