[gimp] app: [Wayland] fix invalid preedit range in text tool.



commit 2ae1ab505a36ebcb87aecf969b3dfa3270c4260c
Author: Jehan <jehan girinstud io>
Date:   Sun Jun 21 12:25:17 2020 +0200

    app: [Wayland] fix invalid preedit range in text tool.
    
    So it seems that pango_attr_iterator_range() could return G_MAXINT for
    a Pango attribute when it is at the end of the preedit string. Looking
    at Pango code, I see they initialize the attribute end property to
    PANGO_ATTR_INDEX_TO_TEXT_END (G_MAXUINT), later clamped to G_MAXINT by
    pango_attr_iterator_range(). So I guess for the specific case where we
    are at the text end, it is normal. Only weird thing is that this didn't
    happen at all on X11, only in Wayland.
    
    So let's do our own pre-check. Also double the check by adding a UTF-8
    validation.
    
    This fixes preedit text not being displayed and the following warning:
    
    > Gtk-CRITICAL **: 12:31:25.118: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, 
NULL)' failed
    
    Even worse, this was potentially an out-of-range reading, though
    fortunately checked early enough.

 app/tools/gimptexttool-editor.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
---
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
index 033631b64f..7a9b4f51d8 100644
--- a/app/tools/gimptexttool-editor.c
+++ b/app/tools/gimptexttool-editor.c
@@ -1515,8 +1515,9 @@ gimp_text_tool_im_preedit_changed (GtkIMContext *context,
       attr_iter = pango_attr_list_get_iterator (attrs);
       do
         {
-          gint attr_start;
-          gint attr_end;
+          const gchar *valid_preedit_end;
+          gint         attr_start;
+          gint         attr_end;
 
           pango_attr_iterator_range (attr_iter, &attr_start, &attr_end);
           if (attr_start < strlen (text_tool->preedit_string))
@@ -1534,10 +1535,23 @@ gimp_text_tool_im_preedit_changed (GtkIMContext *context,
 
               gtk_text_buffer_begin_user_action (buffer);
 
+              /*
+               * Returned attribute end by pango_attr_iterator_range()
+               * may be G_MAXINT to mean the string end, though somehow
+               * we only encountered this in Wayland. Anyway let's take
+               * this possibility into account.
+               */
+              if (attr_end > strlen (text_tool->preedit_string))
+                attr_end = strlen (text_tool->preedit_string);
+
+              /* Double check encoding validity. */
+              if (! g_utf8_validate (text_tool->preedit_string + attr_start, attr_end - attr_start, 
&valid_preedit_end))
+                g_warning ("%s: preedit string is not valid UTF-8.", G_STRFUNC);
+
               /* Insert the preedit chunk at current cursor position. */
               gtk_text_buffer_insert_at_cursor (GTK_TEXT_BUFFER (text_tool->buffer),
                                                 text_tool->preedit_string + attr_start,
-                                                attr_end - attr_start);
+                                                valid_preedit_end - text_tool->preedit_string - attr_start);
               gtk_text_buffer_get_iter_at_mark (buffer, &start,
                                                 start_mark);
               gtk_text_buffer_delete_mark (buffer, start_mark);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]