summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-10-02 20:36:01 +0200
committerBram Moolenaar <Bram@vim.org>2020-10-02 20:36:01 +0200
commit795aaa1e84d76a6fe066694de9876b8a21cbe40c (patch)
tree47160caca49d77a8d5938103ca4dcd334d51d8a6
parent8a9bc95eaec53f4e0c951ff8f2686ae5113a5709 (diff)
patch 8.2.1787: crash with 'incsearch' and very long linev8.2.1787
Problem: Crash with 'incsearch' and very long line. Solution: Check whether regprog becomes NULL. (closes #7063)
-rw-r--r--src/search.c16
-rw-r--r--src/testdir/test_search.vim14
-rw-r--r--src/version.c2
3 files changed, 31 insertions, 1 deletions
diff --git a/src/search.c b/src/search.c
index badf793718..fd668383b7 100644
--- 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_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)
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index e39458f71f..f62914e3ed 100644
--- 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
diff --git a/src/version.c b/src/version.c
index 7f528b9332..877d63de40 100644
--- 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,