diff src/regexp_nfa.c @ 29191:0af5fe160e4e v8.2.5115

patch 8.2.5115: search timeout is overrun with some patterns Commit: https://github.com/vim/vim/commit/616592e0816d2d9f893fcd95e3e1e0fbc5893168 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jun 17 15:17:10 2022 +0100 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.
author Bram Moolenaar <Bram@vim.org>
date Fri, 17 Jun 2022 16:30:06 +0200
parents b90bca860b5a
children c7aa0c46acd5
line wrap: on
line diff
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -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 re
     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