Merge branch 'mcatanzaro/#3469' into 'main'

gvariant-parser: add assert to ensure we don't write too far

Closes #3469

See merge request GNOME/glib!4280
This commit is contained in:
Michael Catanzaro 2024-09-19 17:38:40 +00:00
commit 60aa29df19
2 changed files with 39 additions and 4 deletions

View File

@ -401,6 +401,8 @@ token_stream_end_ref (TokenStream *stream,
ref->end = stream->stream - stream->start;
}
/* This is guaranteed to write exactly as many bytes to `out` as it consumes
* from `in`. i.e. The `out` buffer doesnt need to be any longer than `in`. */
static void
pattern_copy (gchar **out,
const gchar **in)
@ -431,15 +433,22 @@ pattern_coalesce (const gchar *left,
{
gchar *result;
gchar *out;
size_t buflen;
size_t left_len = strlen (left), right_len = strlen (right);
/* the length of the output is loosely bound by the sum of the input
* lengths, not simply the greater of the two lengths.
*
* (*(iii)) + ((iii)*) ((iii)(iii))
* (*(iii)) + ((iii)*) = ((iii)(iii))
*
* 8 + 8 = 12
*
* This can be proven by the fact that `out` is never incremented by more
* bytes than are consumed from `left` or `right` in each iteration.
*/
out = result = g_malloc (strlen (left) + strlen (right));
g_assert (left_len < G_MAXSIZE - right_len);
buflen = left_len + right_len + 1;
out = result = g_malloc (buflen);
while (*left && *right)
{
@ -493,6 +502,9 @@ pattern_coalesce (const gchar *left,
}
}
/* Need at least one byte remaining for trailing nul. */
g_assert (out < result + buflen);
if (*left || *right)
{
g_free (result);

View File

@ -4014,7 +4014,7 @@ test_parses (void)
g_free (printed);
}
/* pattern coalese of `MN` and `*` is `MN` */
/* pattern coalesce of `MN` and `*` is `MN` */
{
GVariant *value = NULL;
GError *error = NULL;
@ -4025,6 +4025,29 @@ test_parses (void)
g_variant_unref (value);
}
/* pattern coalesce of `u` and `u` is `u`; this operates close to the string
* length bounds in pattern_coalesce() */
{
GVariant *value = NULL;
GError *error = NULL;
value = g_variant_parse (NULL, "[@u 5, @u 15]", NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (g_variant_get_type_string (value), ==, "au");
g_variant_unref (value);
}
/* pattern coalesce of `(Ma*Ma(iii))` and `(Ma(iii)Ma*)` is `(Ma(iii)Ma(iii))` */
{
GVariant *value = NULL;
GError *error = NULL;
value = g_variant_parse (NULL, "[([], [(1,2,3)]), ([(1,2,3)], [])]", NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (g_variant_get_type_string (value), ==, "a(a(iii)a(iii))");
g_variant_unref (value);
}
#ifndef _MSC_VER
/* inf/nan strings are C99 features which Visual C++ does not support */
/* inf/nan mini test */