From bc0434f1ced83fc3a5f5ace44cbad3acdc5e3e29 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 5 Oct 2021 22:15:28 -0700 Subject: [PATCH] expressions: Parse multiple sets of parentheses for grouping together. Fuzzers are fond of driving expression parsers to failure by exhausting the stack in trivial ways. This defeats the simplest attempts by lining up thousands of left parentheses in a row. I am a bit curious whether the fuzzer will now invent something more sophisticated, such as nested function calls or non-empty expressions like 1+(1+(1+(1+(1+.... This fixes bug #61286. Thanks to Irfan Ariq for reporting the bug. --- src/language/expressions/parse.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index 57307bf306..0493ed878b 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -953,11 +953,22 @@ parse_primary (struct lexer *lexer, struct expression *e) case T_LPAREN: { - union any_node *node; - lex_get (lexer); - node = parse_or (lexer, e); - if (node != NULL && !lex_force_match (lexer, T_RPAREN)) + /* Count number of left parentheses so that we can match them against + an equal number of right parentheses. This defeats trivial attempts + to exhaust the stack with a lot of left parentheses. (More + sophisticated attacks will still succeed.) */ + size_t n = 0; + while (lex_match (lexer, T_LPAREN)) + n++; + + union any_node *node = parse_or (lexer, e); + if (!node) return NULL; + + for (size_t i = 0; i < n; i++) + if (!lex_force_match (lexer, T_RPAREN)) + return NULL; + return node; } -- 2.30.2