CheckBufferOverrun: Improved CTU analysis for array
This commit is contained in:
parent
40af889df0
commit
9653760547
14
lib/ctu.cpp
14
lib/ctu.cpp
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue