Skip to content

Commit 6a46223

Browse files
Fix #13566 fuzzing crash in ValueFlowAnalyzer::assume() (#7245)
1 parent 6b38f78 commit 6a46223

File tree

4 files changed

+35
-26
lines changed

4 files changed

+35
-26
lines changed

Diff for: lib/tokenize.cpp

+24-16
Original file line numberDiff line numberDiff line change
@@ -8545,26 +8545,34 @@ void Tokenizer::findGarbageCode() const
85458545
syntaxError(tok);
85468546
}
85478547

8548-
if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... }
8549-
if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{|}|)")) {
8550-
if (Token::Match(tok->previous(), "[,(]")) {
8551-
const Token *prev = tok->previous();
8552-
while (prev && prev->str() != "(") {
8553-
if (prev->str() == ")")
8554-
prev = prev->link();
8555-
prev = prev->previous();
8548+
if (tok->isControlFlowKeyword()) {
8549+
if (Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... }
8550+
if (tok->previous() && !Token::Match(tok->previous(), "%name%|:|;|{|}|)")) {
8551+
if (Token::Match(tok->previous(), "[,(]")) {
8552+
const Token *prev = tok->previous();
8553+
while (prev && prev->str() != "(") {
8554+
if (prev->str() == ")")
8555+
prev = prev->link();
8556+
prev = prev->previous();
8557+
}
8558+
if (prev && Token::Match(prev->previous(), "%name% ("))
8559+
unknownMacroError(prev->previous());
85568560
}
8557-
if (prev && Token::Match(prev->previous(), "%name% ("))
8558-
unknownMacroError(prev->previous());
8561+
if (!Token::simpleMatch(tok->tokAt(-2), "operator \"\" if"))
8562+
syntaxError(tok);
85598563
}
8560-
if (!Token::simpleMatch(tok->tokAt(-2), "operator \"\" if"))
8564+
if (!Token::Match(tok->next(), "( !!)"))
85618565
syntaxError(tok);
8566+
if (tok->str() != "for") {
8567+
if (isGarbageExpr(tok->next(), tok->linkAt(1), cpp && (mSettings.standards.cpp>=Standards::cppstd_t::CPP17)))
8568+
syntaxError(tok);
8569+
}
85628570
}
8563-
if (!Token::Match(tok->next(), "( !!)"))
8564-
syntaxError(tok);
8565-
if (tok->str() != "for") {
8566-
if (isGarbageExpr(tok->next(), tok->linkAt(1), cpp && (mSettings.standards.cpp>=Standards::cppstd_t::CPP17)))
8567-
syntaxError(tok);
8571+
if (Token::simpleMatch(tok, "do {")) {
8572+
if (!Token::simpleMatch(tok->linkAt(1), "} while ("))
8573+
syntaxError(tok->linkAt(1));
8574+
if (!Token::simpleMatch(tok->linkAt(1)->linkAt(2), ") ;"))
8575+
syntaxError(tok->linkAt(1)->linkAt(2));
85688576
}
85698577
}
85708578

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
f(a b){do{if(b){}}while(e)x}

Diff for: test/testother.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -10842,31 +10842,31 @@ class TestOther : public TestFixture {
1084210842
"unsigned char c;\n"
1084310843
"do {\n"
1084410844
" c = getc (pFile);\n"
10845-
"} while (c != EOF)"
10845+
"} while (c != EOF);"
1084610846
"}");
1084710847
ASSERT_EQUALS("[test.cpp:5]: (warning) Storing getc() return value in char variable and then comparing with EOF.\n", errout_str());
1084810848

1084910849
check("void f (FILE * pFile){\n"
1085010850
"unsigned char c;\n"
1085110851
"do {\n"
1085210852
" c = getc (pFile);\n"
10853-
"} while (EOF != c)"
10853+
"} while (EOF != c);"
1085410854
"}");
1085510855
ASSERT_EQUALS("[test.cpp:5]: (warning) Storing getc() return value in char variable and then comparing with EOF.\n", errout_str());
1085610856

1085710857
check("void f (FILE * pFile){\n"
1085810858
"int i;\n"
1085910859
"do {\n"
1086010860
" i = getc (pFile);\n"
10861-
"} while (i != EOF)"
10861+
"} while (i != EOF);"
1086210862
"}");
1086310863
ASSERT_EQUALS("", errout_str());
1086410864

1086510865
check("void f (FILE * pFile){\n"
1086610866
"int i;\n"
1086710867
"do {\n"
1086810868
" i = getc (pFile);\n"
10869-
"} while (EOF != i)"
10869+
"} while (EOF != i);"
1087010870
"}");
1087110871
ASSERT_EQUALS("", errout_str());
1087210872

@@ -10876,39 +10876,39 @@ class TestOther : public TestFixture {
1087610876
"unsigned char c;\n"
1087710877
"do {\n"
1087810878
" c = fgetc (pFile);\n"
10879-
"} while (c != EOF)"
10879+
"} while (c != EOF);"
1088010880
"}");
1088110881
ASSERT_EQUALS("[test.cpp:5]: (warning) Storing fgetc() return value in char variable and then comparing with EOF.\n", errout_str());
1088210882

1088310883
check("void f (FILE * pFile){\n"
1088410884
"char c;\n"
1088510885
"do {\n"
1088610886
" c = fgetc (pFile);\n"
10887-
"} while (EOF != c)"
10887+
"} while (EOF != c);"
1088810888
"}");
1088910889
ASSERT_EQUALS("[test.cpp:5]: (warning) Storing fgetc() return value in char variable and then comparing with EOF.\n", errout_str());
1089010890

1089110891
check("void f (FILE * pFile){\n"
1089210892
"signed char c;\n"
1089310893
"do {\n"
1089410894
" c = fgetc (pFile);\n"
10895-
"} while (EOF != c)"
10895+
"} while (EOF != c);"
1089610896
"}");
1089710897
ASSERT_EQUALS("", errout_str());
1089810898

1089910899
check("void f (FILE * pFile){\n"
1090010900
"int i;\n"
1090110901
"do {\n"
1090210902
" i = fgetc (pFile);\n"
10903-
"} while (i != EOF)"
10903+
"} while (i != EOF);"
1090410904
"}");
1090510905
ASSERT_EQUALS("", errout_str());
1090610906

1090710907
check("void f (FILE * pFile){\n"
1090810908
"int i;\n"
1090910909
"do {\n"
1091010910
" i = fgetc (pFile);\n"
10911-
"} while (EOF != i)"
10911+
"} while (EOF != i);"
1091210912
"}");
1091310913
ASSERT_EQUALS("", errout_str());
1091410914

Diff for: test/testvalueflow.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4241,7 +4241,7 @@ class TestValueFlow : public TestFixture {
42414241
" do {\n"
42424242
" if (pvd.descr_type == 0xff) {}\n"
42434243
" dostuff(&pvd);\n"
4244-
" } while (condition)\n"
4244+
" } while (condition);\n"
42454245
"}";
42464246
values = removeImpossible(tokenValues(code, "=="));
42474247
ASSERT_EQUALS(1, values.size());

0 commit comments

Comments
 (0)