diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 9569ecc9e..e4b2f6207 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -2453,6 +2453,16 @@ static std::string execute(const Token *start, const Token *end, Data &data) lhs = lhs->astOperand1(); if (!lhs) 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()); + changedVariables.insert(structToken->varId()); + continue; + } + } if (Token::Match(lhs, ". %name% =|[") && lhs->astOperand1() && lhs->astOperand1()->valueType()) { const Token *structToken = lhs->astOperand1(); if (!structToken->valueType() || !structToken->varId()) diff --git a/test/testbughuntingchecks.cpp b/test/testbughuntingchecks.cpp index a5ba043ea..a874baa75 100644 --- a/test/testbughuntingchecks.cpp +++ b/test/testbughuntingchecks.cpp @@ -40,6 +40,7 @@ private: TEST_CASE(arrayIndexOutOfBounds2); TEST_CASE(arrayIndexOutOfBounds3); TEST_CASE(arrayIndexOutOfBounds4); + TEST_CASE(arrayIndexOutOfBounds5); TEST_CASE(bufferOverflowMemCmp1); TEST_CASE(bufferOverflowMemCmp2); TEST_CASE(bufferOverflowStrcpy1); @@ -135,6 +136,23 @@ private: 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() { // CVE-2020-24265 check("void foo(const char *pktdata, int datalen) {\n"