diff --git a/simplecpp.cpp b/simplecpp.cpp index 21c4bd82..b9e34c23 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1693,7 +1693,9 @@ namespace simplecpp { nameTokDef = nametoken; variadic = false; variadicOpt = false; + delete optExpandValue; optExpandValue = nullptr; + delete optNoExpandValue; optNoExpandValue = nullptr; if (!nameTokDef) { valueToken = endToken = nullptr; @@ -2367,8 +2369,8 @@ namespace simplecpp { bool variadicOpt; /** Expansion value for varadic macros with __VA_OPT__ expanded and discarded respectively */ - const TokenList *optExpandValue; - const TokenList *optNoExpandValue; + const TokenList *optExpandValue{}; + const TokenList *optNoExpandValue{}; /** was the value of this macro actually defined in the code? */ bool valueDefinedInCode_; diff --git a/test.cpp b/test.cpp index 0ecaa3b1..f2bfe697 100644 --- a/test.cpp +++ b/test.cpp @@ -3217,6 +3217,7 @@ static void safe_api() #endif } +// crashes detected by fuzzer static void fuzz_crash() { { @@ -3231,6 +3232,16 @@ static void fuzz_crash() } } +// memory leaks detected by LSAN/valgrind +static void leak() +{ + { // #498 + const char code[] = "#define e(...)__VA_OPT__()\n" + "#define e\n"; + (void)preprocess(code, simplecpp::DUI()); + } +} + int main(int argc, char **argv) { TEST_CASE(backslash); @@ -3487,5 +3498,7 @@ int main(int argc, char **argv) TEST_CASE(fuzz_crash); + TEST_CASE(leak); + return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS; }