Fixed #6357 (Improve check: pointer arithmetic 'p+x' overrun, conditional x)

This commit is contained in:
Daniel Marjamäki 2014-12-26 09:12:00 +01:00
parent 7ab12cea63
commit 6194a4eefd
2 changed files with 30 additions and 3 deletions

View File

@ -875,9 +875,13 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
index = tok->astParent()->astOperand2(); index = tok->astParent()->astOperand2();
else else
index = tok->astParent()->astOperand1(); index = tok->astParent()->astOperand1();
const ValueFlow::Value *value = index ? index->getMaxValue(false) : nullptr; if (index) {
if (value && (value->intvalue < 0 || value->intvalue > arrayInfo.num(0))) const ValueFlow::Value *value = index->getValueGE(arrayInfo.num(0) + 1U, _settings);
pointerOutOfBoundsError(tok->astParent(), index, value->intvalue); if (!value)
value = index->getValueLE(-1, _settings);
if (value)
pointerOutOfBoundsError(tok->astParent(), index, value->intvalue);
}
} }
else if (isPortabilityEnabled && tok->astParent() && tok->astParent()->str() == "-") { else if (isPortabilityEnabled && tok->astParent() && tok->astParent()->str() == "-") {
@ -885,6 +889,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
if (var && var->isArray()) { if (var && var->isArray()) {
const Token *index = tok->astParent()->astOperand2(); const Token *index = tok->astParent()->astOperand2();
const ValueFlow::Value *value = index ? index->getValueGE(1,_settings) : nullptr; const ValueFlow::Value *value = index ? index->getValueGE(1,_settings) : nullptr;
if (!value)
value = index->getValueLE(-1 - arrayInfo.num(0), _settings);
if (value) if (value)
pointerOutOfBoundsError(tok->astParent(), index, value->intvalue); pointerOutOfBoundsError(tok->astParent(), index, value->intvalue);
} }

View File

@ -2970,6 +2970,13 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds.\n", errout.str());
check("void f(int i) {\n"
" char x[10];\n"
" if (i == 123) {}\n"
" dostuff(x+i);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x+i' is out of bounds.\n", errout.str());
check("void f() {\n" // #6350 - fp when there is cast of buffer check("void f() {\n" // #6350 - fp when there is cast of buffer
" wchar_t buf[64];\n" " wchar_t buf[64];\n"
" p = (unsigned char *) buf + sizeof (buf);\n" " p = (unsigned char *) buf + sizeof (buf);\n"
@ -3018,6 +3025,20 @@ private:
" return x-1;\n" " return x-1;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'x-1' is out of bounds.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'x-1' is out of bounds.\n", errout.str());
check("void f(int i) {\n"
" char x[10];\n"
" if (i == 123) {}\n"
" dostuff(x-i);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x-i' is out of bounds.\n", errout.str());
check("void f(int i) {\n"
" char x[10];\n"
" if (i == -20) {}\n"
" dostuff(x-i);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is -20 the pointer arithmetic 'x-i' is out of bounds.\n", errout.str());
} }
void sprintf1() { void sprintf1() {