mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-19 23:28:54 +02:00
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:
@@ -401,6 +401,8 @@ token_stream_end_ref (TokenStream *stream,
|
|||||||
ref->end = stream->stream - stream->start;
|
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 doesn’t need to be any longer than `in`. */
|
||||||
static void
|
static void
|
||||||
pattern_copy (gchar **out,
|
pattern_copy (gchar **out,
|
||||||
const gchar **in)
|
const gchar **in)
|
||||||
@@ -431,15 +433,22 @@ pattern_coalesce (const gchar *left,
|
|||||||
{
|
{
|
||||||
gchar *result;
|
gchar *result;
|
||||||
gchar *out;
|
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
|
/* the length of the output is loosely bound by the sum of the input
|
||||||
* lengths, not simply the greater of the two lengths.
|
* lengths, not simply the greater of the two lengths.
|
||||||
*
|
*
|
||||||
* (*(iii)) + ((iii)*) ((iii)(iii))
|
* (*(iii)) + ((iii)*) = ((iii)(iii))
|
||||||
*
|
*
|
||||||
* 8 + 8 = 12
|
* 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)
|
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)
|
if (*left || *right)
|
||||||
{
|
{
|
||||||
g_free (result);
|
g_free (result);
|
||||||
|
@@ -4014,7 +4014,7 @@ test_parses (void)
|
|||||||
g_free (printed);
|
g_free (printed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pattern coalese of `MN` and `*` is `MN` */
|
/* pattern coalesce of `MN` and `*` is `MN` */
|
||||||
{
|
{
|
||||||
GVariant *value = NULL;
|
GVariant *value = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
@@ -4025,6 +4025,29 @@ test_parses (void)
|
|||||||
g_variant_unref (value);
|
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
|
#ifndef _MSC_VER
|
||||||
/* inf/nan strings are C99 features which Visual C++ does not support */
|
/* inf/nan strings are C99 features which Visual C++ does not support */
|
||||||
/* inf/nan mini test */
|
/* inf/nan mini test */
|
||||||
|
Reference in New Issue
Block a user