From 02775c490bbd3a601436815807492664574a7517 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 28 Dec 2023 21:49:25 +0100 Subject: [PATCH] Discard additional tokens in non-expression contexts --- .../mwscript/test_scripts.cpp | 26 ++++++++++++++++++- components/compiler/lineparser.cpp | 13 +++++----- components/compiler/skipparser.cpp | 20 ++++++++++++-- components/compiler/skipparser.hpp | 6 ++++- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/apps/openmw_test_suite/mwscript/test_scripts.cpp b/apps/openmw_test_suite/mwscript/test_scripts.cpp index b623084fb9..dbed262235 100644 --- a/apps/openmw_test_suite/mwscript/test_scripts.cpp +++ b/apps/openmw_test_suite/mwscript/test_scripts.cpp @@ -19,7 +19,16 @@ namespace mErrorHandler.reset(); std::istringstream input(scriptBody); Compiler::Scanner scanner(mErrorHandler, input, mCompilerContext.getExtensions()); - scanner.scan(mParser); + try + { + scanner.scan(mParser); + } + catch (...) + { + if (!shouldFail) + logErrors(); + throw; + } if (mErrorHandler.isGood()) return CompiledScript(mParser.getProgram(), mParser.getLocals()); else if (!shouldFail) @@ -385,6 +394,12 @@ if (player->GameHour == 10) set player->GameHour to 20 endif +End)mwscript"; + + const std::string sIssue4996 = R"mwscript(---Begin issue4996 + +player-> SetPos, Z, myZ + 50 + End)mwscript"; const std::string sIssue5087 = R"mwscript(Begin Begin @@ -457,6 +472,9 @@ set a to 1 -+'\/.,><$@---!=\/?--------(){}------ show a +( GetDisabled == 1 ) +GetDisabled == 1 + End)mwscript"; TEST_F(MWScriptTest, mwscript_test_invalid) @@ -810,6 +828,12 @@ End)mwscript"; EXPECT_FALSE(!compile(sIssue4888)); } + TEST_F(MWScriptTest, mwscript_test_4996) + { + registerExtensions(); + EXPECT_FALSE(!compile(sIssue4996)); + } + TEST_F(MWScriptTest, mwscript_test_5087) { registerExtensions(); diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 460dcfb2f9..90bdac1610 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -271,18 +271,14 @@ namespace Compiler mCode.insert(mCode.end(), code.begin(), code.end()); extensions->generateInstructionCode(keyword, mCode, mLiterals, mExplicit, optionals); + SkipParser skip(getErrorHandler(), getContext(), true); + scanner.scan(skip); + mState = EndState; return true; } - } - if (const Extensions* extensions = getContext().getExtensions()) - { char returnType; - std::string argumentType; - - bool hasExplicit = mState == ExplicitState; - if (extensions->isFunction(keyword, returnType, argumentType, hasExplicit)) { if (!hasExplicit && mState == ExplicitState) @@ -302,6 +298,9 @@ namespace Compiler int optionals = mExprParser.parseArguments(argumentType, scanner, code, keyword); mCode.insert(mCode.end(), code.begin(), code.end()); extensions->generateFunctionCode(keyword, mCode, mLiterals, mExplicit, optionals); + + SkipParser skip(getErrorHandler(), getContext(), true); + scanner.scan(skip); } mState = EndState; return true; diff --git a/components/compiler/skipparser.cpp b/components/compiler/skipparser.cpp index 0036e93dda..39d834c8ca 100644 --- a/components/compiler/skipparser.cpp +++ b/components/compiler/skipparser.cpp @@ -1,39 +1,55 @@ #include "skipparser.hpp" +#include "errorhandler.hpp" #include "scanner.hpp" namespace Compiler { - SkipParser::SkipParser(ErrorHandler& errorHandler, const Context& context) + SkipParser::SkipParser(ErrorHandler& errorHandler, const Context& context, bool reportStrayArguments) : Parser(errorHandler, context) + , mReportStrayArguments(reportStrayArguments) { } + void SkipParser::reportStrayArgument(const TokenLoc& loc) + { + if (mReportStrayArguments) + getErrorHandler().warning("Extra argument", loc); + } + bool SkipParser::parseInt(int value, const TokenLoc& loc, Scanner& scanner) { + reportStrayArgument(loc); return true; } bool SkipParser::parseFloat(float value, const TokenLoc& loc, Scanner& scanner) { + reportStrayArgument(loc); return true; } bool SkipParser::parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner) { + reportStrayArgument(loc); return true; } bool SkipParser::parseKeyword(int keyword, const TokenLoc& loc, Scanner& scanner) { + reportStrayArgument(loc); return true; } bool SkipParser::parseSpecial(int code, const TokenLoc& loc, Scanner& scanner) { if (code == Scanner::S_newline) + { + if (mReportStrayArguments) + scanner.putbackSpecial(code, loc); return false; - + } + reportStrayArgument(loc); return true; } } diff --git a/components/compiler/skipparser.hpp b/components/compiler/skipparser.hpp index fdc5effc13..304ed40330 100644 --- a/components/compiler/skipparser.hpp +++ b/components/compiler/skipparser.hpp @@ -11,8 +11,12 @@ namespace Compiler class SkipParser : public Parser { + bool mReportStrayArguments; + + void reportStrayArgument(const TokenLoc& loc); + public: - SkipParser(ErrorHandler& errorHandler, const Context& context); + SkipParser(ErrorHandler& errorHandler, const Context& context, bool reportStrayArguments = false); bool parseInt(int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token.