Commit: patch 9.2.0932: NFA engine fallback can double free the compiled program

Christian Brabandt <[email protected]> Mon, 10 Aug 2026 22:30:09 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0932: NFA engine fallback can double free the compiled program

Commit: https://github.com/vim/vim/commit/cab0901f121d0fab74c9a42bb90583d59b3d3c21
Author: Samuel Schlesinger <[email protected]>
Date:   Mon Aug 10 20:17:42 2026 +0000

    patch 9.2.0932: NFA engine fallback can double free the compiled program
    
    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: #20986
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Samuel Schlesinger <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/regexp.c b/src/regexp.c
index 7f52f9a95..6da2e66a7 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -3114,15 +3114,23 @@ vim_regexec_string(
 	char_u *pat = vim_strsave(((nfa_regprog_T *)rmp->regprog)->pattern);
 
 	p_re = BACKTRACKING_ENGINE;
-	vim_regfree(rmp->regprog);
 	if (pat != NULL)
 	{
+	    regprog_T *prev_prog = rmp->regprog;
+
 #ifdef FEAT_EVAL
 	    report_re_switch(pat);
 #endif
 	    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, line, col, nl);
 		rmp->regprog->re_in_use = FALSE;
diff --git a/src/version.c b/src/version.c
index 41fe299ee..a33437590 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    932,
 /**/
     931,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wtWdN-005rvQ-Hv%40256bit.org.