gvariant-parser: Fix error handling when type coalescing fails

When parsing GVariant text format strings, we do a limited form of type
inference. The algorithm for type inference for nested array child types
is not complete, however (and making it complete, at least with a naive
implementation, would make it O(N^2), which is not worth it) and so some
text format arrays were triggering an assertion failure in the error
handling code.

Fix that by making the error handling code a little more relaxed, in the
knowledge that our type inference algorithm is not complete. See the
comment added to the code.

This includes a test case, provided by oss-fuzz.

oss-fuzz#11578

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2019-02-05 15:50:15 +00:00
parent f2d51adc13
commit c927c59a84
2 changed files with 27 additions and 2 deletions

View File

@ -671,6 +671,20 @@ ast_array_get_pattern (AST **array,
gchar *pattern;
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* = (doesnt 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.
*/
pattern = ast_get_pattern (array[0], error);
if (pattern == NULL)
@ -705,8 +719,18 @@ ast_array_get_pattern (AST **array,
gchar *tmp2;
gchar *m;
/* if 'j' reaches 'i' then we failed to find the pair */
g_assert (j < i);
/* 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 >= i)
{
ast_set_error (array[i], error, NULL,
G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE,
"unable to find a common type");
g_free (tmp);
return NULL;
}
tmp2 = ast_get_pattern (array[j], NULL);
g_assert (tmp2 != NULL);

View File

@ -3943,6 +3943,7 @@ 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",