Array index out of bounds: Fixed false positive when taking address beyond array using calculated array index
This commit is contained in:
parent
3e9d8e6ae1
commit
5f712cc213
|
@ -450,7 +450,7 @@ void CheckBufferOverrun::parse_for_body(const Token *tok, const ArrayInfo &array
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (arrayInfo.varid() && counter_varid > 0 && !min_counter_value.empty() && !max_counter_value.empty()) {
|
else if (arrayInfo.varid() && tok2->varId() && counter_varid > 0 && !min_counter_value.empty() && !max_counter_value.empty()) {
|
||||||
// Is the loop variable used to calculate the array index?
|
// Is the loop variable used to calculate the array index?
|
||||||
// In this scope it is determined if such calculated
|
// In this scope it is determined if such calculated
|
||||||
// array indexes are out of bounds.
|
// array indexes are out of bounds.
|
||||||
|
@ -491,6 +491,10 @@ void CheckBufferOverrun::parse_for_body(const Token *tok, const ArrayInfo &array
|
||||||
max_index = std::atoi(MathLib::calculate(first, max_counter_value, action, _tokenizer).c_str());
|
max_index = std::atoi(MathLib::calculate(first, max_counter_value, action, _tokenizer).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//printf("min_index = %d, max_index = %d, size = %d\n", min_index, max_index, size);
|
//printf("min_index = %d, max_index = %d, size = %d\n", min_index, max_index, size);
|
||||||
if (min_index < 0 || max_index < 0) {
|
if (min_index < 0 || max_index < 0) {
|
||||||
std::vector<MathLib::bigint> indexes;
|
std::vector<MathLib::bigint> indexes;
|
||||||
|
@ -499,7 +503,14 @@ void CheckBufferOverrun::parse_for_body(const Token *tok, const ArrayInfo &array
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip 0 length arrays
|
// skip 0 length arrays
|
||||||
if (arrayInfo.num(0) && (min_index >= arrayInfo.num(0) || max_index >= arrayInfo.num(0))) {
|
if (arrayInfo.num(0) == 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
// taking address.
|
||||||
|
else if (tok2->previous()->str() == "&" && max_index == arrayInfo.num(0))
|
||||||
|
;
|
||||||
|
|
||||||
|
else if (arrayInfo.num(0) && (min_index >= arrayInfo.num(0) || max_index >= arrayInfo.num(0))) {
|
||||||
std::vector<MathLib::bigint> indexes;
|
std::vector<MathLib::bigint> indexes;
|
||||||
indexes.push_back(std::max(min_index, max_index));
|
indexes.push_back(std::max(min_index, max_index));
|
||||||
arrayIndexOutOfBoundsError(tok2, arrayInfo, indexes);
|
arrayIndexOutOfBoundsError(tok2, arrayInfo, indexes);
|
||||||
|
|
|
@ -109,6 +109,7 @@ private:
|
||||||
TEST_CASE(array_index_37);
|
TEST_CASE(array_index_37);
|
||||||
TEST_CASE(array_index_38); // ticket #3273
|
TEST_CASE(array_index_38); // ticket #3273
|
||||||
TEST_CASE(array_index_39);
|
TEST_CASE(array_index_39);
|
||||||
|
TEST_CASE(array_index_40); // loop variable calculation, taking address
|
||||||
TEST_CASE(array_index_multidim);
|
TEST_CASE(array_index_multidim);
|
||||||
TEST_CASE(array_index_switch_in_for);
|
TEST_CASE(array_index_switch_in_for);
|
||||||
TEST_CASE(array_index_for_in_for); // FP: #2634
|
TEST_CASE(array_index_for_in_for); // FP: #2634
|
||||||
|
@ -1309,6 +1310,15 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10]' index 10 out of bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10]' index 10 out of bounds\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void array_index_40() {
|
||||||
|
check("void f() {\n"
|
||||||
|
" char a[10];\n"
|
||||||
|
" for (int i = 0; i < 10; ++i)\n"
|
||||||
|
" f2(&a[i + 1]);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void array_index_multidim() {
|
void array_index_multidim() {
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue