diff options
| author | Hiroya Fujinami <make.just.on@gmail.com> | 2025-05-16 10:14:26 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-16 10:14:26 +0900 |
| commit | 35000ac2ed3a1829f8d193ffb23da0e44cc6fe5f (patch) | |
| tree | c3430ab96d4cf63f89b1bebd0603266b9c391df8 /regparse.c | |
| parent | 6b10d40157b5287cd13169437800343165eae949 (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.c | 17 |
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); |
