diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 134d5fcf2..85fafd9fb 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1146,8 +1146,25 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo { arrayIndexOutOfBoundsError(tok, arrayInfo, indexes); } + // Is any array index out of bounds? + else if (totalIndex != totalElements) + { + // check each index for overflow + for (unsigned int i = 0; i < indexes.size(); ++i) + { + if (indexes[i] >= arrayInfo.num(i)) + { + // The access is still within the memory range for the array + // so it may be intentional. + if (_settings->inconclusive) + { + arrayIndexOutOfBoundsError(tok, arrayInfo, indexes); + break; // only warn about the first one + } + } + } + } } - } // Loop.. diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index e6b3dbb9a..a956e4c5e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -109,6 +109,7 @@ private: TEST_CASE(array_index_31); // ticket #2120 - out of bounds in subfunction when type is unknown TEST_CASE(array_index_32); TEST_CASE(array_index_33); // ticket #3044 + TEST_CASE(array_index_34); // ticket #3063 TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_for_in_for); // FP: #2634 @@ -1090,6 +1091,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void array_index_34() // ticket #3063 + { + check("void foo() {\n" + " int y[2][2][2];\n" + " y[0][2][0] = 0;\n" + " y[0][0][2] = 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (error) Array 'y[2][2][2]' index y[0][2][0] out of bounds\n" + "[test.cpp:4]: (error) Array 'y[2][2][2]' index y[0][0][2] out of bounds\n", errout.str()); + } + void array_index_multidim() { check("void f()\n" @@ -1153,7 +1165,7 @@ private: " char a[10][10][10];\n" " a[2*3][4*3][2] = 'a';\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10][10][10]' index a[6][12][2] out of bounds\n", "", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10][10][10]' index a[6][12][2] out of bounds\n", errout.str()); check("void f()\n" "{\n"