Prevent double free for too big repetition quantifiers (#13332)
Prevent double free for too big repetition quantifiers The previous implementation calls `free(node)` twice (on parsing and compiling a regexp) when it has an error, so it leads to a double-free issue. This commit enforces `free(node)` once by introducing a temporal pointer to hold parsing nodes.
This commit is contained in:
parent
6b10d40157
commit
35000ac2ed
Notes:
git
2025-05-16 01:14:39 +00:00
Merged-By: makenowjust <make.just.on@gmail.com>
17
regparse.c
17
regparse.c
@ -6721,7 +6721,7 @@ parse_subexp(Node** top, OnigToken* tok, int term,
|
|||||||
UChar** src, UChar* end, ScanEnv* env)
|
UChar** src, UChar* end, ScanEnv* env)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
Node *node, **headp;
|
Node *node, *topnode, **headp;
|
||||||
|
|
||||||
*top = NULL;
|
*top = NULL;
|
||||||
env->parse_depth++;
|
env->parse_depth++;
|
||||||
@ -6737,26 +6737,29 @@ parse_subexp(Node** top, OnigToken* tok, int term,
|
|||||||
*top = node;
|
*top = node;
|
||||||
}
|
}
|
||||||
else if (r == TK_ALT) {
|
else if (r == TK_ALT) {
|
||||||
*top = onig_node_new_alt(node, NULL);
|
topnode = onig_node_new_alt(node, NULL);
|
||||||
headp = &(NCDR(*top));
|
headp = &(NCDR(topnode));
|
||||||
while (r == TK_ALT) {
|
while (r == TK_ALT) {
|
||||||
r = fetch_token(tok, src, end, env);
|
r = fetch_token(tok, src, end, env);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
onig_node_free(node);
|
onig_node_free(topnode);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
r = parse_branch(&node, tok, term, src, end, env);
|
r = parse_branch(&node, tok, term, src, end, env);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
onig_node_free(node);
|
onig_node_free(topnode);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
*headp = onig_node_new_alt(node, NULL);
|
*headp = onig_node_new_alt(node, NULL);
|
||||||
headp = &(NCDR(*headp));
|
headp = &(NCDR(*headp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->type != (enum TokenSyms )term)
|
if (tok->type != (enum TokenSyms )term) {
|
||||||
|
onig_node_free(topnode);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
*top = topnode;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
onig_node_free(node);
|
onig_node_free(node);
|
||||||
|
@ -1875,6 +1875,12 @@ class TestRegexp < Test::Unit::TestCase
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_too_big_number_for_repeat_range
|
||||||
|
assert_raise_with_message(SyntaxError, /too big number for repeat range/) do
|
||||||
|
eval(%[/|{1000000}/])
|
||||||
|
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user