]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0131: potential buffer overflow in regdump() v9.2.0131
authorChristian Brabandt <cb@256bit.org>
Sun, 8 Mar 2026 19:18:28 +0000 (19:18 +0000)
committerChristian Brabandt <cb@256bit.org>
Mon, 9 Mar 2026 20:18:52 +0000 (20:18 +0000)
Problem:  Potential buffer overflow in regdump()
Solution: Add the size to the compiled regular expression and ensure we
          don't read over the limit.

Note: this is not a security issue, because regdump() is typically not
compiled in any version of Vim, so should not affect anybody.

supported by AI claude.

Signed-off-by: Christian Brabandt <cb@256bit.org>
src/regexp.h
src/regexp_bt.c
src/version.c

index 1ff2e1b6efae6fa1bf1c565014bb65868bb44a7e..7a0c3abac6f864a4288ca7807c40886048186dc3 100644 (file)
@@ -73,6 +73,9 @@ typedef struct
     char_u             reganch;
     char_u             *regmust;
     int                        regmlen;
+#ifdef DEBUG
+    int                        regsz;
+#endif
 #ifdef FEAT_SYN_HL
     char_u             reghasz;
 #endif
index 56895188749e793c836f91f2573e4687283b88cb..37fba5e6fdd73bb577ba7351cdc02777f9f09bfa 100644 (file)
@@ -2497,6 +2497,9 @@ bt_regcomp(char_u *expr, int re_flags)
     if (r == NULL)
        return NULL;
     r->re_in_use = FALSE;
+#ifdef DEBUG
+    r->regsz = regsize;
+#endif
 
     // Second pass: emit code.
     regcomp_start(expr, re_flags);
@@ -5200,11 +5203,11 @@ regdump(char_u *pattern, bt_regprog_T *r)
     s = r->program + 1;
     // Loop until we find the END that isn't before a referred next (an END
     // can also appear in a NOMATCH operand).
-    while (op != END || s <= end)
+    while ((op != END || s <= end) && s < r->program + r->regsz)
     {
        op = OP(s);
        fprintf(f, "%2d%s", (int)(s - r->program), regprop(s)); // Where, what.
-       next = regnext(s);
+       next = (s + 3 <= r->program + r->regsz) ? regnext(s) : NULL;
        if (next == NULL)       // Next ptr.
            fprintf(f, "(0)");
        else
@@ -5230,14 +5233,22 @@ regdump(char_u *pattern, bt_regprog_T *r)
            s += 5;
        }
        s += 3;
+       if (op == MULTIBYTECODE)
+       {
+           fprintf(f, " mbc=%d", utf_ptr2char(s));
+           s += utfc_ptr2len(s);
+       }
        if (op == ANYOF || op == ANYOF + ADD_NL
                || op == ANYBUT || op == ANYBUT + ADD_NL
                || op == EXACTLY)
        {
            // Literal string, where present.
            fprintf(f, "\nxxxxxxxxx\n");
-           while (*s != NUL)
-               fprintf(f, "%c", *s++);
+           while (*s != NUL && s < r->program + r->regsz)
+           {
+               fprintf(f, "%c", *s);
+               s += utfc_ptr2len(s);  // advance by full char including combining
+           }
            fprintf(f, "\nxxxxxxxxx\n");
            s++;
        }
index 0a8788b0b53d4a5a5bce7941ed752c4fa7e5b67c..9f4687ba1dfab8a93e146099c30732d174568eae 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    131,
 /**/
     130,
 /**/