mirror of
https://github.com/neovim/neovim.git
synced 2026-07-14 05:10:36 +00:00
vim-patch:9.2.0131: potential buffer overflow in regdump() (#38217)
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.
9360647715
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
@@ -99,6 +99,9 @@ typedef struct {
|
|||||||
uint8_t reganch;
|
uint8_t reganch;
|
||||||
uint8_t *regmust;
|
uint8_t *regmust;
|
||||||
int regmlen;
|
int regmlen;
|
||||||
|
#ifdef REGEXP_DEBUG
|
||||||
|
int regsz;
|
||||||
|
#endif
|
||||||
uint8_t reghasz;
|
uint8_t reghasz;
|
||||||
uint8_t program[];
|
uint8_t program[];
|
||||||
} bt_regprog_T;
|
} bt_regprog_T;
|
||||||
@@ -5449,6 +5452,9 @@ static regprog_T *bt_regcomp(uint8_t *expr, int re_flags)
|
|||||||
// Allocate space.
|
// Allocate space.
|
||||||
bt_regprog_T *r = xmalloc(offsetof(bt_regprog_T, program) + (size_t)regsize);
|
bt_regprog_T *r = xmalloc(offsetof(bt_regprog_T, program) + (size_t)regsize);
|
||||||
r->re_in_use = false;
|
r->re_in_use = false;
|
||||||
|
#ifdef REGEXP_DEBUG
|
||||||
|
r->regsz = regsize;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Second pass: emit code.
|
// Second pass: emit code.
|
||||||
regcomp_start(expr, re_flags);
|
regcomp_start(expr, re_flags);
|
||||||
@@ -7832,10 +7838,10 @@ static void regdump(uint8_t *pattern, bt_regprog_T *r)
|
|||||||
s = &r->program[1];
|
s = &r->program[1];
|
||||||
// Loop until we find the END that isn't before a referred next (an END
|
// Loop until we find the END that isn't before a referred next (an END
|
||||||
// can also appear in a NOMATCH operand).
|
// 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);
|
op = OP(s);
|
||||||
fprintf(f, "%2d%s", (int)(s - r->program), regprop(s)); // Where, what.
|
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.
|
if (next == NULL) { // Next ptr.
|
||||||
fprintf(f, "(0)");
|
fprintf(f, "(0)");
|
||||||
} else {
|
} else {
|
||||||
@@ -7859,13 +7865,18 @@ static void regdump(uint8_t *pattern, bt_regprog_T *r)
|
|||||||
s += 5;
|
s += 5;
|
||||||
}
|
}
|
||||||
s += 3;
|
s += 3;
|
||||||
|
if (op == MULTIBYTECODE) {
|
||||||
|
fprintf(f, " mbc=%d", utf_ptr2char(s));
|
||||||
|
s += utfc_ptr2len(s);
|
||||||
|
}
|
||||||
if (op == ANYOF || op == ANYOF + ADD_NL
|
if (op == ANYOF || op == ANYOF + ADD_NL
|
||||||
|| op == ANYBUT || op == ANYBUT + ADD_NL
|
|| op == ANYBUT || op == ANYBUT + ADD_NL
|
||||||
|| op == EXACTLY) {
|
|| op == EXACTLY) {
|
||||||
// Literal string, where present.
|
// Literal string, where present.
|
||||||
fprintf(f, "\nxxxxxxxxx\n");
|
fprintf(f, "\nxxxxxxxxx\n");
|
||||||
while (*s != NUL) {
|
while (*s != NUL && s < r->program + r->regsz) {
|
||||||
fprintf(f, "%c", *s++);
|
fprintf(f, "%c", *s);
|
||||||
|
s += utfc_ptr2len(s); // advance by full char including combining
|
||||||
}
|
}
|
||||||
fprintf(f, "\nxxxxxxxxx\n");
|
fprintf(f, "\nxxxxxxxxx\n");
|
||||||
s++;
|
s++;
|
||||||
|
|||||||
Reference in New Issue
Block a user