Patch 8.1.0098
Problem: Segfault when pattern with \z() is very slow.
Solution: Check for NULL regprog. Add "nfa_fail" to test_override() to be
able to test this. Fix that 'searchhl' resets called_emsg.
Files: src/syntax.c, runtime/doc/eval.txt, src/evalfunc.c, src/vim.h,
src/testdir/test_syntax.vim, src/globals.h, src/screen.c,
src/regexp.c, src/regexp_nfa.c
*** ../vim-8.1.0097/src/syntax.c 2018-05-20 13:35:40.193163458 +0200
--- src/syntax.c 2018-06-23 13:47:27.294238648 +0200
***************
*** 3327,3332 ****
--- 3327,3338 ----
profile_start(&pt);
#endif
+ if (rmp->regprog == NULL)
+ // This can happen if a previous call to vim_regexec_multi() tried to
+ // use the NFA engine, which resulted in NFA_TOO_EXPENSIVE, and
+ // compiling the pattern with the other engine fails.
+ return FALSE;
+
rmp->rmm_maxcol = syn_buf->b_p_smc;
r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col,
#ifdef FEAT_RELTIME
*** ../vim-8.1.0097/runtime/doc/eval.txt 2018-06-20 22:37:52.658911284
+0200
--- runtime/doc/eval.txt 2018-06-23 13:27:43.863676347 +0200
***************
*** 8694,8699 ****
--- 8694,8701 ----
redraw disable the redrawing() function
char_avail disable the char_avail() function
starting reset the "starting" variable, see below
+ nfa_fail makes the NFA regexp engine fail to force a
+ fallback to the old engine
ALL clear all overrides ({val} is not used)
"starting" is to be used when a test should behave like
*** ../vim-8.1.0097/src/evalfunc.c 2018-06-20 22:37:52.654911306 +0200
--- src/evalfunc.c 2018-06-23 13:29:32.603042364 +0200
***************
*** 13090,13099 ****
--- 13090,13102 ----
save_starting = -1;
}
}
+ else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
+ nfa_fail_for_testing = val;
else if (STRCMP(name, (char_u *)"ALL") == 0)
{
disable_char_avail_for_testing = FALSE;
disable_redraw_for_testing = FALSE;
+ nfa_fail_for_testing = FALSE;
if (save_starting >= 0)
{
starting = save_starting;
*** ../vim-8.1.0097/src/vim.h 2018-04-30 15:12:48.000000000 +0200
--- src/vim.h 2018-06-23 14:06:57.244449803 +0200
***************
*** 1013,1018 ****
--- 1013,1019 ----
/* values for reg_do_extmatch */
# define REX_SET 1 /* to allow \z\(...\), */
# define REX_USE 2 /* to allow \z\1 et al. */
+ # define REX_ALL (REX_SET | REX_USE)
#endif
/* Return values for fullpathcmp() */
*** ../vim-8.1.0097/src/testdir/test_syntax.vim 2018-02-24 19:33:19.000000000
+0100
--- src/testdir/test_syntax.vim 2018-06-23 14:11:40.474945470 +0200
***************
*** 562,564 ****
--- 562,576 ----
let $COLORFGBG = ''
call delete('Xtest.c')
endfun
+
+ " Using \z() in a region with NFA failing should not crash.
+ func Test_syn_wrong_z_one()
+ new
+ call setline(1, ['just some text', 'with foo and bar to match with'])
+ syn region FooBar start="foo\z(.*\)bar" end="\z1"
+ call test_override("nfa_fail", 1)
+ redraw!
+ redraw!
+ call test_override("ALL", 0)
+ bwipe!
+ endfunc
*** ../vim-8.1.0097/src/globals.h 2018-06-19 17:49:20.296015375 +0200
--- src/globals.h 2018-06-23 13:30:00.290880945 +0200
***************
*** 1634,1639 ****
--- 1634,1640 ----
/* flags set by test_override() */
EXTERN int disable_char_avail_for_testing INIT(= 0);
EXTERN int disable_redraw_for_testing INIT(= 0);
+ EXTERN int nfa_fail_for_testing INIT(= 0);
EXTERN int in_free_unref_items INIT(= FALSE);
#endif
*** ../vim-8.1.0097/src/screen.c 2018-06-17 16:23:29.341140642 +0200
--- src/screen.c 2018-06-23 14:02:46.329754550 +0200
***************
*** 7868,7873 ****
--- 7868,7874 ----
linenr_T l;
colnr_T matchcol;
long nmatched;
+ int save_called_emsg = called_emsg;
if (shl->lnum != 0)
{
***************
*** 7986,7991 ****
--- 7987,7995 ----
break; /* useful match found */
}
}
+
+ // Restore called_emsg for assert_fails().
+ called_emsg = save_called_emsg;
}
/*
*** ../vim-8.1.0097/src/regexp.c 2018-02-13 16:28:11.000000000 +0100
--- src/regexp.c 2018-06-23 14:09:21.727692568 +0200
***************
*** 367,373 ****
static char_u e_unmatchedpar[] = N_("E55: Unmatched %s)");
#ifdef FEAT_SYN_HL
static char_u e_z_not_allowed[] = N_("E66: \\z( not allowed here");
! static char_u e_z1_not_allowed[] = N_("E67: \\z1 et al. not allowed here");
#endif
static char_u e_missing_sb[] = N_("E69: Missing ] after %s%%[");
static char_u e_empty_sb[] = N_("E70: Empty %s%%[]");
--- 367,373 ----
static char_u e_unmatchedpar[] = N_("E55: Unmatched %s)");
#ifdef FEAT_SYN_HL
static char_u e_z_not_allowed[] = N_("E66: \\z( not allowed here");
! static char_u e_z1_not_allowed[] = N_("E67: \\z1 - \\z9 not allowed here");
#endif
static char_u e_missing_sb[] = N_("E69: Missing ] after %s%%[");
static char_u e_empty_sb[] = N_("E70: Empty %s%%[]");
***************
*** 2139,2145 ****
switch (c)
{
#ifdef FEAT_SYN_HL
! case '(': if (reg_do_extmatch != REX_SET)
EMSG_RET_NULL(_(e_z_not_allowed));
if (one_exactly)
EMSG_ONE_RET_NULL;
--- 2139,2145 ----
switch (c)
{
#ifdef FEAT_SYN_HL
! case '(': if ((reg_do_extmatch & REX_SET) == 0)
EMSG_RET_NULL(_(e_z_not_allowed));
if (one_exactly)
EMSG_ONE_RET_NULL;
***************
*** 2158,2164 ****
case '6':
case '7':
case '8':
! case '9': if (reg_do_extmatch != REX_USE)
EMSG_RET_NULL(_(e_z1_not_allowed));
ret = regnode(ZREF + c - '0');
re_has_z = REX_USE;
--- 2158,2164 ----
case '6':
case '7':
case '8':
! case '9': if ((reg_do_extmatch & REX_USE) == 0)
EMSG_RET_NULL(_(e_z1_not_allowed));
ret = regnode(ZREF + c - '0');
re_has_z = REX_USE;
***************
*** 8332,8339 ****
/*
* Match a regexp against multiple lines.
! * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
! * Note: "rmp->regprog" may be freed and changed.
* Uses curbuf for line count and 'iskeyword'.
*
* Return zero if there is no match. Return number of lines contained in the
--- 8332,8339 ----
/*
* Match a regexp against multiple lines.
! * "rmp->regprog" must be a compiled regexp as returned by vim_regcomp().
! * Note: "rmp->regprog" may be freed and changed, even set to NULL.
* Uses curbuf for line count and 'iskeyword'.
*
* Return zero if there is no match. Return number of lines contained in the
***************
*** 8376,8382 ****
--- 8376,8387 ----
#ifdef FEAT_EVAL
report_re_switch(pat);
#endif
+ // checking for \z misuse was already done when compiling for NFA,
+ // allow all here
+ reg_do_extmatch = REX_ALL;
rmp->regprog = vim_regcomp(pat, re_flags);
+ reg_do_extmatch = 0;
+
if (rmp->regprog != NULL)
result = rmp->regprog->engine->regexec_multi(
rmp, win, buf, lnum, col, tm, timed_out);
*** ../vim-8.1.0097/src/regexp_nfa.c 2018-06-22 21:42:26.743455036 +0200
--- src/regexp_nfa.c 2018-06-23 14:08:50.071858765 +0200
***************
*** 1482,1488 ****
case '8':
case '9':
/* \z1...\z9 */
! if (reg_do_extmatch != REX_USE)
EMSG_RET_FAIL(_(e_z1_not_allowed));
EMIT(NFA_ZREF1 + (no_Magic(c) - '1'));
/* No need to set nfa_has_backref, the sub-matches don't
--- 1482,1488 ----
case '8':
case '9':
/* \z1...\z9 */
! if ((reg_do_extmatch & REX_USE) == 0)
EMSG_RET_FAIL(_(e_z1_not_allowed));
EMIT(NFA_ZREF1 + (no_Magic(c) - '1'));
/* No need to set nfa_has_backref, the sub-matches don't
***************
*** 1491,1497 ****
break;
case '(':
/* \z( */
! if (reg_do_extmatch != REX_SET)
EMSG_RET_FAIL(_(e_z_not_allowed));
if (nfa_reg(REG_ZPAREN) == FAIL)
return FAIL; /* cascaded error */
--- 1491,1497 ----
break;
case '(':
/* \z( */
! if ((reg_do_extmatch & REX_SET) == 0)
EMSG_RET_FAIL(_(e_z_not_allowed));
if (nfa_reg(REG_ZPAREN) == FAIL)
return FAIL; /* cascaded error */
***************
*** 5692,5698 ****
nextlist->n = 0; /* clear nextlist */
nextlist->has_pim = FALSE;
++nfa_listid;
! if (prog->re_engine == AUTOMATIC_ENGINE && nfa_listid >= NFA_MAX_STATES)
{
/* too many states, retry with old engine */
nfa_match = NFA_TOO_EXPENSIVE;
--- 5692,5699 ----
nextlist->n = 0; /* clear nextlist */
nextlist->has_pim = FALSE;
++nfa_listid;
! if (prog->re_engine == AUTOMATIC_ENGINE
! && (nfa_listid >= NFA_MAX_STATES || nfa_fail_for_testing))
{
/* too many states, retry with old engine */
nfa_match = NFA_TOO_EXPENSIVE;
*** ../vim-8.1.0097/src/version.c 2018-06-22 21:42:26.747455046 +0200
--- src/version.c 2018-06-23 13:28:43.939326081 +0200
***************
*** 763,764 ****
--- 763,766 ----
{ /* Add new patch number below this line */
+ /**/
+ 98,
/**/
--
I AM THANKFUL...
...for all the complaining I hear about the government
because it means we have freedom of speech.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.