From 1a4bd0a7b34f546a89391ca64c9174f84df0de96 Mon Sep 17 00:00:00 2001 From: orbitcowboy Date: Fri, 3 Jun 2022 13:10:45 +0200 Subject: [PATCH] Fixed FP, found with daca@home: ftp://ftp.de.debian.org/debian/pool/main/k/knot/knot_3.1.8.orig.tar.xz; knot-3.1.8/tests/knot/test_confio.c:301:18: error: Invalid strcmp() argument nr 2. A nul-terminated string is required. [invalidFunctionArgStr] --- lib/checkfunctions.cpp | 18 +++++++++++------- test/testfunctions.cpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index b65f3eb76..ef80d237b 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -125,7 +125,7 @@ void CheckFunctions::invalidFunctionUsage() else if (!mSettings->library.isIntArgValid(functionToken, argnr, 1)) invalidFunctionArgError(argtok, functionToken->str(), argnr, nullptr, mSettings->library.validarg(functionToken, argnr)); } -// check + // check if (mSettings->library.isargstrz(functionToken, argnr)) { if (Token::Match(argtok, "& %var% !![") && argtok->next() && argtok->next()->valueType()) { const ValueType * valueType = argtok->next()->valueType(); @@ -151,13 +151,17 @@ void CheckFunctions::invalidFunctionUsage() if (Token::simpleMatch(varTok, "= {")) { varTok = varTok->tokAt(1); auto charsUntilFirstZero = 0; - while (varTok && !Token::simpleMatch(varTok->next(), "}")) { - if (!Token::simpleMatch(varTok->next(), ",")) { - ++charsUntilFirstZero; - } + bool search = true; + while (search && varTok && !Token::simpleMatch(varTok->next(), "}")) { varTok = varTok->next(); - if (varTok && varTok->hasKnownIntValue() && varTok->getKnownIntValue() == 0) { - break; // stop counting for cases like char buf[3] = {'x', '\0', 'y'}; + if (!Token::simpleMatch(varTok, ",")) { + if (Token::Match(varTok, "%op%")) { + varTok = varTok->next(); + continue; + } + ++charsUntilFirstZero; + if (varTok && varTok->hasKnownIntValue() && varTok->getKnownIntValue() == 0) + search=false; // stop counting for cases like char buf[3] = {'x', '\0', 'y'}; } } if (varTok && varTok->hasKnownIntValue() && varTok->getKnownIntValue() != 0 diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index ec24780f8..eb2285df7 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -650,6 +650,24 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + check("FILE* f(void) {\n" + " const char fileName[] = { \'0\' + 42 };\n" // no size is explicitly defined, no implicit '\0' is added + " return fopen(fileName, \"r\"); \n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required.\n", errout.str()); + + check("FILE* f(void) {\n" + " const char fileName[] = { \'0\' + 42, \'x\' };\n" // no size is explicitly defined, no implicit '\0' is added + " return fopen(fileName, \"r\"); \n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Invalid fopen() argument nr 1. A nul-terminated string is required.\n", errout.str()); + + check("FILE* f(void) {\n" + " const char fileName[2] = { \'0\' + 42 };\n" // implicitly '\0' added at the end because size is set to 2 + " return fopen(fileName, \"r\"); \n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("FILE* f(void) {\n" " const char fileName[] = { };\n" " return fopen(fileName, \"r\"); \n"