TestBufferOverRun: Handle string literals (#2287)
This commit is contained in:
parent
f83eb127ae
commit
73a569be97
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue