From 41794dbadbdbdd7b2fde3c3b6f47f1f4744efd60 Mon Sep 17 00:00:00 2001 From: whitequark <whitequark@whitequark.org> 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 03caa21..cbff038 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 8ae4c75..5e73a02 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 9553dbd..9cbfb24 100644 --- a/test/debugtool.cpp +++ b/test/debugtool.cpp @@ -9,8 +9,13 @@ int main(int argc, char **argv) { std::vector<std::string> 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 <command> <options>\n", args[0].c_str());