From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001
From: Chen Guanqiao <chen.chenchacha@foxmail.com>
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 <chen.chenchacha@foxmail.com>

Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9adbdd45d7101405eb05487bdf6a2015af9f8afd

---
 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 7d053540d6..9097f690b3 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 7a8c37448b..c137294229 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
-- 
GitLab

