#10244: Fixed false negative: bufferAccessOutOfBounds
This commit is contained in:
parent
44c8b315c6
commit
e869452240
|
@ -600,21 +600,21 @@ void CheckBufferOverrun::bufferOverflow()
|
|||
continue;
|
||||
// TODO: strcpy(buf+10, "hello");
|
||||
const ValueFlow::Value bufferSize = getBufferSize(argtok);
|
||||
if (bufferSize.intvalue <= 1)
|
||||
if (bufferSize.intvalue <= 0)
|
||||
continue;
|
||||
bool error = std::none_of(minsizes->begin(), minsizes->end(), [=](const Library::ArgumentChecks::MinSize &minsize) {
|
||||
const bool error = std::none_of(minsizes->begin(), minsizes->end(), [=](const Library::ArgumentChecks::MinSize &minsize) {
|
||||
return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings);
|
||||
});
|
||||
if (error)
|
||||
bufferOverflowError(args[argnr], &bufferSize);
|
||||
bufferOverflowError(args[argnr], &bufferSize, (bufferSize.intvalue == 1) ? Certainty::inconclusive : Certainty::normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckBufferOverrun::bufferOverflowError(const Token *tok, const ValueFlow::Value *value)
|
||||
void CheckBufferOverrun::bufferOverflowError(const Token *tok, const ValueFlow::Value *value, const Certainty::CertaintyLevel &certainty)
|
||||
{
|
||||
reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? tok->expressionString() : "buf"), CWE_BUFFER_OVERRUN, Certainty::normal);
|
||||
reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? tok->expressionString() : "buf"), CWE_BUFFER_OVERRUN, certainty);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "check.h"
|
||||
#include "config.h"
|
||||
#include "ctu.h"
|
||||
#include "errortypes.h"
|
||||
#include "mathlib.h"
|
||||
#include "symboldatabase.h"
|
||||
#include "valueflow.h"
|
||||
|
@ -83,7 +84,7 @@ public:
|
|||
c.pointerArithmeticError(nullptr, nullptr, nullptr);
|
||||
c.negativeIndexError(nullptr, std::vector<Dimension>(), std::vector<const ValueFlow::Value *>());
|
||||
c.arrayIndexThenCheckError(nullptr, "i");
|
||||
c.bufferOverflowError(nullptr, nullptr);
|
||||
c.bufferOverflowError(nullptr, nullptr, Certainty::normal);
|
||||
c.objectIndexError(nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,7 @@ private:
|
|||
void pointerArithmeticError(const Token *tok, const Token *indexToken, const ValueFlow::Value *indexValue);
|
||||
|
||||
void bufferOverflow();
|
||||
void bufferOverflowError(const Token *tok, const ValueFlow::Value *value);
|
||||
void bufferOverflowError(const Token *tok, const ValueFlow::Value *value, const Certainty::CertaintyLevel& certainty);
|
||||
|
||||
void arrayIndexThenCheck();
|
||||
void arrayIndexThenCheckError(const Token *tok, const std::string &indexName);
|
||||
|
|
|
@ -180,6 +180,7 @@ private:
|
|||
TEST_CASE(buffer_overrun_29); // #7083: false positive: typedef and initialization with strings
|
||||
TEST_CASE(buffer_overrun_30); // #6367
|
||||
TEST_CASE(buffer_overrun_31);
|
||||
TEST_CASE(buffer_overrun_32); //#10244
|
||||
TEST_CASE(buffer_overrun_errorpath);
|
||||
TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch
|
||||
// TODO TEST_CASE(buffer_overrun_function_array_argument);
|
||||
|
@ -2652,6 +2653,43 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void buffer_overrun_32() {
|
||||
// destination size is too small
|
||||
check("void f(void) {\n"
|
||||
" const char src[3] = \"abc\";\n"
|
||||
" char dest[1] = \"a\";\n"
|
||||
" (void)strxfrm(dest,src,1);\n"
|
||||
" (void)strxfrm(dest,src,2);\n"// <<
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error, inconclusive) Buffer is accessed out of bounds: dest\n", errout.str());
|
||||
// destination size is too small
|
||||
check("void f(void) {\n"
|
||||
" const char src[3] = \"abc\";\n"
|
||||
" char dest[2] = \"ab\";\n"
|
||||
" (void)strxfrm(dest,src,1);\n"
|
||||
" (void)strxfrm(dest,src,2);\n"
|
||||
" (void)strxfrm(dest,src,3);\n" // <<
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer is accessed out of bounds: dest\n", errout.str());
|
||||
// source size is too small
|
||||
check("void f(void) {\n"
|
||||
" const char src[2] = \"ab\";\n"
|
||||
" char dest[3] = \"abc\";\n"
|
||||
" (void)strxfrm(dest,src,1);\n"
|
||||
" (void)strxfrm(dest,src,2);\n"
|
||||
" (void)strxfrm(dest,src,3);\n" // <<
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Buffer is accessed out of bounds: src\n", errout.str());
|
||||
// source size is too small
|
||||
check("void f(void) {\n"
|
||||
" const char src[1] = \"a\";\n"
|
||||
" char dest[3] = \"abc\";\n"
|
||||
" (void)strxfrm(dest,src,1);\n"
|
||||
" (void)strxfrm(dest,src,2);\n" // <<
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error, inconclusive) Buffer is accessed out of bounds: src\n", errout.str());
|
||||
}
|
||||
|
||||
void buffer_overrun_errorpath() {
|
||||
setMultiline();
|
||||
settings0.templateLocation = "{file}:{line}:note:{info}";
|
||||
|
@ -3609,7 +3647,7 @@ private:
|
|||
" struct Foo x;\n"
|
||||
" mysprintf(x.a, \"aa\");\n"
|
||||
"}", settings);
|
||||
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds: x.a\n", "", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", errout.str());
|
||||
|
||||
// ticket #900
|
||||
check("void f() {\n"
|
||||
|
@ -3630,14 +3668,14 @@ private:
|
|||
" struct Foo *x = malloc(sizeof(Foo));\n"
|
||||
" mysprintf(x.a, \"aa\");\n"
|
||||
"}", settings);
|
||||
ASSERT_EQUALS("", errout.str()); // TODO: Inconclusive error?
|
||||
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());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error, inconclusive) Buffer is accessed out of bounds: x.a\n", errout.str());
|
||||
|
||||
check("struct Foo {\n" // #6668 - unknown size
|
||||
" char a[LEN];\n"
|
||||
|
|
Loading…
Reference in New Issue