glib2/gvariant-Fix-error-handling-for-parsing-Unicode-esca.patch
2019-09-30 10:40:42 -04:00

77 lines
2.5 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From d2224b475d20b544cf782ce046183209d419a012 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 4 Dec 2018 12:55:21 +0000
Subject: [PATCH 325/682] gvariant: Fix error handling for parsing Unicode
escapes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When parsing an escaped Unicode character in a text format GVariant
string, such as '\U0001F415', the code uses g_ascii_strtoull(). This,
unexpectedly, accepts minus signs, which can cause an assertion failure
when input like '\u-FF4' is presented for parsing.
Validate that there are no leading sign characters when parsing.
This shouldnt be considered a security bug, because the GVariant text
format parser should not be used on untrusted input.
oss-fuzz#11576
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-parser.c | 20 +++++++++++++++++---
glib/tests/gvariant.c | 20 ++++++++++++++++++--
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 44e341965..b860d42f4 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -1528,6 +1528,8 @@ string_free (AST *ast)
g_slice_free (String, string);
}
+/* Accepts exactly @length hexadecimal digits. No leading sign or `0x`/`0X` prefix allowed.
+ * No leading/trailing space allowed. */
static gboolean
unicode_unescape (const gchar *src,
gint *src_ofs,
@@ -1538,8 +1540,9 @@ unicode_unescape (const gchar *src,
GError **error)
{
gchar buffer[9];
- guint64 value;
+ guint64 value = 0;
gchar *end;
+ gsize n_valid_chars;
(*src_ofs)++;
@@ -1547,11 +1550,22 @@ unicode_unescape (const gchar *src,
strncpy (buffer, src + *src_ofs, length);
buffer[length] = '\0';
- value = g_ascii_strtoull (buffer, &end, 0x10);
+ for (n_valid_chars = 0; n_valid_chars < length; n_valid_chars++)
+ if (!g_ascii_isxdigit (buffer[n_valid_chars]))
+ break;
+
+ if (n_valid_chars == length)
+ value = g_ascii_strtoull (buffer, &end, 0x10);
if (value == 0 || end != buffer + length)
{
- parser_set_error (error, ref, NULL,
+ SourceRef escape_ref;
+
+ escape_ref = *ref;
+ escape_ref.start += *src_ofs;
+ escape_ref.end = escape_ref.start + n_valid_chars;
+
+ parser_set_error (error, &escape_ref, NULL,
G_VARIANT_PARSE_ERROR_INVALID_CHARACTER,
"invalid %d-character unicode escape", length);
return FALSE;