From 7be8a8dda38542ebe8272b86f99e8633275b01cd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 11 Aug 2026 10:19:52 +0800 Subject: [PATCH] vim-patch:9.2.0932: NFA engine fallback can double free the compiled program (#41268) Problem: When the automatic regexp engine falls back to the backtracking engine in vim_regexec_string(), the compiled program is freed before the replacement is compiled; when saving the pattern fails from being out of memory the caller's "regprog" is left pointing to freed memory and is freed again. Solution: Free the previous program only after compiling the replacement succeeded, like vim_regexec_multi() already does (Samuel Schlesinger). closes: vim/vim#20986 https://github.com/vim/vim/commit/cab0901f121d0fab74c9a42bb90583d59b3d3c21 Co-authored-by: Samuel Schlesinger Co-authored-by: Claude --- src/nvim/regexp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 4331670add..5ed7727a93 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -16253,10 +16253,15 @@ static bool vim_regexec_string(regmatch_T *rmp, const char *line, colnr_T col, b char *pat = xstrdup(((nfa_regprog_T *)rmp->regprog)->pattern); p_re = BACKTRACKING_ENGINE; - vim_regfree(rmp->regprog); + regprog_T *prev_prog = rmp->regprog; report_re_switch(pat); rmp->regprog = vim_regcomp(pat, re_flags); - if (rmp->regprog != NULL) { + if (rmp->regprog == NULL) { + // Somehow compiling the pattern failed now, put back the + // previous one to avoid "regprog" becoming NULL. + rmp->regprog = prev_prog; + } else { + vim_regfree(prev_prog); rmp->regprog->re_in_use = true; result = rmp->regprog->engine->regexec_nl(rmp, (uint8_t *)line, col, nl); rmp->regprog->re_in_use = false;