Skip to content

Commit

Permalink
merge revision(s) 0846c2d,6c7cb00c094332a208cf36e5cd723a9ba60c41b8: […
Browse files Browse the repository at this point in the history
…Backport #16376]

	Check backref number buffer overrun [Bug #16376]

	---
	 regcomp.c                | 21 ++++++++++++---------
	 test/ruby/test_regexp.rb |  6 ++++++
	 2 files changed, 18 insertions(+), 9 deletions(-)

	test/ruby/test_regexp.rb: Avoid "ambiguity between regexp and two
	 divisions"

	---
	 test/ruby/test_regexp.rb | 2 +-
	 1 file changed, 1 insertion(+), 1 deletion(-)
  • Loading branch information
unak committed Dec 31, 2021
1 parent 426266a commit 1cc5567
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
21 changes: 12 additions & 9 deletions regcomp.c
Expand Up @@ -1914,7 +1914,7 @@ noname_disable_map(Node** plink, GroupNumRemap* map, int* counter)
}

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 *backs;
Expand All @@ -1930,6 +1930,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
backs = bn->back_dynamic;

for (i = 0, pos = 0; i < old_num; i++) {
if (backs[i] > num_mem) return ONIGERR_INVALID_BACKREF;
n = map[backs[i]].new_val;
if (n > 0) {
backs[pos] = n;
Expand All @@ -1942,36 +1943,38 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
}

static int
renumber_by_map(Node* node, GroupNumRemap* map)
renumber_by_map(Node* node, GroupNumRemap* map, const int num_mem)
{
int r = 0;

switch (NTYPE(node)) {
case NT_LIST:
case NT_ALT:
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)));
break;
case NT_QTFR:
r = renumber_by_map(NQTFR(node)->target, map);
r = renumber_by_map(NQTFR(node)->target, map, num_mem);
break;
case NT_ENCLOSE:
{
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;
r = renumber_by_map(en->target, map);
}
r = renumber_by_map(en->target, map, num_mem);
}
break;

case NT_BREF:
r = renumber_node_backref(node, map);
r = renumber_node_backref(node, map, num_mem);
break;

case NT_ANCHOR:
if (NANCHOR(node)->target)
r = renumber_by_map(NANCHOR(node)->target, map);
r = renumber_by_map(NANCHOR(node)->target, map, num_mem);
break;

default:
Expand Down Expand Up @@ -2033,7 +2036,7 @@ disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
r = noname_disable_map(root, map, &counter);
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;

for (i = 1, pos = 1; i <= env->num_mem; i++) {
Expand Down
6 changes: 6 additions & 0 deletions test/ruby/test_regexp.rb
Expand Up @@ -1293,6 +1293,12 @@ def test_absent
assert_nil($1)
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.
def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp)
Expand Down
2 changes: 1 addition & 1 deletion version.h
Expand Up @@ -2,7 +2,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 207
#define RUBY_PATCHLEVEL 208

#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 12
Expand Down

0 comments on commit 1cc5567

Please sign in to comment.