Skip to content

Commit bfc40ff

Browse files
committed
Fixed cppcheck-opensource#4868 (Segmentation fault in Preprocessor::handleIncludes())
1 parent e4270ba commit bfc40ff

2 files changed

Lines changed: 23 additions & 7 deletions

File tree

lib/preprocessor.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,15 +1970,15 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
19701970
if (indent == indentmatch + 1)
19711971
elseIsTrue = true;
19721972

1973-
} else if (!suppressCurrentCodePath && line.compare(0,4,"#if ") == 0) {
1974-
if (indent == indentmatch && match_cfg_def(defs, line.substr(4))) {
1973+
} else if (line.compare(0,4,"#if ") == 0) {
1974+
if (!suppressCurrentCodePath && indent == indentmatch && match_cfg_def(defs, line.substr(4))) {
19751975
elseIsTrue = false;
19761976
indentmatch++;
19771977
}
19781978
++indent;
19791979

19801980
if (indent == indentmatch + 1)
1981-
elseIsTrue = true;
1981+
elseIsTrue = true; // this value doesn't matter when suppressCurrentCodePath is true
19821982
} else if (line.compare(0,6,"#elif ") == 0 || line.compare(0,5,"#else") == 0) {
19831983
if (!elseIsTrue) {
19841984
if (indentmatch == indent) {
@@ -1994,10 +1994,6 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
19941994
}
19951995
}
19961996
}
1997-
if (suppressCurrentCodePath) {
1998-
suppressCurrentCodePath = false;
1999-
indentmatch = indent;
2000-
}
20011997
} else if (line.compare(0, 6, "#endif") == 0) {
20021998
if (indent > 0)
20031999
--indent;

test/testpreprocessor.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ class TestPreprocessor : public TestFixture {
268268
TEST_CASE(def_missingInclude);
269269
TEST_CASE(def_handleIncludes_ifelse1); // problems in handleIncludes for #else
270270
TEST_CASE(def_handleIncludes_ifelse2);
271+
TEST_CASE(def_handleIncludes_ifelse3); // #4868 - crash
271272

272273
TEST_CASE(def_valueWithParentheses); // #3531
273274

@@ -3510,6 +3511,25 @@ class TestPreprocessor : public TestFixture {
35103511
preprocessor.handleIncludes(code, "test.c", includePaths, defs).find("123"));
35113512
}
35123513

3514+
void def_handleIncludes_ifelse3() { // #4865
3515+
const char code[] = "#ifdef A\n"
3516+
"#if defined(SOMETHING_NOT_DEFINED)\n"
3517+
"#else\n"
3518+
"#endif\n"
3519+
"#else\n"
3520+
"#endif";
3521+
3522+
Settings settings;
3523+
settings.userUndefs.insert("A");
3524+
Preprocessor preprocessor(&settings, this);
3525+
3526+
const std::list<std::string> includePaths;
3527+
std::map<std::string,std::string> defs;
3528+
defs["B"] = "1";
3529+
defs["C"] = "1";
3530+
preprocessor.handleIncludes(code, "test.c", includePaths, defs); // don't crash
3531+
}
3532+
35133533
void def_valueWithParentheses() {
35143534
// #define should introduce a new symbol regardless of parentheses in the value
35153535
// and regardless of white space in weird places (people do this for some reason).

0 commit comments

Comments
 (0)