]> granicus.if.org Git - vim/commitdiff
patch 8.2.3612: using freed memory with regexp using a mark v8.2.3612
authorBram Moolenaar <Bram@vim.org>
Wed, 17 Nov 2021 18:22:56 +0000 (18:22 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 17 Nov 2021 18:22:56 +0000 (18:22 +0000)
Problem:    Using freed memory with regexp using a mark.
Solution:   Get the line again after getting the mark position.

src/regexp.c
src/regexp_nfa.c
src/testdir/test_regexp_latin.vim
src/version.c

index e28d9e69597350a7ddbc99f4adf7ac57c259a1fc..4b14745791304c501d7e3addf04b0cb41f2a2a36 100644 (file)
@@ -1129,7 +1129,7 @@ typedef struct {
     // The current match-position is stord in these variables:
     linenr_T   lnum;           // line number, relative to first line
     char_u     *line;          // start of current line
-    char_u     *input;         // current input, points into "regline"
+    char_u     *input;         // current input, points into "line"
 
     int        need_clear_subexpr;     // subexpressions still need to be cleared
 #ifdef FEAT_SYN_HL
index c7db9818786714e49492ffe3bdd7fa37de7f40d6..a0f1a960b30aa579c1dbcdc2d71ef77eb07ad468 100644 (file)
@@ -6834,8 +6834,16 @@ nfa_regmatch(
            case NFA_MARK_GT:
            case NFA_MARK_LT:
              {
+               size_t  col = rex.input - rex.line;
                pos_T   *pos = getmark_buf(rex.reg_buf, t->state->val, FALSE);
 
+               // Line may have been freed, get it again.
+               if (REG_MULTI)
+               {
+                   rex.line = reg_getline(rex.lnum);
+                   rex.input = rex.line + col;
+               }
+
                // Compare the mark position to the match position, if the mark
                // exists and mark is set in reg_buf.
                if (pos != NULL && pos->lnum > 0)
index c487b274d2e0480bc975a5fd254b106b0b8aaab3..96c317736df1009990dba940f0be476c5c63a349 100644 (file)
@@ -1037,4 +1037,12 @@ func Test_matching_pos()
   set re&
 endfunc
 
+func Test_using_mark_position()
+  " this was using freed memory
+  new
+  norm O0
+  call assert_fails("s/\\%')", 'E486:')
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 4251b03ea5ad368ebfd43b8fd468b1d044cd9d48..197f0198a43c225eba8977a75877912177e093ad 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3612,
 /**/
     3611,
 /**/