From 5f712cc213d547e84374fa54681bb84922de7394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 17 Dec 2011 21:35:12 +0100 Subject: [PATCH] Array index out of bounds: Fixed false positive when taking address beyond array using calculated array index --- lib/checkbufferoverrun.cpp | 15 +++++++++++++-- test/testbufferoverrun.cpp | 10 ++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 280d8b570..8dde61b1a 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -450,7 +450,7 @@ void CheckBufferOverrun::parse_for_body(const Token *tok, const ArrayInfo &array 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? // In this scope it is determined if such calculated // 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()); } + else { + continue; + } + //printf("min_index = %d, max_index = %d, size = %d\n", min_index, max_index, size); if (min_index < 0 || max_index < 0) { std::vector indexes; @@ -499,7 +503,14 @@ void CheckBufferOverrun::parse_for_body(const Token *tok, const ArrayInfo &array } // 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 indexes; indexes.push_back(std::max(min_index, max_index)); arrayIndexOutOfBoundsError(tok2, arrayInfo, indexes); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index a824ac877..f29e69752 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -109,6 +109,7 @@ private: TEST_CASE(array_index_37); TEST_CASE(array_index_38); // ticket #3273 TEST_CASE(array_index_39); + TEST_CASE(array_index_40); // loop variable calculation, taking address TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); 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()); } + 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() { check("void f()\n" "{\n"