From c05e2cc6c4a063a96cdd1a613ea067b7bffdb416 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 4 Jan 2022 10:37:16 +0100 Subject: [PATCH] Fix #10154 False positive: objectIndex (#3666) --- lib/checkbufferoverrun.cpp | 9 +++++++++ test/testbufferoverrun.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 7ca09cef8..a9b6179de 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1015,6 +1015,15 @@ void CheckBufferOverrun::objectIndex() if (var->valueType()->pointer > obj->valueType()->pointer) continue; } + if (obj->valueType() && var->valueType() && (obj->isCast() || (mTokenizer->isCPP() && isCPPCast(obj)) || obj->valueType()->pointer)) { // allow cast to a different type + const auto varSize = var->valueType()->typeSize(*mSettings); + if (varSize == 0) + continue; + if (obj->valueType()->type != var->valueType()->type) { + if (ValueFlow::isOutOfBounds(makeSizeValue(varSize, v.path), idx).empty()) + continue; + } + } if (v.path != 0) { std::vector idxValues; std::copy_if(idx->values().begin(), diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 3311b6904..64d3351da 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -4905,6 +4905,44 @@ private: " f(&u, N);\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("uint32_t f(uint32_t u) {\n" // #10154 + " return ((uint8_t*)&u)[3];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("uint32_t f(uint32_t u) {\n" + " return ((uint8_t*)&u)[4];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (error) The address of local variable 'u' is accessed at non-zero index.\n", errout.str()); + + check("uint32_t f(uint32_t u) {\n" + " return reinterpret_cast(&u)[3];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("uint32_t f(uint32_t u) {\n" + " return reinterpret_cast(&u)[4];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (error) The address of local variable 'u' is accessed at non-zero index.\n", errout.str()); + + check("uint32_t f(uint32_t u) {\n" + " uint8_t* p = (uint8_t*)&u;\n" + " return p[3];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("uint32_t f(uint32_t u) {\n" + " uint8_t* p = (uint8_t*)&u;\n" + " return p[4];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (error) The address of local variable 'u' is accessed at non-zero index.\n", errout.str()); + + check("uint32_t f(uint32_t* pu) {\n" + " uint8_t* p = (uint8_t*)pu;\n" + " return p[4];\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } };