summaryrefslogtreecommitdiff
path: root/regparse.c
diff options
context:
space:
mode:
authorHiroya Fujinami <make.just.on@gmail.com>2025-05-16 10:14:26 +0900
committerGitHub <noreply@github.com>2025-05-16 10:14:26 +0900
commit35000ac2ed3a1829f8d193ffb23da0e44cc6fe5f (patch)
treec3430ab96d4cf63f89b1bebd0603266b9c391df8 /regparse.c
parent6b10d40157b5287cd13169437800343165eae949 (diff)
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.
Notes
Notes: Merged-By: makenowjust <make.just.on@gmail.com>
Diffstat (limited to 'regparse.c')
-rw-r--r--regparse.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/regparse.c b/regparse.c
index 1026c323b5..7b2bc7eea8 100644
--- a/regparse.c
+++ b/regparse.c
@@ -6721,7 +6721,7 @@ parse_subexp(Node** top, OnigToken* tok, int term,
UChar** src, UChar* end, ScanEnv* env)
{
int r;
- Node *node, **headp;
+ Node *node, *topnode, **headp;
*top = NULL;
env->parse_depth++;
@@ -6737,26 +6737,29 @@ parse_subexp(Node** top, OnigToken* tok, int term,
*top = node;
}
else if (r == TK_ALT) {
- *top = onig_node_new_alt(node, NULL);
- headp = &(NCDR(*top));
+ topnode = onig_node_new_alt(node, NULL);
+ headp = &(NCDR(topnode));
while (r == TK_ALT) {
r = fetch_token(tok, src, end, env);
if (r < 0) {
- onig_node_free(node);
+ onig_node_free(topnode);
return r;
}
r = parse_branch(&node, tok, term, src, end, env);
if (r < 0) {
- onig_node_free(node);
+ onig_node_free(topnode);
return r;
}
*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;
+ }
+ *top = topnode;
}
else {
onig_node_free(node);