Fixed false positives from terminateStrncpy
This commit is contained in:
parent
1fe1fc7008
commit
c32d015337
|
@ -1015,9 +1015,14 @@ void CheckBufferOverrun::checkScope_inner(const Token *tok, const ArrayInfo &arr
|
||||||
const Token * const sizeArg = args.size() == 3 ? args[2] : nullptr;
|
const Token * const sizeArg = args.size() == 3 ? args[2] : nullptr;
|
||||||
const bool knownSize = sizeArg && sizeArg->hasKnownIntValue();
|
const bool knownSize = sizeArg && sizeArg->hasKnownIntValue();
|
||||||
const Token * const endToken = tok2->linkAt(1);
|
const Token * const endToken = tok2->linkAt(1);
|
||||||
|
const bool smallerSrcString = (args.size() == 3 &&
|
||||||
|
args[1]->hasKnownValue() &&
|
||||||
|
args[1]->values().front().isTokValue() &&
|
||||||
|
args[1]->values().front().tokvalue->tokType() == Token::eString &&
|
||||||
|
Token::getStrLength(args[1]->values().front().tokvalue) < sizeArg->getKnownIntValue());
|
||||||
|
|
||||||
// check for strncpy which is not terminated
|
// check for strncpy which is not terminated
|
||||||
if (knownSize && tok2->str() == "strncpy") {
|
if (knownSize && !smallerSrcString && tok2->str() == "strncpy") {
|
||||||
// strncpy takes entire variable length as input size
|
// strncpy takes entire variable length as input size
|
||||||
const MathLib::bigint num = sizeArg->getKnownIntValue();
|
const MathLib::bigint num = sizeArg->getKnownIntValue();
|
||||||
|
|
||||||
|
@ -1040,7 +1045,7 @@ void CheckBufferOverrun::checkScope_inner(const Token *tok, const ArrayInfo &arr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dangerous usage of strncat..
|
// Dangerous usage of strncat..
|
||||||
else if (knownSize && tok2->str() == "strncat") {
|
else if (knownSize && !smallerSrcString && tok2->str() == "strncat") {
|
||||||
const MathLib::bigint n = sizeArg->getKnownIntValue();
|
const MathLib::bigint n = sizeArg->getKnownIntValue();
|
||||||
if (n >= total_size)
|
if (n >= total_size)
|
||||||
strncatUsageError(tok2);
|
strncatUsageError(tok2);
|
||||||
|
|
|
@ -221,6 +221,7 @@ private:
|
||||||
TEST_CASE(terminateStrncpy1);
|
TEST_CASE(terminateStrncpy1);
|
||||||
TEST_CASE(terminateStrncpy2);
|
TEST_CASE(terminateStrncpy2);
|
||||||
TEST_CASE(terminateStrncpy3);
|
TEST_CASE(terminateStrncpy3);
|
||||||
|
TEST_CASE(terminateStrncpy4);
|
||||||
TEST_CASE(recursive_long_time);
|
TEST_CASE(recursive_long_time);
|
||||||
|
|
||||||
TEST_CASE(crash1); // Ticket #1587 - crash
|
TEST_CASE(crash1); // Ticket #1587 - crash
|
||||||
|
@ -3605,6 +3606,20 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'str' may not be null-terminated after the call to strncpy().\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning, inconclusive) The buffer 'str' may not be null-terminated after the call to strncpy().\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void terminateStrncpy4() {
|
||||||
|
check("void bar() {\n"
|
||||||
|
" char buf[4];\n"
|
||||||
|
" strncpy(buf, \"ab\", 4);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void bar() {\n"
|
||||||
|
" char buf[4];\n"
|
||||||
|
" strncpy(buf, \"abcde\", 4);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) The buffer 'buf' is not null-terminated after the call to strncpy().\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void recursive_long_time() {
|
void recursive_long_time() {
|
||||||
// Just test that recursive check doesn't take long time
|
// Just test that recursive check doesn't take long time
|
||||||
check("char *f2 ( char *b )\n"
|
check("char *f2 ( char *b )\n"
|
||||||
|
|
Loading…
Reference in New Issue