[gtk+/gtk-3-18] textiter: fix bug in case insensitive backward search



commit b325d0a98ab3f64442f4a8e5ce9a286ba9b0f013
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Thu Nov 26 13:31:19 2015 +0100

    textiter: fix bug in case insensitive backward search
    
    'win.lines' contains the same content as the GtkTextBuffer, so to find
    @match_start, forward_chars_with_skipping() is called with
    skip_decomp=FALSE (the last parameter). So far so good.
    
    On the other hand, the content 'lines' (the needle split in lines) is
    casefolded and normalized for a case insensitive search. So,
    forward_chars_with_skipping(..., skip_decomp=TRUE) must be called only
    for the portion of text containing the needle.
    
    Since 'start_tmp' contains the location at the start of the match, we
    can simply begin at that location to find the end of the match.
    
    Unit tests are added.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=758698

 gtk/gtktextiter.c        |   23 ++++++++++-------------
 testsuite/gtk/textiter.c |   12 ++++++++++++
 2 files changed, 22 insertions(+), 13 deletions(-)
---
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index 6b31c64..99c363a 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -5308,37 +5308,34 @@ gtk_text_iter_backward_search (const GtkTextIter *iter,
         {
           /* Match! */
           gint offset;
-          GtkTextIter next;
           GtkTextIter start_tmp;
-          
+          GtkTextIter end_tmp;
+
           /* Offset to start of search string */
           offset = g_utf8_strlen (*win.lines, first_line_match - *win.lines);
 
-          next = win.first_line_start;
-          start_tmp = next;
+          start_tmp = win.first_line_start;
           forward_chars_with_skipping (&start_tmp, offset,
                                        visible_only, !slice, FALSE);
 
           if (limit &&
               gtk_text_iter_compare (limit, &start_tmp) > 0)
             goto out; /* match was bogus */
-          
+
           if (match_start)
             *match_start = start_tmp;
 
           /* Go to end of search string */
-          l = lines;
-          while (*l)
-            {
-              offset += g_utf8_strlen (*l, -1);
-              ++l;
-            }
+          offset = 0;
+          for (l = lines; *l != NULL; l++)
+            offset += g_utf8_strlen (*l, -1);
 
-          forward_chars_with_skipping (&next, offset,
+          end_tmp = start_tmp;
+          forward_chars_with_skipping (&end_tmp, offset,
                                        visible_only, !slice, case_insensitive);
 
           if (match_end)
-            *match_end = next;
+            *match_end = end_tmp;
 
           retval = TRUE;
           goto out;
diff --git a/testsuite/gtk/textiter.c b/testsuite/gtk/textiter.c
index d05a897..51c209b 100644
--- a/testsuite/gtk/textiter.c
+++ b/testsuite/gtk/textiter.c
@@ -186,6 +186,12 @@ test_search (void)
   check_found_backward ("This is some \303\240 text", "some \303\240", 0, 8, 14, "some \303\240");
   check_found_backward ("This is some \303\240 text", "\303\240 text", 0, 13, 19, "\303\240 text");
   check_found_backward ("This is some \303\240 text", "some \303\240 text", 0, 8, 19, "some \303\240 text");
+
+  /* multi-byte characters outside the needle */
+  check_found_forward ("\303\200 aa", "aa", 0, 2, 4, "aa");
+  check_found_forward ("aa \303\200", "aa", 0, 0, 2, "aa");
+  check_found_backward ("\303\200 aa", "aa", 0, 2, 4, "aa");
+  check_found_backward ("aa \303\200", "aa", 0, 0, 2, "aa");
 }
 
 static void
@@ -265,6 +271,12 @@ test_search_caseless (void)
   check_found_backward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
   check_found_backward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, 
"\303\200\n\303\200");
   check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, 
"\303\200\n\303\200");
+
+  /* multi-byte characters outside the needle */
+  check_found_forward ("\303\200 aa", "aa", flags, 2, 4, "aa");
+  check_found_forward ("aa \303\200", "aa", flags, 0, 2, "aa");
+  check_found_backward ("\303\200 aa", "aa", flags, 2, 4, "aa");
+  check_found_backward ("aa \303\200", "aa", flags, 0, 2, "aa");
 }
 
 static void


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