Fixed #3283 (False negative: array index out of bounds not found for constant string and known array index value)
This commit is contained in:
parent
0bf17213ec
commit
344d7e2f34
|
@ -1246,6 +1246,17 @@ void CheckBufferOverrun::checkReadlinkBufferUsage(const Token* tok, const Token
|
||||||
|
|
||||||
void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
||||||
{
|
{
|
||||||
|
// check string literals
|
||||||
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
|
if (Token::Match(tok, "%str% [ %num% ]")) {
|
||||||
|
std::string str = tok->strValue();
|
||||||
|
std::size_t index = atoi(tok->tokAt(2)->str().c_str());
|
||||||
|
if (index > str.length()) {
|
||||||
|
bufferOverrunError(tok, tok->str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check all known fixed size arrays first by just looking them up
|
// check all known fixed size arrays first by just looking them up
|
||||||
for (unsigned int i = 1; i <= _tokenizer->varIdCount(); i++) {
|
for (unsigned int i = 1; i <= _tokenizer->varIdCount(); i++) {
|
||||||
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(i);
|
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(i);
|
||||||
|
|
|
@ -128,6 +128,7 @@ private:
|
||||||
TEST_CASE(array_index_vla_for); // #3221: access VLA inside for
|
TEST_CASE(array_index_vla_for); // #3221: access VLA inside for
|
||||||
TEST_CASE(array_index_extern); // FP when using 'extern'. #1684
|
TEST_CASE(array_index_extern); // FP when using 'extern'. #1684
|
||||||
TEST_CASE(array_index_cast); // FP after cast. #2841
|
TEST_CASE(array_index_cast); // FP after cast. #2841
|
||||||
|
TEST_CASE(array_index_string_literal);
|
||||||
|
|
||||||
TEST_CASE(buffer_overrun_1);
|
TEST_CASE(buffer_overrun_1);
|
||||||
TEST_CASE(buffer_overrun_2);
|
TEST_CASE(buffer_overrun_2);
|
||||||
|
@ -1657,6 +1658,38 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Array 'x[2]' index 4 out of bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (error) Array 'x[2]' index 4 out of bounds\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void array_index_string_literal() {
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *str = \"abc\";\n"
|
||||||
|
" int i = 10;\n"
|
||||||
|
" bar(str[i]);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Buffer access out-of-bounds: \"abc\"\n", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *str = \"abc\";\n"
|
||||||
|
" bar(str[4]);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: \"abc\"\n", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *str = \"abc\";\n"
|
||||||
|
" bar(str[3]);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" const char *str = \"a\tc\";\n"
|
||||||
|
" bar(str[4]);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer access out-of-bounds: \"a\tc\"\n", errout.str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void buffer_overrun_1() {
|
void buffer_overrun_1() {
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue