Fixed #6356 (Improve checking: pointer arithmetic "ab.a + 100" overrun)
This commit is contained in:
parent
c110770481
commit
bc40f5041d
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue