diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 46d8e1c7c6c..6468d766f93 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -68,7 +68,9 @@ static const ValueFlow::Value *getBufferSizeValue(const Token *tok) auto it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isBufferSizeValue)); if (it != tokenValues.cend()) return &*it; - it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), std::mem_fn(&ValueFlow::Value::isContainerSizeValue)); + it = std::find_if(tokenValues.cbegin(), tokenValues.cend(), [](const ValueFlow::Value& v) { + return v.isContainerSizeValue() && !v.isImpossible(); + }); return it == tokenValues.cend() ? nullptr : &*it; } @@ -588,6 +590,8 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons ValueFlow::Value bufSizeVal; bufSizeVal.valueType = ValueFlow::Value::ValueType::BUFFER_SIZE; bufSizeVal.intvalue = value->intvalue * elementSize; + bufSizeVal.valueKind = value->valueKind; + bufSizeVal.errorPath = value->errorPath; return bufSizeVal; } } @@ -721,7 +725,10 @@ void CheckBufferOverrunImpl::bufferOverflow() void CheckBufferOverrunImpl::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, Certainty certainty) { - reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"), CWE_BUFFER_OVERRUN, certainty); + const auto errorPath = getErrorPath(tok, value, "Buffer overrun"); + const auto severity = !value || value->isKnown() ? Severity::error : Severity::warning; + const std::string msg = "Buffer is accessed out of bounds: " + (tok ? getRealBufferTok(tok)->expressionString() : "buf"); + reportError(errorPath, severity, "bufferAccessOutOfBounds", msg, CWE_BUFFER_OVERRUN, certainty); } //--------------------------------------------------------------------------- diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 37ab7083902..fa0315f804f 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3564,6 +3564,21 @@ class TestBufferOverrun : public TestFixture { " memset(&a[i], 0, sizeof(a));\n" "}\n"); ASSERT_EQUALS("[test.cpp:4:16]: (error) Buffer is accessed out of bounds: &a[i] [bufferAccessOutOfBounds]\n", errout_str()); + + check("void f(const std::vector& s) {\n" // #14948 + " if (s.size() < 4)\n" + " return;\n" + " uint32_t u = 0;\n" + " std::memcpy(&u, &s[0], sizeof(u));\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + + check("void f(const std::vector& s) {\n" + " if (s.size() == 2) {}\n" + " uint32_t u = 0;\n" + " std::memcpy(&u, &s[0], sizeof(u));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:21]: (warning) Buffer is accessed out of bounds: &s[0] [bufferAccessOutOfBounds]\n", errout_str()); } void buffer_overrun_errorpath() {