Skip to content

Commit 3b1485f

Browse files
authored
Add check for npos, when checkInternal receives file with missing dot (#7911)
1 parent cdc3f03 commit 3b1485f

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

lib/cppcheck.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,21 @@ unsigned int CppCheck::checkFile(const FileWithDetails& file, const std::string
884884
return checkInternal(file, cfgname, fileIndex, f);
885885
}
886886

887+
void CppCheck::checkPlistOutput(const FileWithDetails& file, const std::vector<std::string>& files)
888+
{
889+
if (!mSettings.plistOutput.empty()) {
890+
const bool slashFound = file.spath().find('/') != std::string::npos;
891+
std::string filename = slashFound ? file.spath().substr(file.spath().rfind('/') + 1) : file.spath();
892+
// removes suffix from filename when it exists
893+
const std::string noSuffixFilename = filename.substr(0, filename.find('.'));
894+
895+
// the hash is added to handle when files in different folders have the same name
896+
const std::size_t fileNameHash = std::hash<std::string> {}(file.spath());
897+
filename = mSettings.plistOutput + noSuffixFilename + "_" + std::to_string(fileNameHash) + ".plist";
898+
mLogger->openPlist(filename, files);
899+
}
900+
}
901+
887902
unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const CreateTokenListFn& createTokenList)
888903
{
889904
// TODO: move to constructor when CppCheck no longer owns the settings
@@ -989,16 +1004,7 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
9891004
if (!preprocessor.loadFiles(files))
9901005
return mLogger->exitcode();
9911006

992-
if (!mSettings.plistOutput.empty()) {
993-
std::string filename2;
994-
if (file.spath().find('/') != std::string::npos)
995-
filename2 = file.spath().substr(file.spath().rfind('/') + 1);
996-
else
997-
filename2 = file.spath();
998-
const std::size_t fileNameHash = std::hash<std::string> {}(file.spath());
999-
filename2 = mSettings.plistOutput + filename2.substr(0, filename2.find('.')) + "_" + std::to_string(fileNameHash) + ".plist";
1000-
mLogger->openPlist(filename2, files);
1001-
}
1007+
checkPlistOutput(file, files);
10021008

10031009
std::string dumpProlog;
10041010
if (mSettings.dump || !mSettings.addons.empty()) {

lib/cppcheck.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ class CPPCHECKLIB CppCheck {
184184
*/
185185
unsigned int checkFile(const FileWithDetails& file, const std::string &cfgname, int fileIndex);
186186

187+
void checkPlistOutput(const FileWithDetails& file, const std::vector<std::string>& files);
188+
187189
/**
188190
* @brief Check a file using buffer
189191
* @param file the file

test/testcppcheck.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class TestCppcheck : public TestFixture {
7979
TEST_CASE(isPremiumCodingStandardId);
8080
TEST_CASE(getDumpFileContentsRawTokens);
8181
TEST_CASE(getDumpFileContentsLibrary);
82+
TEST_CASE(checkPlistOutput);
8283
TEST_CASE(premiumResultsCache);
8384
TEST_CASE(toomanyconfigs);
8485
TEST_CASE(purgedConfiguration);
@@ -522,6 +523,43 @@ class TestCppcheck : public TestFixture {
522523
}
523524
}
524525

526+
void checkPlistOutput() const {
527+
Suppressions supprs;
528+
ErrorLogger2 errorLogger;
529+
std::vector<std::string> files = {"textfile.txt"};
530+
531+
{
532+
const auto s = dinit(Settings, $.templateFormat = templateFormat, $.plistOutput = "output");
533+
const ScopedFile file("file", "");
534+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
535+
const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0};
536+
537+
cppcheck.checkPlistOutput(fileWithDetails, files);
538+
const std::string outputFile {"outputfile_" + std::to_string(std::hash<std::string> {}(fileWithDetails.spath())) + ".plist"};
539+
ASSERT(Path::exists(outputFile));
540+
std::remove(outputFile.c_str());
541+
}
542+
543+
{
544+
const auto s = dinit(Settings, $.plistOutput = "output");
545+
const ScopedFile file("file.c", "");
546+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
547+
const FileWithDetails fileWithDetails {file.path(), Path::identify(file.path(), false), 0};
548+
549+
cppcheck.checkPlistOutput(fileWithDetails, files);
550+
const std::string outputFile {"outputfile_" + std::to_string(std::hash<std::string> {}(fileWithDetails.spath())) + ".plist"};
551+
ASSERT(Path::exists(outputFile));
552+
std::remove(outputFile.c_str());
553+
}
554+
555+
{
556+
Settings s;
557+
const ScopedFile file("file.c", "");
558+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
559+
cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files);
560+
}
561+
}
562+
525563
void premiumResultsCache() const {
526564
// Trac #13889 - cached misra results are shown after removing --premium=misra-c-2012 option
527565

0 commit comments

Comments
 (0)