patch 8.2.5115: search timeout is overrun with some patterns
Problem: Search timeout is overrun with some patterns.
Solution: Check for timeout in more places. Make the flag volatile and
atomic. Use assert_inrange() to see what happened.
This commit is contained in:
@ -4237,6 +4237,27 @@ sub_equal(regsub_T *sub1, regsub_T *sub2)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef FEAT_RELTIME
|
||||
/*
|
||||
* Check if we are past the time limit, if there is one.
|
||||
*/
|
||||
static int
|
||||
nfa_did_time_out(void)
|
||||
{
|
||||
if (*timeout_flag)
|
||||
{
|
||||
if (nfa_timed_out != NULL)
|
||||
{
|
||||
if (!*nfa_timed_out)
|
||||
ch_log(NULL, "NFA regexp timed out");
|
||||
*nfa_timed_out = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_LOG
|
||||
static void
|
||||
open_debug_log(int result)
|
||||
@ -4451,7 +4472,7 @@ state_in_list(
|
||||
/*
|
||||
* Add "state" and possibly what follows to state list ".".
|
||||
* Returns "subs_arg", possibly copied into temp_subs.
|
||||
* Returns NULL when recursiveness is too deep.
|
||||
* Returns NULL when recursiveness is too deep or timed out.
|
||||
*/
|
||||
static regsubs_T *
|
||||
addstate(
|
||||
@ -4480,6 +4501,11 @@ addstate(
|
||||
#endif
|
||||
static int depth = 0;
|
||||
|
||||
#ifdef FEAT_RELTIME
|
||||
if (nfa_did_time_out())
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// This function is called recursively. When the depth is too much we run
|
||||
// out of stack and crash, limit recursiveness here.
|
||||
if (++depth >= 5000 || subs == NULL)
|
||||
@ -5643,24 +5669,6 @@ find_match_text(colnr_T startcol, int regstart, char_u *match_text)
|
||||
return 0L;
|
||||
}
|
||||
|
||||
#ifdef FEAT_RELTIME
|
||||
/*
|
||||
* Check if we are past the time limit, if there is one.
|
||||
* To reduce overhead, only check one in "count" times.
|
||||
*/
|
||||
static int
|
||||
nfa_did_time_out(void)
|
||||
{
|
||||
if (*timeout_flag)
|
||||
{
|
||||
if (nfa_timed_out != NULL)
|
||||
*nfa_timed_out = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Main matching routine.
|
||||
*
|
||||
@ -5708,7 +5716,6 @@ nfa_regmatch(
|
||||
if (got_int)
|
||||
return FALSE;
|
||||
#ifdef FEAT_RELTIME
|
||||
// Check relatively often here, since this is the toplevel matching.
|
||||
if (nfa_did_time_out())
|
||||
return FALSE;
|
||||
#endif
|
||||
@ -7109,7 +7116,6 @@ nextchar:
|
||||
if (got_int)
|
||||
break;
|
||||
#ifdef FEAT_RELTIME
|
||||
// Check for timeout once in a twenty times to avoid overhead.
|
||||
if (nfa_did_time_out())
|
||||
break;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user