From bfc40ffe9f2fd6deab26f0f59cdaafe2da1c17c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 21 Jun 2013 20:10:46 +0200 Subject: [PATCH] Fixed #4868 (Segmentation fault in Preprocessor::handleIncludes()) --- lib/preprocessor.cpp | 10 +++------- test/testpreprocessor.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index e0e405ece..34761731e 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1970,15 +1970,15 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str if (indent == indentmatch + 1) elseIsTrue = true; - } else if (!suppressCurrentCodePath && line.compare(0,4,"#if ") == 0) { - if (indent == indentmatch && match_cfg_def(defs, line.substr(4))) { + } else if (line.compare(0,4,"#if ") == 0) { + if (!suppressCurrentCodePath && indent == indentmatch && match_cfg_def(defs, line.substr(4))) { elseIsTrue = false; indentmatch++; } ++indent; if (indent == indentmatch + 1) - elseIsTrue = true; + elseIsTrue = true; // this value doesn't matter when suppressCurrentCodePath is true } else if (line.compare(0,6,"#elif ") == 0 || line.compare(0,5,"#else") == 0) { if (!elseIsTrue) { if (indentmatch == indent) { @@ -1994,10 +1994,6 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str } } } - if (suppressCurrentCodePath) { - suppressCurrentCodePath = false; - indentmatch = indent; - } } else if (line.compare(0, 6, "#endif") == 0) { if (indent > 0) --indent; diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index c8899c148..dfee67cf3 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -268,6 +268,7 @@ private: TEST_CASE(def_missingInclude); TEST_CASE(def_handleIncludes_ifelse1); // problems in handleIncludes for #else TEST_CASE(def_handleIncludes_ifelse2); + TEST_CASE(def_handleIncludes_ifelse3); // #4868 - crash TEST_CASE(def_valueWithParentheses); // #3531 @@ -3510,6 +3511,25 @@ private: preprocessor.handleIncludes(code, "test.c", includePaths, defs).find("123")); } + void def_handleIncludes_ifelse3() { // #4865 + const char code[] = "#ifdef A\n" + "#if defined(SOMETHING_NOT_DEFINED)\n" + "#else\n" + "#endif\n" + "#else\n" + "#endif"; + + Settings settings; + settings.userUndefs.insert("A"); + Preprocessor preprocessor(&settings, this); + + const std::list includePaths; + std::map defs; + defs["B"] = "1"; + defs["C"] = "1"; + preprocessor.handleIncludes(code, "test.c", includePaths, defs); // don't crash + } + void def_valueWithParentheses() { // #define should introduce a new symbol regardless of parentheses in the value // and regardless of white space in weird places (people do this for some reason).