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"