From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001 From: Chen Guanqiao Date: Thu, 11 Nov 2021 01:04:38 +0800 Subject: [PATCH] gutf8: add string length check when ending character offset is -1 Some function such as atk_text_get_text, use -1 to indicate the end of the string. And an crash occurs when the -1 is passed to g_utf8_substring. Call Trace: 0 __memmove_avx_unaligned_erms 1 memcpy 2 g_utf8_substring 3 impl_GetText 4 handle_other 5 handle_message 6 _dbus_object_tree_dispatch_and_unlock 7 dbus_connection_dispatch 8 dbus_connection_dispatch 9 () 10 g_main_dispatch 11 g_main_context_dispatch 12 g_main_context_iterate 13 g_main_context_iteration 14 g_application_run 15 main Signed-off-by: Chen Guanqiao --- glib/gutf8.c | 19 +++++++++++++++++-- glib/tests/utf8-misc.c | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/glib/gutf8.c b/glib/gutf8.c index 7d053540d..9097f690b 100644 --- a/glib/gutf8.c +++ b/glib/gutf8.c @@ -271,11 +271,15 @@ g_utf8_strlen (const gchar *p, * g_utf8_substring: * @str: a UTF-8 encoded string * @start_pos: a character offset within @str - * @end_pos: another character offset within @str + * @end_pos: another character offset within @str, + * or `-1` to indicate the end of the string * * Copies a substring out of a UTF-8 encoded string. * The substring will contain @end_pos - @start_pos characters. * + * Since GLib 2.72, `-1` can be passed to @end_pos to indicate the + * end of the string. + * * Returns: (transfer full): a newly allocated copy of the requested * substring. Free with g_free() when no longer needed. * @@ -288,8 +292,19 @@ g_utf8_substring (const gchar *str, { gchar *start, *end, *out; + g_return_val_if_fail (end_pos >= start_pos || end_pos == -1, NULL); + start = g_utf8_offset_to_pointer (str, start_pos); - end = g_utf8_offset_to_pointer (start, end_pos - start_pos); + + if (end_pos == -1) + { + glong length = g_utf8_strlen (start, -1); + end = g_utf8_offset_to_pointer (start, length); + } + else + { + end = g_utf8_offset_to_pointer (start, end_pos - start_pos); + } out = g_malloc (end - start + 1); memcpy (out, start, end - start); diff --git a/glib/tests/utf8-misc.c b/glib/tests/utf8-misc.c index 7a8c37448..c13729422 100644 --- a/glib/tests/utf8-misc.c +++ b/glib/tests/utf8-misc.c @@ -128,6 +128,10 @@ test_utf8_substring (void) r = g_utf8_substring ("abc\xe2\x82\xa0gh\xe2\x82\xa4", 2, 5); g_assert_cmpstr (r, ==, "c\xe2\x82\xa0g"); g_free (r); + + r = g_utf8_substring ("abcd", 1, -1); + g_assert_cmpstr (r, ==, "bcd"); + g_free (r); } static void