]> granicus.if.org Git - vim/commitdiff
patch 8.2.1787: crash with 'incsearch' and very long line v8.2.1787
authorBram Moolenaar <Bram@vim.org>
Fri, 2 Oct 2020 18:36:01 +0000 (20:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 2 Oct 2020 18:36:01 +0000 (20:36 +0200)
Problem:    Crash with 'incsearch' and very long line.
Solution:   Check whether regprog becomes NULL. (closes #7063)

src/search.c
src/testdir/test_search.vim
src/version.c

index badf7937184583b41d57e282bfac74ed1312a331..fd668383b74d6f998267c73bbe9cc7861007639b 100644 (file)
@@ -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_T *cur, int direction)
                               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)
index e39458f71f55c06315a69b225e15713b845cd2d4..f62914e3edcfcd47e2431079c6dff12204b73a8c 100644 (file)
@@ -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
index 7f528b9332dd4583b6717203257160ae6d876f6b..877d63de408fb80d5a620e0ba1ab221d975318d3 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1787,
 /**/
     1786,
 /**/