CheckBufferOverrun: Improved CTU analysis for array

This commit is contained in:
Daniel Marjamäki 2019-03-23 11:20:35 +01:00
parent 40af889df0
commit 9653760547
3 changed files with 32 additions and 4 deletions

View File

@ -331,6 +331,20 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer)
} }
fileInfo->functionCalls.push_back(functionCall); fileInfo->functionCalls.push_back(functionCall);
} }
// array
if (argtok->variable() && argtok->variable()->isArray() && argtok->variable()->dimensions().size()==1 && argtok->variable()->dimension(0)>1) {
FileInfo::FunctionCall functionCall;
functionCall.callValueType = ValueFlow::Value::ValueType::BUFFER_SIZE;
functionCall.callId = getFunctionId(tokenizer, tok->astOperand1()->function());
functionCall.callFunctionName = tok->astOperand1()->expressionString();
functionCall.location.fileName = tokenizer->list.file(tok);
functionCall.location.linenr = tok->linenr();
functionCall.callArgNr = argnr + 1;
functionCall.callArgumentExpression = argtok->expressionString();
functionCall.callArgValue = argtok->variable()->dimension(0) * argtok->valueType()->typeSize(*tokenizer->getSettings());
functionCall.warning = false;
fileInfo->functionCalls.push_back(functionCall);
}
// pointer to uninitialized data.. // pointer to uninitialized data..
if (!argtok->isUnaryOp("&")) if (!argtok->isUnaryOp("&"))
continue; continue;

View File

@ -857,6 +857,10 @@ public:
#endif #endif
} }
const Settings *getSettings() const {
return mSettings;
}
private: private:
/** Disable copy constructor */ /** Disable copy constructor */
Tokenizer(const Tokenizer &) = delete; Tokenizer(const Tokenizer &) = delete;

View File

@ -247,6 +247,7 @@ private:
// TODO TEST_CASE(pointerAddition1); // TODO TEST_CASE(pointerAddition1);
TEST_CASE(ctu_1); TEST_CASE(ctu_1);
TEST_CASE(ctu_2);
} }
@ -4141,28 +4142,37 @@ private:
} }
void ctu_1() { void ctu_1() {
ctu("void dostuff(const char *p) {\n" ctu("void dostuff(char *p) {\n"
" p[-3] = 0;\n" " p[-3] = 0;\n"
"}\n" "}\n"
"\n" "\n"
"int main() {\n" "int main() {\n"
" char *s = malloc(4);\n" " char *s = malloc(4);\n"
" dostuff(s);\n" " dostuff(s);\n"
" return 0;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:7] -> [test.cpp:2]: (error) Buffer access out of bounds; buffer 'p' is accessed at offset -3.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:7] -> [test.cpp:2]: (error) Buffer access out of bounds; buffer 'p' is accessed at offset -3.\n", errout.str());
ctu("void dostuff(const char *p) {\n" ctu("void dostuff(char *p) {\n"
" p[4] = 0;\n" " p[4] = 0;\n"
"}\n" "}\n"
"\n" "\n"
"int main() {\n" "int main() {\n"
" char *s = malloc(4);\n" " char *s = malloc(4);\n"
" dostuff(s);\n" " dostuff(s);\n"
" return 0;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:7] -> [test.cpp:2]: (error) Buffer access out of bounds; 'p' buffer size is 4 and it is accessed at offset 4.\n", errout.str()); ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:7] -> [test.cpp:2]: (error) Buffer access out of bounds; 'p' buffer size is 4 and it is accessed at offset 4.\n", errout.str());
} }
void ctu_2() {
ctu("void dostuff(char *p) {\n"
" p[10] = 0;\n"
"}\n"
"int main() {\n"
" char str[4];\n"
" dostuff(str);\n"
"}");
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Buffer access out of bounds; 'p' buffer size is 4 and it is accessed at offset 10.\n", errout.str());
}
}; };
REGISTER_TEST(TestBufferOverrun) REGISTER_TEST(TestBufferOverrun)