Bug hunting; better handling of struct member assignment in for loop
This commit is contained in:
parent
a9f4a14c8d
commit
02bb14003b
|
@ -2453,6 +2453,16 @@ static std::string execute(const Token *start, const Token *end, Data &data)
|
||||||
lhs = lhs->astOperand1();
|
lhs = lhs->astOperand1();
|
||||||
if (!lhs)
|
if (!lhs)
|
||||||
throw ExprEngineException(tok2, "Unhandled assignment in loop");
|
throw ExprEngineException(tok2, "Unhandled assignment in loop");
|
||||||
|
if (Token::Match(lhs, ". %name% =|[") && Token::simpleMatch(lhs->astOperand1(), ".")) {
|
||||||
|
const Token *structToken = lhs;
|
||||||
|
while (Token::Match(structToken, ".|["))
|
||||||
|
structToken = structToken->astOperand1();
|
||||||
|
if (Token::Match(structToken, "%var%")) {
|
||||||
|
data.assignValue(structToken, structToken->varId(), std::make_shared<ExprEngine::BailoutValue>());
|
||||||
|
changedVariables.insert(structToken->varId());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Token::Match(lhs, ". %name% =|[") && lhs->astOperand1() && lhs->astOperand1()->valueType()) {
|
if (Token::Match(lhs, ". %name% =|[") && lhs->astOperand1() && lhs->astOperand1()->valueType()) {
|
||||||
const Token *structToken = lhs->astOperand1();
|
const Token *structToken = lhs->astOperand1();
|
||||||
if (!structToken->valueType() || !structToken->varId())
|
if (!structToken->valueType() || !structToken->varId())
|
||||||
|
|
|
@ -40,6 +40,7 @@ private:
|
||||||
TEST_CASE(arrayIndexOutOfBounds2);
|
TEST_CASE(arrayIndexOutOfBounds2);
|
||||||
TEST_CASE(arrayIndexOutOfBounds3);
|
TEST_CASE(arrayIndexOutOfBounds3);
|
||||||
TEST_CASE(arrayIndexOutOfBounds4);
|
TEST_CASE(arrayIndexOutOfBounds4);
|
||||||
|
TEST_CASE(arrayIndexOutOfBounds5);
|
||||||
TEST_CASE(bufferOverflowMemCmp1);
|
TEST_CASE(bufferOverflowMemCmp1);
|
||||||
TEST_CASE(bufferOverflowMemCmp2);
|
TEST_CASE(bufferOverflowMemCmp2);
|
||||||
TEST_CASE(bufferOverflowStrcpy1);
|
TEST_CASE(bufferOverflowStrcpy1);
|
||||||
|
@ -135,6 +136,23 @@ private:
|
||||||
errout.str());
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arrayIndexOutOfBounds5() {
|
||||||
|
check("struct {\n"
|
||||||
|
" struct { int z; } y;\n"
|
||||||
|
"} x;\n"
|
||||||
|
"\n"
|
||||||
|
"void foo(int i) {\n"
|
||||||
|
" for (int c = 0; c <= i; c++)\n"
|
||||||
|
" x.y.z = 13;\n"
|
||||||
|
" int buf[10];\n"
|
||||||
|
" if (buf[i] > 0) { }\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is less than 10\n"
|
||||||
|
"[test.cpp:9]: (error) Array index out of bounds, cannot determine that i is not negative\n"
|
||||||
|
"[test.cpp:9]: (error) Cannot determine that 'buf[i]' is initialized\n",
|
||||||
|
errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void bufferOverflowMemCmp1() {
|
void bufferOverflowMemCmp1() {
|
||||||
// CVE-2020-24265
|
// CVE-2020-24265
|
||||||
check("void foo(const char *pktdata, int datalen) {\n"
|
check("void foo(const char *pktdata, int datalen) {\n"
|
||||||
|
|
Loading…
Reference in New Issue