Check backref number buffer overrun [Bug #16376]

This commit is contained in:
xtkoba (Tee KOBAYASHI) 2021-03-15 10:15:10 +09:00 committed by Nobuyoshi Nakada
parent 2a6bfd2246
commit 0846c2da45
No known key found for this signature in database
GPG Key ID: 7CD2805BFA3770C6
2 changed files with 18 additions and 9 deletions

View File

@ -1933,7 +1933,7 @@ noname_disable_map(Node** plink, GroupNumRemap* map, int* counter)
} }
static int static int
renumber_node_backref(Node* node, GroupNumRemap* map) renumber_node_backref(Node* node, GroupNumRemap* map, const int num_mem)
{ {
int i, pos, n, old_num; int i, pos, n, old_num;
int *backs; int *backs;
@ -1949,6 +1949,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
backs = bn->back_dynamic; backs = bn->back_dynamic;
for (i = 0, pos = 0; i < old_num; i++) { for (i = 0, pos = 0; i < old_num; i++) {
if (backs[i] > num_mem) return ONIGERR_INVALID_BACKREF;
n = map[backs[i]].new_val; n = map[backs[i]].new_val;
if (n > 0) { if (n > 0) {
backs[pos] = n; backs[pos] = n;
@ -1961,7 +1962,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
} }
static int static int
renumber_by_map(Node* node, GroupNumRemap* map) renumber_by_map(Node* node, GroupNumRemap* map, const int num_mem)
{ {
int r = 0; int r = 0;
@ -1969,28 +1970,30 @@ renumber_by_map(Node* node, GroupNumRemap* map)
case NT_LIST: case NT_LIST:
case NT_ALT: case NT_ALT:
do { do {
r = renumber_by_map(NCAR(node), map); r = renumber_by_map(NCAR(node), map, num_mem);
} while (r == 0 && IS_NOT_NULL(node = NCDR(node))); } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break; break;
case NT_QTFR: case NT_QTFR:
r = renumber_by_map(NQTFR(node)->target, map); r = renumber_by_map(NQTFR(node)->target, map, num_mem);
break; break;
case NT_ENCLOSE: case NT_ENCLOSE:
{ {
EncloseNode* en = NENCLOSE(node); EncloseNode* en = NENCLOSE(node);
if (en->type == ENCLOSE_CONDITION) if (en->type == ENCLOSE_CONDITION) {
if (en->regnum > num_mem) return ONIGERR_INVALID_BACKREF;
en->regnum = map[en->regnum].new_val; en->regnum = map[en->regnum].new_val;
r = renumber_by_map(en->target, map); }
r = renumber_by_map(en->target, map, num_mem);
} }
break; break;
case NT_BREF: case NT_BREF:
r = renumber_node_backref(node, map); r = renumber_node_backref(node, map, num_mem);
break; break;
case NT_ANCHOR: case NT_ANCHOR:
if (NANCHOR(node)->target) if (NANCHOR(node)->target)
r = renumber_by_map(NANCHOR(node)->target, map); r = renumber_by_map(NANCHOR(node)->target, map, num_mem);
break; break;
default: default:
@ -2052,7 +2055,7 @@ disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
r = noname_disable_map(root, map, &counter); r = noname_disable_map(root, map, &counter);
if (r != 0) return r; if (r != 0) return r;
r = renumber_by_map(*root, map); r = renumber_by_map(*root, map, env->num_mem);
if (r != 0) return r; if (r != 0) return r;
for (i = 1, pos = 1; i <= env->num_mem; i++) { for (i = 1, pos = 1; i <= env->num_mem; i++) {

View File

@ -1312,6 +1312,12 @@ class TestRegexp < Test::Unit::TestCase
assert_nil($1) assert_nil($1)
end end
def test_backref_overrun
assert_raise_with_message(SyntaxError, /invalid backref number/) do
eval(%["".match /(())(?<X>)((?(90000)))/])
end
end
# This assertion is for porting x2() tests in testpy.py of Onigmo. # This assertion is for porting x2() tests in testpy.py of Onigmo.
def assert_match_at(re, str, positions, msg = nil) def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp) re = Regexp.new(re) unless re.is_a?(Regexp)