diff --git a/cfg/posix.cfg b/cfg/posix.cfg
index d5f369496..9fa1597f4 100644
--- a/cfg/posix.cfg
+++ b/cfg/posix.cfg
@@ -5279,7 +5279,6 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s
-
diff --git a/cfg/std.cfg b/cfg/std.cfg
index 566f7104c..c7633313a 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -5209,7 +5209,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
-
diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp
index 75538c309..1d6ce74b9 100644
--- a/lib/checkfunctions.cpp
+++ b/lib/checkfunctions.cpp
@@ -141,7 +141,7 @@ void CheckFunctions::invalidFunctionUsage()
const Variable* const variable = argtok->variable();
// Is non-null terminated local variable of type char (e.g. char buf[] = {'x'};) ?
if (variable && variable->isLocal()
- && valueType && valueType->type == ValueType::Type::CHAR) {
+ && valueType && (valueType->type == ValueType::Type::CHAR || valueType->type == ValueType::Type::WCHAR_T)) {
const Token* varTok = variable->declEndToken();
auto count = -1; // Find out explicitly set count, e.g.: char buf[3] = {...}. Variable 'count' is set to 3 then.
if (varTok && Token::simpleMatch(varTok->previous(), "]"))
@@ -170,6 +170,13 @@ void CheckFunctions::invalidFunctionUsage()
&& (count == -1 || (count > 0 && count <= charsUntilFirstZero))) {
invalidFunctionArgStrError(argtok, functionToken->str(), argnr);
}
+ } else if (count > -1 && Token::Match(varTok, "= %str%")) {
+ const Token* strTok = varTok->getValueTokenMinStrSize(mSettings);
+ if (strTok) {
+ const int strSize = Token::getStrArraySize(strTok);
+ if (strSize > count)
+ invalidFunctionArgStrError(argtok, functionToken->str(), argnr);
+ }
}
}
}
diff --git a/test/cfg/posix.c b/test/cfg/posix.c
index d45cc26f2..aad6217ee 100644
--- a/test/cfg/posix.c
+++ b/test/cfg/posix.c
@@ -558,9 +558,7 @@ void bufferAccessOutOfBounds_bzero(void *s, size_t n)
size_t bufferAccessOutOfBounds_strnlen(const char *s, size_t maxlen)
{
const char buf[2]={'4','2'};
- // cppcheck-suppress invalidFunctionArgStr
size_t len = strnlen(buf,2);
- // cppcheck-suppress invalidFunctionArgStr
// cppcheck-suppress bufferAccessOutOfBounds
len+=strnlen(buf,3);
return len;
diff --git a/test/cfg/std.c b/test/cfg/std.c
index 873adef83..684c4dd7a 100644
--- a/test/cfg/std.c
+++ b/test/cfg/std.c
@@ -34,7 +34,7 @@ size_t invalidFunctionArgStr_wcslen(void)
const wchar_t terminated0[] = L"ABCDEF49620910";
const wchar_t terminated1[3] = { L'a', L'b', L'\0' };
const wchar_t notTerminated[3] = { L'a', L'b', L'c' };
- // TODO: cppcheck-suppress invalidFunctionArgStr
+ // cppcheck-suppress invalidFunctionArgStr
(void) wcslen(notTerminated);
(void) wcslen(terminated0);
return wcslen(terminated1);
@@ -3908,10 +3908,11 @@ void bufferAccessOutOfBounds_strxfrm(void)
{
const char src[3] = "abc";
char dest[1] = "a";
+ // cppcheck-suppress invalidFunctionArgStr
(void)strxfrm(dest,src,1);
- // cppcheck-suppress bufferAccessOutOfBounds
+ // cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr]
(void)strxfrm(dest,src,2);
- // cppcheck-suppress bufferAccessOutOfBounds
+ // cppcheck-suppress [bufferAccessOutOfBounds,invalidFunctionArgStr]
(void)strxfrm(dest,src,3);
}
diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp
index e95c0fc8c..33d05ff82 100644
--- a/test/testfunctions.cpp
+++ b/test/testfunctions.cpp
@@ -711,6 +711,18 @@ private:
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
+
+ check("int f() {\n"
+ " const char c[3] = \"abc\";\n"
+ " return strlen(c);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:3]: (error) Invalid strlen() argument nr 1. A nul-terminated string is required.\n", errout.str());
+
+ check("int f() {\n"
+ " const wchar_t c[3] = L\"abc\";\n"
+ " return wcslen(c);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:3]: (error) Invalid wcslen() argument nr 1. A nul-terminated string is required.\n", errout.str());
}
void mathfunctionCall_sqrt() {