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, ".|::"))
array = array->astOperand2();
if (!array->variable())
return false;
if (array->variable()->isArray() && !array->variable()->dimensions().empty()) {
if (array->variable() && array->variable()->isArray() && !array->variable()->dimensions().empty()) {
*dimensions = array->variable()->dimensions();
if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) {
visitAstNodes(arrayToken,
@ -244,7 +241,7 @@ static std::vector<const ValueFlow::Value *> getOverrunIndexValues(const Token *
continue;
allKnown = false;
}
if (array->variable()->isArray() && dimensions[i].num == 0)
if (array->variable() && array->variable()->isArray() && dimensions[i].num == 0)
continue;
if (value->intvalue == dimensions[i].num)
equal = true;
@ -275,7 +272,7 @@ void CheckBufferOverrun::arrayIndex()
const Token *array = tok->astOperand1();
while (Token::Match(array, ".|::"))
array = array->astOperand2();
if (!array|| !array->variable() || array->variable()->nameToken() == array)
if (!array || ((!array->variable() || array->variable()->nameToken() == array) && array->tokType() != Token::eString))
continue;
if (!array->scope()->isExecutable()) {
// 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_2);
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_7);
TEST_CASE(array_index_11);
@ -189,6 +189,7 @@ private:
TEST_CASE(pointer_out_of_bounds_1);
// TODO TEST_CASE(pointer_out_of_bounds_2);
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(strncat1);
@ -385,13 +386,16 @@ private:
void array_index_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];");
ASSERT_EQUALS("", errout.str());
check("char c = \"\\0abc\"[2];");
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() {
@ -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());
}
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() {
check("void f() {\n"
" char x[10];\n"