comparison 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
comparison
equal deleted inserted replaced
29190:a4f0e5e61728 29191:0af5fe160e4e
4235 } 4235 }
4236 4236
4237 return TRUE; 4237 return TRUE;
4238 } 4238 }
4239 4239
4240 #ifdef FEAT_RELTIME
4241 /*
4242 * Check if we are past the time limit, if there is one.
4243 */
4244 static int
4245 nfa_did_time_out(void)
4246 {
4247 if (*timeout_flag)
4248 {
4249 if (nfa_timed_out != NULL)
4250 {
4251 if (!*nfa_timed_out)
4252 ch_log(NULL, "NFA regexp timed out");
4253 *nfa_timed_out = TRUE;
4254 }
4255 return TRUE;
4256 }
4257 return FALSE;
4258 }
4259 #endif
4260
4240 #ifdef ENABLE_LOG 4261 #ifdef ENABLE_LOG
4241 static void 4262 static void
4242 open_debug_log(int result) 4263 open_debug_log(int result)
4243 { 4264 {
4244 log_fd = fopen(NFA_REGEXP_RUN_LOG, "a"); 4265 log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
4449 #define ADDSTATE_HERE_OFFSET 10 4470 #define ADDSTATE_HERE_OFFSET 10
4450 4471
4451 /* 4472 /*
4452 * Add "state" and possibly what follows to state list ".". 4473 * Add "state" and possibly what follows to state list ".".
4453 * Returns "subs_arg", possibly copied into temp_subs. 4474 * Returns "subs_arg", possibly copied into temp_subs.
4454 * Returns NULL when recursiveness is too deep. 4475 * Returns NULL when recursiveness is too deep or timed out.
4455 */ 4476 */
4456 static regsubs_T * 4477 static regsubs_T *
4457 addstate( 4478 addstate(
4458 nfa_list_T *l, // runtime state list 4479 nfa_list_T *l, // runtime state list
4459 nfa_state_T *state, // state to update 4480 nfa_state_T *state, // state to update
4477 static regsubs_T temp_subs; 4498 static regsubs_T temp_subs;
4478 #ifdef ENABLE_LOG 4499 #ifdef ENABLE_LOG
4479 int did_print = FALSE; 4500 int did_print = FALSE;
4480 #endif 4501 #endif
4481 static int depth = 0; 4502 static int depth = 0;
4503
4504 #ifdef FEAT_RELTIME
4505 if (nfa_did_time_out())
4506 return NULL;
4507 #endif
4482 4508
4483 // This function is called recursively. When the depth is too much we run 4509 // This function is called recursively. When the depth is too much we run
4484 // out of stack and crash, limit recursiveness here. 4510 // out of stack and crash, limit recursiveness here.
4485 if (++depth >= 5000 || subs == NULL) 4511 if (++depth >= 5000 || subs == NULL)
4486 { 4512 {
5641 break; 5667 break;
5642 } 5668 }
5643 return 0L; 5669 return 0L;
5644 } 5670 }
5645 5671
5646 #ifdef FEAT_RELTIME
5647 /*
5648 * Check if we are past the time limit, if there is one.
5649 * To reduce overhead, only check one in "count" times.
5650 */
5651 static int
5652 nfa_did_time_out(void)
5653 {
5654 if (*timeout_flag)
5655 {
5656 if (nfa_timed_out != NULL)
5657 *nfa_timed_out = TRUE;
5658 return TRUE;
5659 }
5660 return FALSE;
5661 }
5662 #endif
5663
5664 /* 5672 /*
5665 * Main matching routine. 5673 * Main matching routine.
5666 * 5674 *
5667 * Run NFA to determine whether it matches rex.input. 5675 * Run NFA to determine whether it matches rex.input.
5668 * 5676 *
5706 // recursive_regmatch(). Allow interrupting them with CTRL-C. 5714 // recursive_regmatch(). Allow interrupting them with CTRL-C.
5707 fast_breakcheck(); 5715 fast_breakcheck();
5708 if (got_int) 5716 if (got_int)
5709 return FALSE; 5717 return FALSE;
5710 #ifdef FEAT_RELTIME 5718 #ifdef FEAT_RELTIME
5711 // Check relatively often here, since this is the toplevel matching.
5712 if (nfa_did_time_out()) 5719 if (nfa_did_time_out())
5713 return FALSE; 5720 return FALSE;
5714 #endif 5721 #endif
5715 5722
5716 #ifdef NFA_REGEXP_DEBUG_LOG 5723 #ifdef NFA_REGEXP_DEBUG_LOG
7107 // Allow interrupting with CTRL-C. 7114 // Allow interrupting with CTRL-C.
7108 line_breakcheck(); 7115 line_breakcheck();
7109 if (got_int) 7116 if (got_int)
7110 break; 7117 break;
7111 #ifdef FEAT_RELTIME 7118 #ifdef FEAT_RELTIME
7112 // Check for timeout once in a twenty times to avoid overhead.
7113 if (nfa_did_time_out()) 7119 if (nfa_did_time_out())
7114 break; 7120 break;
7115 #endif 7121 #endif
7116 } 7122 }
7117 7123