From b1d4176b6edca72afb1996706563f4c86fa9af55 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 23 Dec 2023 13:54:57 +0100 Subject: [PATCH] Ensure not closing macro definition parameters throws an error --- .../Parsing/Impl/DefinesStreamProxy.cpp | 3 ++ src/Parser/Parsing/ParsingException.h | 2 +- .../Parsing/Impl/DefinesStreamProxyTests.cpp | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp index c24ae47e2..ef249e5f4 100644 --- a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp +++ b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp @@ -148,6 +148,9 @@ void DefinesStreamProxy::ContinueDefine(const ParserLine& line, const unsigned c const auto lineEndEscapePos = GetLineEndEscapePos(line); if (lineEndEscapePos < 0) { + if (m_parameter_state != ParameterState::NOT_IN_PARAMETERS) + throw ParsingException(CreatePos(line, currentPos), "Unclosed macro parameters"); + if (currentPos <= 0) m_current_define_value << line.m_line; else diff --git a/src/Parser/Parsing/ParsingException.h b/src/Parser/Parsing/ParsingException.h index e036f8732..34876ff14 100644 --- a/src/Parser/Parsing/ParsingException.h +++ b/src/Parser/Parsing/ParsingException.h @@ -6,7 +6,7 @@ #include #include -class ParsingException final : std::exception +class ParsingException final : public std::exception { TokenPos m_pos; std::string m_message; diff --git a/test/ParserTests/Parsing/Impl/DefinesStreamProxyTests.cpp b/test/ParserTests/Parsing/Impl/DefinesStreamProxyTests.cpp index dc93ee57c..da2d2e7ec 100644 --- a/test/ParserTests/Parsing/Impl/DefinesStreamProxyTests.cpp +++ b/test/ParserTests/Parsing/Impl/DefinesStreamProxyTests.cpp @@ -1,8 +1,14 @@ #include "Parsing/Impl/DefinesStreamProxy.h" #include "Parsing/Mock/MockParserLineStream.h" +#include "Parsing/ParsingException.h" #include #include +#include +#include +#include + +using namespace Catch::Matchers; namespace test::parsing::impl::defines_stream_proxy { @@ -13,6 +19,12 @@ namespace test::parsing::impl::defines_stream_proxy REQUIRE(line.m_line == value); } + void ExpectErrorInLine(IParserLineStream* stream, const int lineNumber, const int columnNumber) + { + REQUIRE_THROWS_MATCHES( + stream->NextLine(), ParsingException, MessageMatches(ContainsSubstring("L" + std::to_string(lineNumber) + ":" + std::to_string(columnNumber)))); + } + TEST_CASE("DefinesStreamProxy: Ensure simple define and positive ifdef is working", "[parsing][parsingstream]") { const std::vector lines{ @@ -725,6 +737,22 @@ namespace test::parsing::impl::defines_stream_proxy REQUIRE(proxy.Eof()); } + TEST_CASE("DefinesStreamProxy: Macro definition that has unclosed parameters throws an error", "[parsing][parsingstream]") + { + const std::vector lines{ + "#define testMacro(", + " a,", + " b,", + " c) a + b - c", + "testMacro(1, 2, 3)", + }; + + MockParserLineStream mockStream(lines); + DefinesStreamProxy proxy(&mockStream); + + ExpectErrorInLine(&proxy, 1, 19); + } + TEST_CASE("DefinesStreamProxy: Macro usages can span multiple lines if they have args", "[parsing][parsingstream]") { const std::vector lines{