Skip to content

Commit a1ba232

Browse files
committed
Add check for npos, when checkInternal receives file with missing dot
1 parent 19faaee commit a1ba232

3 files changed

Lines changed: 53 additions & 10 deletions

File tree

lib/cppcheck.cpp

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

887+
bool 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+
const std::size_t dotPosition = filename.find('.');
893+
894+
if(dotPosition == std::string::npos) {
895+
ErrorMessage::FileLocation loc(filename, 0, 0);
896+
ErrorMessage errmsg({std::move(loc)}, "", Severity::error, "filename does not contain dot", "filenameError", Certainty::normal);
897+
mErrorLogger.reportErr(errmsg);
898+
return false;
899+
}
900+
901+
const std::size_t fileNameHash = std::hash<std::string> {}(file.spath());
902+
filename = mSettings.plistOutput + filename.substr(0, filename.find('.')) + "_" + std::to_string(fileNameHash) + ".plist";
903+
mLogger->openPlist(filename, files);
904+
}
905+
return true;
906+
}
907+
887908
unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::string &cfgname, int fileIndex, const CreateTokenListFn& createTokenList)
888909
{
889910
// TODO: move to constructor when CppCheck no longer owns the settings
@@ -989,16 +1010,8 @@ unsigned int CppCheck::checkInternal(const FileWithDetails& file, const std::str
9891010
if (!preprocessor.loadFiles(tokens1, files))
9901011
return mLogger->exitcode();
9911012

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-
}
1013+
if (!checkPlistOutput(file, files))
1014+
return mLogger->exitcode();
10021015

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

lib/cppcheck.h

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

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

test/testcppcheck.cpp

Lines changed: 28 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,33 @@ class TestCppcheck : public TestFixture {
522523
}
523524
}
524525

526+
void checkPlistOutput() const {
527+
Suppressions supprs;
528+
ErrorLogger2 errorLogger;
529+
std::vector<std::string> files = {"file.txt"};
530+
531+
{
532+
const auto s = dinit(Settings, $.templateFormat = templateFormat, $.plistOutput = "output");
533+
ScopedFile file("file", "");
534+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
535+
ASSERT_EQUALS(false, cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files));
536+
}
537+
538+
{
539+
const auto s = dinit(Settings, $.plistOutput = "output");
540+
ScopedFile file("file.c", "");
541+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
542+
ASSERT_EQUALS(true, cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files));
543+
}
544+
545+
{
546+
Settings s;
547+
ScopedFile file("file.c", "");
548+
CppCheck cppcheck(s, supprs, errorLogger, false, {});
549+
ASSERT_EQUALS(true, cppcheck.checkPlistOutput(FileWithDetails(file.path(), Path::identify(file.path(), false), 0), files));
550+
}
551+
}
552+
525553
void premiumResultsCache() const {
526554
// Trac #13889 - cached misra results are shown after removing --premium=misra-c-2012 option
527555

0 commit comments

Comments
 (0)