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 <chen.chenchacha@foxmail.com>
This commit is contained in:
Chen Guanqiao 2021-11-11 01:04:38 +08:00
parent b4b5b3d029
commit 9adbdd45d7
2 changed files with 21 additions and 2 deletions

View File

@ -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);

View File

@ -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