From: Christian Brabandt Date: Sun, 8 Mar 2026 19:18:28 +0000 (+0000) Subject: patch 9.2.0131: potential buffer overflow in regdump() X-Git-Tag: v9.2.0131^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9360647715c2d7e4ed484ef0188f7fcbb5c414a7;p=thirdparty%2Fvim.git patch 9.2.0131: potential buffer overflow in regdump() 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 --- diff --git a/src/regexp.h b/src/regexp.h index 1ff2e1b6ef..7a0c3abac6 100644 --- a/src/regexp.h +++ b/src/regexp.h @@ -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 diff --git a/src/regexp_bt.c b/src/regexp_bt.c index 5689518874..37fba5e6fd 100644 --- a/src/regexp_bt.c +++ b/src/regexp_bt.c @@ -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++; } diff --git a/src/version.c b/src/version.c index 0a8788b0b5..9f4687ba1d 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 131, /**/ 130, /**/