From 57e5444427ca096b837e4ed61e05e5632872810f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 12 Feb 2025 07:10:30 +0100 Subject: [PATCH] Fix #403 (Stack overflow in Macro::expand()) --- simplecpp.cpp | 3 ++- test.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 20ae2528..88994736 100755 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -2139,7 +2139,8 @@ namespace simplecpp { for (const Token *partok = parametertokens[argnr]->next; partok != parametertokens[argnr + 1U];) { const MacroMap::const_iterator it = macros.find(partok->str()); if (it != macros.end() && !partok->isExpandedFrom(&it->second) && (partok->str() == name() || expandedmacros.find(partok->str()) == expandedmacros.end())) { - const std::set expandedmacros2; // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation + std::set expandedmacros2(expandedmacros); // temporary amnesia to allow reexpansion of currently expanding macros during argument evaluation + expandedmacros2.erase(name()); partok = it->second.expand(output, loc, partok, macros, expandedmacros2); } else { output->push_back(newMacroToken(partok->str(), loc, isReplaced(expandedmacros), partok)); diff --git a/test.cpp b/test.cpp index 3ff00b33..f0ef918d 100644 --- a/test.cpp +++ b/test.cpp @@ -850,6 +850,16 @@ static void define_define_22() // #400 inner macro not expanded after hash hash ASSERT_EQUALS("\n\n\n34", preprocess(code)); } +static void define_define_23() // #403 crash (infinite recursion) +{ + const char code[] = "#define C_(x, y) x ## y\n" + "#define C(x, y) C_(x, y)\n" + "#define X(func) C(Y, C(func, Z))\n" + "#define die X(die)\n" + "die(void);\n"; + ASSERT_EQUALS("\n\n\n\nYdieZ ( void ) ;", preprocess(code)); +} + static void define_va_args_1() { const char code[] = "#define A(fmt...) dostuff(fmt)\n" @@ -3030,6 +3040,7 @@ int main(int argc, char **argv) TEST_CASE(define_define_20); // 384 arg contains comma TEST_CASE(define_define_21); TEST_CASE(define_define_22); // #400 + TEST_CASE(define_define_23); // #403 - crash, infinite recursion TEST_CASE(define_va_args_1); TEST_CASE(define_va_args_2); TEST_CASE(define_va_args_3);