0
0
mirror of https://github.com/vim/vim.git synced 2025-10-02 05:04:20 -04:00

patch 8.0.0646: the hlsearch test fails on fast systems

Problem:    The hlsearch test fails on fast systems.
Solution:   Make the search pattern slower.  Fix that the old regexp engine
            doesn't timeout properly.
This commit is contained in:
Bram Moolenaar
2017-06-17 20:55:06 +02:00
parent 1ef9bbe215
commit 0946326580
3 changed files with 37 additions and 11 deletions

View File

@@ -3492,7 +3492,7 @@ typedef struct regbehind_S
static char_u *reg_getline(linenr_T lnum); static char_u *reg_getline(linenr_T lnum);
static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int *timed_out); static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int *timed_out);
static long regtry(bt_regprog_T *prog, colnr_T col); static long regtry(bt_regprog_T *prog, colnr_T col, proftime_T *tm, int *timed_out);
static void cleanup_subexpr(void); static void cleanup_subexpr(void);
#ifdef FEAT_SYN_HL #ifdef FEAT_SYN_HL
static void cleanup_zsubexpr(void); static void cleanup_zsubexpr(void);
@@ -3519,7 +3519,7 @@ static void save_se_one(save_se_T *savep, char_u **pp);
static int re_num_cmp(long_u val, char_u *scan); static int re_num_cmp(long_u val, char_u *scan);
static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen); static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen);
static int regmatch(char_u *prog); static int regmatch(char_u *prog, proftime_T *tm, int *timed_out);
static int regrepeat(char_u *p, long maxcount); static int regrepeat(char_u *p, long maxcount);
#ifdef DEBUG #ifdef DEBUG
@@ -3780,8 +3780,8 @@ bt_regexec_multi(
bt_regexec_both( bt_regexec_both(
char_u *line, char_u *line,
colnr_T col, /* column to start looking for match */ colnr_T col, /* column to start looking for match */
proftime_T *tm UNUSED, /* timeout limit or NULL */ proftime_T *tm, /* timeout limit or NULL */
int *timed_out UNUSED) /* flag set on timeout or NULL */ int *timed_out) /* flag set on timeout or NULL */
{ {
bt_regprog_T *prog; bt_regprog_T *prog;
char_u *s; char_u *s;
@@ -3919,7 +3919,7 @@ bt_regexec_both(
|| (c < 255 && prog->regstart < 255 && || (c < 255 && prog->regstart < 255 &&
#endif #endif
MB_TOLOWER(prog->regstart) == MB_TOLOWER(c))))) MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
retval = regtry(prog, col); retval = regtry(prog, col, tm, timed_out);
else else
retval = 0; retval = 0;
} }
@@ -3958,7 +3958,7 @@ bt_regexec_both(
break; break;
} }
retval = regtry(prog, col); retval = regtry(prog, col, tm, timed_out);
if (retval > 0) if (retval > 0)
break; break;
@@ -4059,7 +4059,11 @@ unref_extmatch(reg_extmatch_T *em)
* Returns 0 for failure, number of lines contained in the match otherwise. * Returns 0 for failure, number of lines contained in the match otherwise.
*/ */
static long static long
regtry(bt_regprog_T *prog, colnr_T col) regtry(
bt_regprog_T *prog,
colnr_T col,
proftime_T *tm, /* timeout limit or NULL */
int *timed_out) /* flag set on timeout or NULL */
{ {
reginput = regline + col; reginput = regline + col;
need_clear_subexpr = TRUE; need_clear_subexpr = TRUE;
@@ -4069,7 +4073,7 @@ regtry(bt_regprog_T *prog, colnr_T col)
need_clear_zsubexpr = TRUE; need_clear_zsubexpr = TRUE;
#endif #endif
if (regmatch(prog->program + 1) == 0) if (regmatch(prog->program + 1, tm, timed_out) == 0)
return 0; return 0;
cleanup_subexpr(); cleanup_subexpr();
@@ -4253,7 +4257,9 @@ static long bl_maxval;
*/ */
static int static int
regmatch( regmatch(
char_u *scan) /* Current node. */ char_u *scan, /* Current node. */
proftime_T *tm UNUSED, /* timeout limit or NULL */
int *timed_out UNUSED) /* flag set on timeout or NULL */
{ {
char_u *next; /* Next node. */ char_u *next; /* Next node. */
int op; int op;
@@ -4266,6 +4272,9 @@ regmatch(
#define RA_BREAK 3 /* break inner loop */ #define RA_BREAK 3 /* break inner loop */
#define RA_MATCH 4 /* successful match */ #define RA_MATCH 4 /* successful match */
#define RA_NOMATCH 5 /* didn't match */ #define RA_NOMATCH 5 /* didn't match */
#ifdef FEAT_RELTIME
int tm_count = 0;
#endif
/* Make "regstack" and "backpos" empty. They are allocated and freed in /* Make "regstack" and "backpos" empty. They are allocated and freed in
* bt_regexec_both() to reduce malloc()/free() calls. */ * bt_regexec_both() to reduce malloc()/free() calls. */
@@ -4300,6 +4309,20 @@ regmatch(
status = RA_FAIL; status = RA_FAIL;
break; break;
} }
#ifdef FEAT_RELTIME
/* Check for timeout once in a 100 times to avoid overhead. */
if (tm != NULL && ++tm_count == 100)
{
tm_count = 0;
if (profile_passed_limit(tm))
{
if (timed_out != NULL)
*timed_out = TRUE;
status = RA_FAIL;
break;
}
}
#endif
status = RA_CONT; status = RA_CONT;
#ifdef DEBUG #ifdef DEBUG

View File

@@ -39,7 +39,8 @@ func Test_hlsearch_hangs()
endif endif
" This pattern takes a long time to match, it should timeout. " This pattern takes a long time to match, it should timeout.
help new
call setline(1, ['aaa', repeat('abc ', 1000), 'ccc'])
let start = reltime() let start = reltime()
set hlsearch nolazyredraw redrawtime=101 set hlsearch nolazyredraw redrawtime=101
let @/ = '\%#=1a*.*X\@<=b*' let @/ = '\%#=1a*.*X\@<=b*'
@@ -48,5 +49,5 @@ func Test_hlsearch_hangs()
call assert_true(elapsed > 0.1) call assert_true(elapsed > 0.1)
call assert_true(elapsed < 1.0) call assert_true(elapsed < 1.0)
set nohlsearch redrawtime& set nohlsearch redrawtime&
quit bwipe!
endfunc endfunc

View File

@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
646,
/**/ /**/
645, 645,
/**/ /**/