Fixed #3283 (False negative: array index out of bounds not found for constant string and known array index value)

This commit is contained in:
Zachary Blair 2011-11-30 19:17:09 -08:00
parent 0bf17213ec
commit 344d7e2f34
2 changed files with 44 additions and 0 deletions

View File

@ -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);

View File

@ -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"