Fixed #6356 (Improve checking: pointer arithmetic "ab.a + 100" overrun)

This commit is contained in:
Daniel Marjamäki 2018-01-27 15:39:27 +01:00
parent c110770481
commit bc40f5041d
2 changed files with 43 additions and 1 deletions

View File

@ -1481,6 +1481,39 @@ void CheckBufferOverrun::bufferOverrun()
{
// singlepass checking using ast, symboldatabase and valueflow
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (_settings->isEnabled(Settings::PORTABILITY) && tok->str() == "+" && tok->valueType() && tok->valueType()->pointer > 0) {
if (!tok->astOperand1() || !tok->astOperand1()->valueType())
continue;
if (!tok->astOperand2() || !tok->astOperand2()->valueType())
continue;
// pointer arithmetic..
const Token *pointerToken, *indexToken;
if (tok->astOperand1()->valueType()->pointer == 0) {
indexToken = tok->astOperand1();
pointerToken = tok->astOperand2();
} else if (tok->astOperand2()->valueType()->pointer == 0) {
indexToken = tok->astOperand2();
pointerToken = tok->astOperand1();
}
while (pointerToken && pointerToken->str() == ".")
pointerToken = pointerToken->astOperand2();
if (!pointerToken || !pointerToken->isName())
continue;
const Variable *var = pointerToken->variable();
if (!var || !var->isArray())
continue;
const ValueFlow::Value *value = indexToken->getValueGE(var->dimension(0)+1, _settings);
if (value) {
pointerOutOfBoundsError(tok, indexToken, value->intvalue);
}
}
// Array index
if (!Token::Match(tok, "%name% ["))
continue;
@ -1876,7 +1909,7 @@ MathLib::bigint CheckBufferOverrun::ArrayInfo::totalIndex(const std::vector<Valu
void CheckBufferOverrun::arrayIndexThenCheck()
{
if (!_settings->isEnabled(Settings::STYLE))
if (!_settings->isEnabled(Settings::PORTABILITY))
return;
const std::size_t functions = symbolDatabase->functionScopes.size();

View File

@ -185,6 +185,7 @@ private:
// char *p2 = a + 11 // UB
TEST_CASE(pointer_out_of_bounds_1);
TEST_CASE(pointer_out_of_bounds_2);
TEST_CASE(pointer_out_of_bounds_3);
TEST_CASE(pointer_out_of_bounds_sub);
TEST_CASE(strncat1);
@ -2795,6 +2796,14 @@ private:
ASSERT_EQUALS("", errout.str());
}
void pointer_out_of_bounds_3() {
check("struct S { int a[10]; };\n"
"void f(struct S *s) {\n"
" char *p = s->a + 100;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 's->a+100' is out of bounds.\n", errout.str());
}
void pointer_out_of_bounds_sub() {
check("void f() {\n"
" char x[10];\n"