From 41794dbadbdbdd7b2fde3c3b6f47f1f4744efd60 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 17 Feb 2017 02:50:00 +0000 Subject: [PATCH] Fix a crash in expression parser. Found by lineprinter0@gmail.com through fuzzing. --- src/expr.cpp | 2 +- test/core/expr/test.cpp | 2 ++ test/debugtool.cpp | 9 +++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/expr.cpp b/src/expr.cpp index 03caa216..cbff0385 100644 --- a/src/expr.cpp +++ b/src/expr.cpp @@ -852,7 +852,7 @@ bool ExprParser::Parse(std::string *error, size_t reduceUntil) { // sub-expression if(!Parse(error, /*reduceUntil=*/stack.size())) return false; - if(stack.back().type != TokenType::PAREN_RIGHT) { + if(stack.empty() || stack.back().type != TokenType::PAREN_RIGHT) { *error = "Expected ')'"; return false; } diff --git a/test/core/expr/test.cpp b/test/core/expr/test.cpp index 8ae4c757..5e73a029 100644 --- a/test/core/expr/test.cpp +++ b/test/core/expr/test.cpp @@ -107,4 +107,6 @@ TEST_CASE(errors) { "Expected an operand"); CHECK_PARSE_ERR("( 2 + 2", "Expected ')'"); + CHECK_PARSE_ERR("(", + "Expected ')'"); } diff --git a/test/debugtool.cpp b/test/debugtool.cpp index 9553dbd1..9cbfb24f 100644 --- a/test/debugtool.cpp +++ b/test/debugtool.cpp @@ -9,8 +9,13 @@ int main(int argc, char **argv) { std::vector args = InitPlatform(argc, argv); if(args.size() == 3 && args[1] == "expr") { - std::string expr = args[2]; - fprintf(stderr, "%g\n", Expr::From(expr.c_str(), false)->Eval()); + std::string expr = args[2], err; + Expr *e = Expr::Parse(expr.c_str(), &err); + if(e == NULL) { + fprintf(stderr, "cannot parse: %s\n", err.c_str()); + } else { + fprintf(stderr, "%g\n", e->Eval()); + } FreeAllTemporary(); } else { fprintf(stderr, "Usage: %s \n", args[0].c_str());