From 9a9f14bd8a134e5122856636d87d5fdc3ff5980a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 May 2021 12:13:39 +0200 Subject: [PATCH] Buffer overflow; Fixed FPs when array size is 1 --- lib/checkbufferoverrun.cpp | 15 +++++++++++++++ test/testbufferoverrun.cpp | 11 +++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 597d63d8b..a29b2dfb1 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -609,6 +609,21 @@ void CheckBufferOverrun::bufferOverflow() const ValueFlow::Value bufferSize = getBufferSize(argtok); if (bufferSize.intvalue <= 0) continue; + // buffer size == 1 => do not warn for dynamic memory + if (bufferSize.intvalue == 1) { + const Token *tok2 = argtok; + while (Token::simpleMatch(tok2->astParent(), ".")) + tok2 = tok2->astParent(); + while (Token::Match(tok2, "[|.")) + tok2 = tok2->astOperand1(); + const Variable *var = tok2 ? tok2->variable() : nullptr; + if (var) { + if (var->isPointer()) + continue; + if (var->isArgument() && (var->isPointer() || var->isReference())) + continue; + } + } const bool error = std::none_of(minsizes->begin(), minsizes->end(), [=](const Library::ArgumentChecks::MinSize &minsize) { return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings); }); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index b84c6ec7b..39a5124a6 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -3672,13 +3672,20 @@ private: check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo *x = malloc(sizeof(Foo));\n" - " mysprintf(x.a, \"aa\");\n" + " mysprintf(x->a, \"aa\");\n" "}", settings); - ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", "", errout.str()); check("struct Foo { char a[1]; };\n" "void f() {\n" " struct Foo *x = malloc(sizeof(Foo) + 10);\n" + " mysprintf(x->a, \"aa\");\n" + "}", settings); + ASSERT_EQUALS("", errout.str()); + + check("struct Foo { char a[1]; };\n" + "void f() {\n" + " struct Foo x;\n" " mysprintf(x.a, \"aa\");\n" "}", settings); ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", errout.str());