File glib2-CVE-2025-14087-3.patch of Package glib2.41970
From dd333a40aa95819720a01caf6de564cd8a4a6310 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Tue, 25 Nov 2025 19:25:58 +0000
Subject: [PATCH] gvariant-parser: Convert error handling code to use size_t
The error handling code allows for printing out the range of input bytes
related to a parsing error. This was previously done using `gint`, but
the input could be longer than `INT_MAX`, so it should really be done
using `size_t`.
Spotted while working on #3834.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
---
glib/gvariant-parser.c | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff -urp glib-2.48.2.orig/glib/gvariant-parser.c glib-2.48.2/glib/gvariant-parser.c
--- glib-2.48.2.orig/glib/gvariant-parser.c 2025-12-11 16:37:46.475037622 -0600
+++ glib-2.48.2/glib/gvariant-parser.c 2025-12-11 16:57:57.743276299 -0600
@@ -86,7 +86,9 @@ g_variant_parser_get_error_quark (void)
typedef struct
{
- gint start, end;
+ /* Offsets from the start of the input, in bytes. Can be equal when referring
+ * to a point rather than a range. The invariant `end >= start` always holds. */
+ size_t start, end;
} SourceRef;
G_GNUC_PRINTF(5, 0)
@@ -101,14 +103,16 @@ parser_set_error_va (GError **error
GString *msg = g_string_new (NULL);
if (location->start == location->end)
- g_string_append_printf (msg, "%d", location->start);
+ g_string_append_printf (msg, "%" G_GSIZE_FORMAT, location->start);
else
- g_string_append_printf (msg, "%d-%d", location->start, location->end);
+ g_string_append_printf (msg, "%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
+ location->start, location->end);
if (other != NULL)
{
g_assert (other->start != other->end);
- g_string_append_printf (msg, ",%d-%d", other->start, other->end);
+ g_string_append_printf (msg, ",%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
+ other->start, other->end);
}
g_string_append_c (msg, ':');
@@ -135,11 +139,15 @@ parser_set_error (GError **error,
typedef struct
{
+ /* We should always have the following ordering constraint:
+ * start <= this <= stream <= end
+ * Additionally, unless in an error or EOF state, `this < stream`.
+ */
const gchar *start;
const gchar *stream;
const gchar *end;
- const gchar *this;
+ const gchar *this; /* (nullable) */
} TokenStream;
@@ -170,7 +178,7 @@ token_stream_set_error (TokenStream *st
static gboolean
token_stream_prepare (TokenStream *stream)
{
- gint brackets = 0;
+ gssize brackets = 0;
const gchar *end;
if (stream->this != NULL)
@@ -392,7 +400,7 @@ static void
pattern_copy (gchar **out,
const gchar **in)
{
- gint brackets = 0;
+ gssize brackets = 0;
while (**in == 'a' || **in == 'm' || **in == 'M')
*(*out)++ = *(*in)++;
@@ -2587,7 +2595,7 @@ g_variant_builder_add_parsed (GVariantBu
static gboolean
parse_num (const gchar *num,
const gchar *limit,
- gint *result)
+ size_t *result)
{
gchar *endptr;
gint64 bignum;
@@ -2597,10 +2605,12 @@ parse_num (const gchar *num,
if (endptr != limit)
return FALSE;
+ /* The upper bound here is more restrictive than it technically needs to be,
+ * but should be enough for any practical situation: */
if (bignum < 0 || bignum > G_MAXINT)
return FALSE;
- *result = bignum;
+ *result = (size_t) bignum;
return TRUE;
}
@@ -2611,7 +2621,7 @@ add_last_line (GString *err,
{
const gchar *last_nl;
gchar *chomped;
- gint i;
+ size_t i;
/* This is an error at the end of input. If we have a file
* with newlines, that's probably the empty string after the
@@ -2756,7 +2766,7 @@ g_variant_parse_error_print_context (GEr
if (dash == NULL || colon < dash)
{
- gint point;
+ size_t point;
/* we have a single point */
if (!parse_num (error->message, colon, &point))
@@ -2774,7 +2784,7 @@ g_variant_parse_error_print_context (GEr
/* We have one or two ranges... */
if (comma && comma < colon)
{
- gint start1, end1, start2, end2;
+ size_t start1, end1, start2, end2;
const gchar *dash2;
/* Two ranges */
@@ -2790,7 +2800,7 @@ g_variant_parse_error_print_context (GEr
}
else
{
- gint start, end;
+ size_t start, end;
/* One range */
if (!parse_num (error->message, dash, &start) || !parse_num (dash + 1, colon, &end))