changeset 22478:5193420617f1 v8.2.1787

patch 8.2.1787: crash with 'incsearch' and very long line Commit: https://github.com/vim/vim/commit/795aaa1e84d76a6fe066694de9876b8a21cbe40c Author: Bram Moolenaar <Bram@vim.org> Date: Fri Oct 2 20:36:01 2020 +0200 patch 8.2.1787: crash with 'incsearch' and very long line Problem: Crash with 'incsearch' and very long line. Solution: Check whether regprog becomes NULL. (closes https://github.com/vim/vim/issues/7063)
author Bram Moolenaar <Bram@vim.org>
date Fri, 02 Oct 2020 20:45:03 +0200
parents eb2150150b99
children 695881a04101
files src/search.c src/testdir/test_search.vim src/version.c
diffstat 3 files changed, 31 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/search.c
+++ b/src/search.c
@@ -759,6 +759,9 @@ searchit(
 					     NULL, NULL
 #endif
 						      );
+		// vim_regexec_multi() may clear "regprog"
+		if (regmatch.regprog == NULL)
+		    break;
 		// Abort searching on an error (e.g., out of stack).
 		if (called_emsg > called_emsg_before
 #ifdef FEAT_RELTIME
@@ -858,6 +861,9 @@ searchit(
 				match_ok = FALSE;
 				break;
 			    }
+			    // vim_regexec_multi() may clear "regprog"
+			    if (regmatch.regprog == NULL)
+				break;
 			    matchpos = regmatch.startpos[0];
 			    endpos = regmatch.endpos[0];
 # ifdef FEAT_EVAL
@@ -972,6 +978,9 @@ searchit(
 #endif
 				break;
 			    }
+			    // vim_regexec_multi() may clear "regprog"
+			    if (regmatch.regprog == NULL)
+				break;
 
 			    // Need to get the line pointer again, a
 			    // multi-line search may have made it invalid.
@@ -1065,6 +1074,10 @@ searchit(
 	    }
 	    at_first_line = FALSE;
 
+	    // vim_regexec_multi() may clear "regprog"
+	    if (regmatch.regprog == NULL)
+		break;
+
 	    /*
 	     * Stop the search if wrapscan isn't set, "stop_lnum" is
 	     * specified, after an interrupt, after a match and after looping
@@ -2911,7 +2924,8 @@ is_zero_width(char_u *pattern, int move,
 			       pos.lnum, regmatch.startpos[0].col, NULL, NULL);
 	    if (nmatched != 0)
 		break;
-	} while (direction == FORWARD ? regmatch.startpos[0].col < pos.col
+	} while (regmatch.regprog != NULL
+		&& direction == FORWARD ? regmatch.startpos[0].col < pos.col
 				      : regmatch.startpos[0].col > pos.col);
 
 	if (called_emsg == called_emsg_before)
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -964,6 +964,20 @@ func Test_incsearch_substitute()
   call Incsearch_cleanup()
 endfunc
 
+func Test_incsearch_substitute_long_line()
+  new
+  call test_override("char_avail", 1)
+  set incsearch
+
+  call repeat('x', 100000)->setline(1)
+  call feedkeys(':s/\%c', 'xt')
+  redraw
+  call feedkeys("\<Esc>", 'xt')
+
+  call Incsearch_cleanup()
+  bwipe!
+endfunc
+
 " Similar to Test_incsearch_substitute() but with a screendump halfway.
 func Test_incsearch_substitute_dump()
   CheckOption incsearch
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1787,
+/**/
     1786,
 /**/
     1785,