changeset 6903:dd923806ae3b v7.4.771

patch 7.4.771 Problem: Search does not handle multi-byte character at the start position correctly. Solution: Take byte size of character into account. (Yukihiro Nakadaira)
author Bram Moolenaar <bram@vim.org>
date Fri, 10 Jul 2015 14:43:35 +0200
parents f3baff59f22a
children 4c5b1fc5100e
files src/search.c src/testdir/Make_amiga.mak src/testdir/Make_dos.mak src/testdir/Make_ming.mak src/testdir/Make_os2.mak src/testdir/Make_vms.mms src/testdir/Makefile src/version.c
diffstat 8 files changed, 37 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/search.c
+++ b/src/search.c
@@ -548,6 +548,7 @@ searchit(win, buf, pos, dir, pat, count,
     pos_T	start_pos;
     int		at_first_line;
     int		extra_col;
+    int		start_char_len;
     int		match_ok;
     long	nmatched;
     int		submatch = 0;
@@ -574,23 +575,37 @@ searchit(win, buf, pos, dir, pat, count,
 	/* When not accepting a match at the start position set "extra_col" to
 	 * a non-zero value.  Don't do that when starting at MAXCOL, since
 	 * MAXCOL + 1 is zero. */
-	if ((options & SEARCH_START) || pos->col == MAXCOL)
-	    extra_col = 0;
+	if (pos->col == MAXCOL)
+	    start_char_len = 0;
 #ifdef FEAT_MBYTE
 	/* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
-	else if (dir != BACKWARD && has_mbyte
-		     && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
-						     && pos->col < MAXCOL - 2)
+	else if (has_mbyte
+		    && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
+						    && pos->col < MAXCOL - 2)
 	{
 	    ptr = ml_get_buf(buf, pos->lnum, FALSE) + pos->col;
 	    if (*ptr == NUL)
-		extra_col = 1;
+		start_char_len = 1;
 	    else
-		extra_col = (*mb_ptr2len)(ptr);
+		start_char_len = (*mb_ptr2len)(ptr);
 	}
 #endif
 	else
-	    extra_col = 1;
+	    start_char_len = 1;
+	if (dir == FORWARD)
+	{
+	    if (options & SEARCH_START)
+		extra_col = 0;
+	    else
+		extra_col = start_char_len;
+	}
+	else
+	{
+	    if (options & SEARCH_START)
+		extra_col = start_char_len;
+	    else
+		extra_col = 0;
+	}
 
 	start_pos = *pos;	/* remember start pos for detecting no match */
 	found = 0;		/* default: not found */
@@ -779,15 +794,15 @@ searchit(win, buf, pos, dir, pat, count,
 					|| (lnum + regmatch.endpos[0].lnum
 							     == start_pos.lnum
 					     && (int)regmatch.endpos[0].col - 1
-								   + extra_col
-							<= (int)start_pos.col))
+							< (int)start_pos.col
+								+ extra_col))
 				    : (lnum + regmatch.startpos[0].lnum
 							      < start_pos.lnum
 					|| (lnum + regmatch.startpos[0].lnum
 							     == start_pos.lnum
 					     && (int)regmatch.startpos[0].col
-								   + extra_col
-						      <= (int)start_pos.col))))
+						      < (int)start_pos.col
+							      + extra_col))))
 			    {
 				match_ok = TRUE;
 				matchpos = regmatch.startpos[0];
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -57,6 +57,7 @@ SCRIPTS = test1.out test3.out test4.out 
 		test_perl.out \
 		test_qf_title.out \
 		test_ruby.out \
+		test_search_mbyte.out \
 		test_set.out \
 		test_signs.out \
 		test_textobjects.out \
@@ -205,6 +206,7 @@ test_options.out: test_options.in
 test_perl.out: test_perl.in
 test_qf_title.out: test_qf_title.in
 test_ruby.out: test_ruby.in
+test_search_mbyte.out: test_search_mbyte.in
 test_set.out: test_set.in
 test_signs.out: test_signs.in
 test_textobjects.out: test_textobjects.in
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -56,6 +56,7 @@ SCRIPTS =	test3.out test4.out test5.out 
 		test_perl.out \
 		test_qf_title.out \
 		test_ruby.out \
+		test_search_mbyte.out \
 		test_set.out \
 		test_signs.out \
 		test_textobjects.out \
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -78,6 +78,7 @@ SCRIPTS =	test3.out test4.out test5.out 
 		test_perl.out \
 		test_qf_title.out \
 		test_ruby.out \
+		test_search_mbyte.out \
 		test_set.out \
 		test_signs.out \
 		test_textobjects.out \
--- a/src/testdir/Make_os2.mak
+++ b/src/testdir/Make_os2.mak
@@ -58,6 +58,7 @@ SCRIPTS = test1.out test3.out test4.out 
 		test_perl.out \
 		test_qf_title.out \
 		test_ruby.out \
+		test_search_mbyte.out \
 		test_set.out \
 		test_signs.out \
 		test_textobjects.out \
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -4,7 +4,7 @@
 # Authors:	Zoltan Arpadffy, <arpadffy@polarhome.com>
 #		Sandor Kopanyi,  <sandor.kopanyi@mailbox.hu>
 #
-# Last change:  2015 Jun 19
+# Last change:  2015 Jul 10
 #
 # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64.
 # Edit the lines in the Configuration section below to select.
@@ -117,6 +117,7 @@ SCRIPT = test1.out  test2.out  test3.out
 	 test_perl.out \
 	 test_qf_title.out \
 	 test_ruby.out \
+	 test_search_mbyte.out \
 	 test_set.out \
 	 test_signs.out \
 	 test_textobjects.out \
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -54,6 +54,7 @@ SCRIPTS = test1.out test2.out test3.out 
 		test_perl.out \
 		test_qf_title.out \
 		test_ruby.out \
+		test_search_mbyte.out \
 		test_set.out \
 		test_signs.out \
 		test_textobjects.out \
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    771,
+/**/
     770,
 /**/
     769,