TestBufferOverRun: Handle string literals (#2287)

This commit is contained in:
Rikard Falkeborn 2019-10-21 07:11:22 +02:00 committed by Daniel Marjamäki
parent f83eb127ae
commit 73a569be97
2 changed files with 32 additions and 8 deletions

View File

@ -188,10 +188,7 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings *set
while (Token::Match(array, ".|::")) while (Token::Match(array, ".|::"))
array = array->astOperand2(); array = array->astOperand2();
if (!array->variable()) if (array->variable() && array->variable()->isArray() && !array->variable()->dimensions().empty()) {
return false;
if (array->variable()->isArray() && !array->variable()->dimensions().empty()) {
*dimensions = array->variable()->dimensions(); *dimensions = array->variable()->dimensions();
if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) { if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) {
visitAstNodes(arrayToken, visitAstNodes(arrayToken,
@ -244,7 +241,7 @@ static std::vector<const ValueFlow::Value *> getOverrunIndexValues(const Token *
continue; continue;
allKnown = false; allKnown = false;
} }
if (array->variable()->isArray() && dimensions[i].num == 0) if (array->variable() && array->variable()->isArray() && dimensions[i].num == 0)
continue; continue;
if (value->intvalue == dimensions[i].num) if (value->intvalue == dimensions[i].num)
equal = true; equal = true;
@ -275,7 +272,7 @@ void CheckBufferOverrun::arrayIndex()
const Token *array = tok->astOperand1(); const Token *array = tok->astOperand1();
while (Token::Match(array, ".|::")) while (Token::Match(array, ".|::"))
array = array->astOperand2(); array = array->astOperand2();
if (!array|| !array->variable() || array->variable()->nameToken() == array) if (!array || ((!array->variable() || array->variable()->nameToken() == array) && array->tokType() != Token::eString))
continue; continue;
if (!array->scope()->isExecutable()) { if (!array->scope()->isExecutable()) {
// LHS in non-executable scope => This is just a definition // LHS in non-executable scope => This is just a definition

View File

@ -86,7 +86,7 @@ private:
TEST_CASE(array_index_1); TEST_CASE(array_index_1);
TEST_CASE(array_index_2); TEST_CASE(array_index_2);
TEST_CASE(array_index_3); TEST_CASE(array_index_3);
// TODO string TEST_CASE(array_index_4); TEST_CASE(array_index_4);
TEST_CASE(array_index_6); TEST_CASE(array_index_6);
TEST_CASE(array_index_7); TEST_CASE(array_index_7);
TEST_CASE(array_index_11); TEST_CASE(array_index_11);
@ -189,6 +189,7 @@ private:
TEST_CASE(pointer_out_of_bounds_1); TEST_CASE(pointer_out_of_bounds_1);
// TODO TEST_CASE(pointer_out_of_bounds_2); // TODO TEST_CASE(pointer_out_of_bounds_2);
TEST_CASE(pointer_out_of_bounds_3); TEST_CASE(pointer_out_of_bounds_3);
TEST_CASE(pointer_out_of_bounds_4);
// TODO TEST_CASE(pointer_out_of_bounds_sub); // TODO TEST_CASE(pointer_out_of_bounds_sub);
// TODO TEST_CASE(strncat1); // TODO TEST_CASE(strncat1);
@ -385,13 +386,16 @@ private:
void array_index_4() { void array_index_4() {
check("char c = \"abc\"[4];"); check("char c = \"abc\"[4];");
ASSERT_EQUALS("[test.cpp:1]: (error) Array index out of bounds: \"abc\"\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Array '\"abc\"[4]' accessed at index 4, which is out of bounds.\n", errout.str());
check("p = &\"abc\"[4];"); check("p = &\"abc\"[4];");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("char c = \"\\0abc\"[2];"); check("char c = \"\\0abc\"[2];");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("char c = L\"abc\"[4];");
ASSERT_EQUALS("[test.cpp:1]: (error) Array 'L\"abc\"[4]' accessed at index 4, which is out of bounds.\n", errout.str());
} }
void array_index_3() { void array_index_3() {
@ -2814,6 +2818,29 @@ private:
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 's->a+100' is out of bounds.\n", errout.str()); 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_4() {
check("const char* f() {\n"
" g(\"Hello\" + 6);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("const char* f() {\n"
" g(\"Hello\" + 7);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Undefined behaviour, pointer arithmetic '\"Hello\"+7' is out of bounds.\n", errout.str());
check("const char16_t* f() {\n"
" g(u\"Hello\" + 6);\n"
"}");
ASSERT_EQUALS("", errout.str());
check("const char16_t* f() {\n"
" g(u\"Hello\" + 7);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Undefined behaviour, pointer arithmetic 'u\"Hello\"+7' is out of bounds.\n", errout.str());
}
void pointer_out_of_bounds_sub() { void pointer_out_of_bounds_sub() {
check("void f() {\n" check("void f() {\n"
" char x[10];\n" " char x[10];\n"