diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-03-01 02:32:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-01 02:32:13 +0100 |
commit | 085f0f1b1b4e03d5378ca37ae2cb8670a7fa53cd (patch) | |
tree | f479fb2d53d16ce5779354c13467fa158759d730 /src | |
parent | e7bd49d835e26c96b2ee152e5b697e20ab749650 (diff) | |
parent | e116b0f61f87a79fd93beb32c337f5bd9e2d3ab9 (diff) | |
download | rneovim-085f0f1b1b4e03d5378ca37ae2cb8670a7fa53cd.tar.gz rneovim-085f0f1b1b4e03d5378ca37ae2cb8670a7fa53cd.tar.bz2 rneovim-085f0f1b1b4e03d5378ca37ae2cb8670a7fa53cd.zip |
Merge #9653 from justinmk/vim-8.1.0985
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/misc1.c | 3 | ||||
-rw-r--r-- | src/nvim/regexp.c | 39 | ||||
-rw-r--r-- | src/nvim/regexp_nfa.c | 22 | ||||
-rw-r--r-- | src/nvim/testdir/test_search.vim | 61 |
4 files changed, 95 insertions, 30 deletions
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index e752910a4b..a8cfc2d700 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -1819,6 +1819,9 @@ void changed(void) changed_int(); } buf_inc_changedtick(curbuf); + + // If a pattern is highlighted, the position may now be invalid. + highlight_match = false; } /* diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 53479294de..3b3ca29dad 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2098,18 +2098,20 @@ static char_u *regatom(int *flagp) default: i = -1; break; } - if (i < 0) - EMSG2_RET_NULL( - _("E678: Invalid character after %s%%[dxouU]"), - reg_magic == MAGIC_ALL); - if (use_multibytecode(i)) + if (i < 0 || i > INT_MAX) { + EMSG2_RET_NULL(_("E678: Invalid character after %s%%[dxouU]"), + reg_magic == MAGIC_ALL); + } + if (use_multibytecode(i)) { ret = regnode(MULTIBYTECODE); - else + } else { ret = regnode(EXACTLY); - if (i == 0) + } + if (i == 0) { regc(0x0a); - else + } else { regmbc(i); + } regc(NUL); *flagp |= HASWIDTH; break; @@ -3063,10 +3065,10 @@ static int coll_get_char(void) case 'u': nr = gethexchrs(4); break; case 'U': nr = gethexchrs(8); break; } - if (nr < 0) { - /* If getting the number fails be backwards compatible: the character - * is a backslash. */ - --regparse; + if (nr < 0 || nr > INT_MAX) { + // If getting the number fails be backwards compatible: the character + // is a backslash. + regparse--; nr = '\\'; } return nr; @@ -7088,6 +7090,7 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) { regprog_T *prog = NULL; char_u *expr = expr_arg; + int save_called_emsg; regexp_engine = p_re; @@ -7114,9 +7117,11 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) bt_regengine.expr = expr; nfa_regengine.expr = expr; - /* - * First try the NFA engine, unless backtracking was requested. - */ + // + // First try the NFA engine, unless backtracking was requested. + // + save_called_emsg = called_emsg; + called_emsg = false; if (regexp_engine != BACKTRACKING_ENGINE) { prog = nfa_regengine.regcomp(expr, re_flags + (regexp_engine == AUTOMATIC_ENGINE ? RE_AUTO : 0)); @@ -7141,11 +7146,13 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags) // If the NFA engine failed, try the backtracking engine. The NFA engine // also fails for patterns that it can't handle well but are still valid // patterns, thus a retry should work. - if (regexp_engine == AUTOMATIC_ENGINE) { + // But don't try if an error message was given. + if (regexp_engine == AUTOMATIC_ENGINE && !called_emsg) { regexp_engine = BACKTRACKING_ENGINE; prog = bt_regengine.regcomp(expr, re_flags); } } + called_emsg |= save_called_emsg; if (prog != NULL) { // Store the info needed to call regcomp() again when the engine turns out diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index d34e653058..95030974d8 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1420,12 +1420,12 @@ static int nfa_regatom(void) default: nr = -1; break; } - if (nr < 0) - EMSG2_RET_FAIL( - _("E678: Invalid character after %s%%[dxouU]"), - reg_magic == MAGIC_ALL); - /* A NUL is stored in the text as NL */ - /* TODO: what if a composing character follows? */ + if (nr < 0 || nr > INT_MAX) { + EMSG2_RET_FAIL(_("E678: Invalid character after %s%%[dxouU]"), + reg_magic == MAGIC_ALL); + } + // A NUL is stored in the text as NL + // TODO(vim): what if a composing character follows? EMIT(nr == 0 ? 0x0a : nr); } break; @@ -6476,16 +6476,10 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) nfa_regcomp_start(expr, re_flags); - /* Build postfix form of the regexp. Needed to build the NFA - * (and count its size). */ + // Build postfix form of the regexp. Needed to build the NFA + // (and count its size). postfix = re2post(); if (postfix == NULL) { - // TODO(vim): only give this error for debugging? - if (post_ptr >= post_end) { - IEMSGN("Internal error: estimated max number " - "of states insufficient: %" PRId64, - post_end - post_start); - } goto fail; // Cascaded (syntax?) error } diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 9e2f80fcba..08ccc8d4fe 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -489,6 +489,30 @@ func Test_incsearch_substitute_dump() call delete('Xis_subst_script') endfunc +func Test_incsearch_with_change() + if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal() + return + endif + + call writefile([ + \ 'set incsearch hlsearch scrolloff=0', + \ 'call setline(1, ["one", "two ------ X", "three"])', + \ 'call timer_start(200, { _ -> setline(2, "x")})', + \ ], 'Xis_change_script') + let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70}) + " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by + " the 'ambiwidth' check. + sleep 300m + + " Highlight X, it will be deleted by the timer callback. + call term_sendkeys(buf, ':%s/X') + call VerifyScreenDump(buf, 'Test_incsearch_change_01', {}) + call term_sendkeys(buf, "\<Esc>") + + call StopVimInTerminal(buf) + call delete('Xis_change_script') +endfunc + func Test_search_undefined_behaviour() if !has("terminal") return @@ -524,3 +548,40 @@ func Test_search_sentence() /\%'( / endfunc + +func Test_large_hex_chars1() + " This used to cause a crash, the character becomes an NFA state. + try + /\%Ufffffc23 + catch + call assert_match('E678:', v:exception) + endtry + try + set re=1 + /\%Ufffffc23 + catch + call assert_match('E678:', v:exception) + endtry + set re& +endfunc + +func Test_large_hex_chars2() + " This used to cause a crash, the character becomes an NFA state. + try + /[\Ufffffc1f] + catch + call assert_match('E486:', v:exception) + endtry + try + set re=1 + /[\Ufffffc1f] + catch + call assert_match('E486:', v:exception) + endtry + set re& +endfunc + +func Test_one_error_msg() + " This was also giving an internal error + call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:') +endfunc |