diff --git a/cfg/posix.cfg b/cfg/posix.cfg
index 2ab8b32dc..b9aa5b118 100644
--- a/cfg/posix.cfg
+++ b/cfg/posix.cfg
@@ -3630,7 +3630,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 249e57ba4..0aa0da5b4 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -4979,7 +4979,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 bf1bf406b..b65f3eb76 100644
--- a/lib/checkfunctions.cpp
+++ b/lib/checkfunctions.cpp
@@ -150,14 +150,18 @@ void CheckFunctions::invalidFunctionUsage()
}
if (Token::simpleMatch(varTok, "= {")) {
varTok = varTok->tokAt(1);
- auto actualCharCount = 0;
+ auto charsUntilFirstZero = 0;
while (varTok && !Token::simpleMatch(varTok->next(), "}")) {
- if (!Token::simpleMatch(varTok->next(), ","))
- ++actualCharCount;
+ if (!Token::simpleMatch(varTok->next(), ",")) {
+ ++charsUntilFirstZero;
+ }
varTok = varTok->next();
+ if (varTok && varTok->hasKnownIntValue() && varTok->getKnownIntValue() == 0) {
+ break; // stop counting for cases like char buf[3] = {'x', '\0', 'y'};
+ }
}
if (varTok && varTok->hasKnownIntValue() && varTok->getKnownIntValue() != 0
- && (count == -1 || (count > 0 && count <= actualCharCount))) {
+ && (count == -1 || (count > 0 && count <= charsUntilFirstZero))) {
invalidFunctionArgStrError(argtok, functionToken->str(), argnr);
}
}
diff --git a/test/cfg/posix.c b/test/cfg/posix.c
index ddb7788da..47c1baffc 100644
--- a/test/cfg/posix.c
+++ b/test/cfg/posix.c
@@ -35,6 +35,17 @@
#include
#include
+void invalidFunctionArgStr_mbsnrtowcs(void)
+{
+ wchar_t wenough[10];
+ mbstate_t s;
+ memset (&s, '\0', sizeof (s));
+ const char* cp = "ABC";
+ wcscpy (wenough, L"DEF");
+ // No warning is expected for - #11119
+ if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1 || wcscmp (wenough, L"AEF") != 0) {}
+}
+
int nullPointer_getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
{
// cppcheck-suppress nullPointer
diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp
index 88263c671..e473c8942 100644
--- a/test/cfg/std.cpp
+++ b/test/cfg/std.cpp
@@ -36,6 +36,17 @@
#include
#include
+char* invalidFunctionArgStr_strncpy(char * destination)
+{
+ // Copies the first num characters of source to destination.
+ // If the end of the source C string (which is signaled by a null-character)
+ // is found before num characters have been copied, destination
+ // is padded with zeros until a total of num characters have been written to it.
+ const char source = 'x';
+ const std::size_t num = 1U;
+ return strncpy(destination, &source, num);
+}
+
void invalidFunctionArgStr_fprintf(FILE *stream, const char *format)
{
const char formatBuf[] = {'%','d'};
diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp
index 2ba9a3119..ec24780f8 100644
--- a/test/testfunctions.cpp
+++ b/test/testfunctions.cpp
@@ -632,6 +632,12 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
+ check("FILE* f(void) {\n"
+ " const char fileName[3] = { \'x\', \'\\0\' ,\'y\' };\n"
+ " return fopen(fileName, \"r\"); \n"
+ "}");
+ ASSERT_EQUALS("", errout.str());
+
check("FILE* f(void) {\n"
" const char fileName[3] = { \'x\', \'y\' };\n" // implicit '\0' added at the end
" return fopen(fileName, \"r\"); \n"