diff --git a/lib/pathmatch.cpp b/lib/pathmatch.cpp index caf121608ed..37c9c8e7f81 100644 --- a/lib/pathmatch.cpp +++ b/lib/pathmatch.cpp @@ -45,6 +45,11 @@ bool PathMatch::match(const std::string &path) const std::string findpath = Path::fromNativeSeparators(path); if (!mCaseSensitive) strTolower(findpath); + std::string finddir; + if (!endsWith(findpath,'/')) + finddir = removeFilename(findpath); + else + finddir = findpath; const bool is_absolute = Path::isAbsolute(path); @@ -54,19 +59,16 @@ bool PathMatch::match(const std::string &path) const // Filtering directory name if (endsWith(pathToMatch,'/')) { - if (!endsWith(findpath,'/')) - findpath = removeFilename(findpath); - - if (pathToMatch.length() > findpath.length()) + if (pathToMatch.length() > finddir.length()) continue; // Match relative paths starting with mask // -isrc matches src/foo.cpp - if (findpath.compare(0, pathToMatch.size(), pathToMatch) == 0) + if (finddir.compare(0, pathToMatch.size(), pathToMatch) == 0) return true; // Match only full directory name in middle or end of the path // -isrc matches myproject/src/ but does not match // myproject/srcfiles/ or myproject/mysrc/ - if (findpath.find("/" + pathToMatch) != std::string::npos) + if (finddir.find("/" + pathToMatch) != std::string::npos) return true; } // Filtering filename diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 655e45de28b..a76fd5e0b4f 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -2784,4 +2784,30 @@ def test_addon_suppr_cli_file_line(tmp_path): def test_addon_suppr_cli_absfile_line(tmp_path): test_file = tmp_path / 'test.c' - __test_addon_suppr(tmp_path, ['--suppress=misra-c2012-2.3:{}:3'.format(test_file)]) \ No newline at end of file + __test_addon_suppr(tmp_path, ['--suppress=misra-c2012-2.3:{}:3'.format(test_file)]) + + +def test_file_ignore_2(tmp_path): # #13570 + tests_path = tmp_path / 'tests' + os.mkdir(tests_path) + + lib_path = tmp_path / 'lib' + os.mkdir(lib_path) + + test_file_1 = lib_path / 'test_1.c' + with open(test_file_1, 'wt'): + pass + + args = [ + '-itests', + '-itest_1.c', + '.' + ] + + exitcode, stdout, stderr = cppcheck(args, cwd=tmp_path) + assert exitcode == 1, stdout + assert stdout.splitlines() == [ + 'cppcheck: error: could not find or open any of the paths given.', + 'cppcheck: Maybe all paths were ignored?' + ] + assert stderr.splitlines() == [] \ No newline at end of file diff --git a/test/testpathmatch.cpp b/test/testpathmatch.cpp index 25cfbe5595b..8786e1b795f 100644 --- a/test/testpathmatch.cpp +++ b/test/testpathmatch.cpp @@ -52,6 +52,7 @@ class TestPathMatch : public TestFixture { TEST_CASE(onemasklongerpath1); TEST_CASE(onemasklongerpath2); TEST_CASE(onemasklongerpath3); + TEST_CASE(onemaskcwd); TEST_CASE(twomasklongerpath1); TEST_CASE(twomasklongerpath2); TEST_CASE(twomasklongerpath3); @@ -60,10 +61,12 @@ class TestPathMatch : public TestFixture { TEST_CASE(filemaskdifferentcase); TEST_CASE(filemask2); TEST_CASE(filemask3); + TEST_CASE(filemaskcwd); TEST_CASE(filemaskpath1); TEST_CASE(filemaskpath2); TEST_CASE(filemaskpath3); TEST_CASE(filemaskpath4); + TEST_CASE(mixedallmatch); } // Test empty PathMatch @@ -146,6 +149,10 @@ class TestPathMatch : public TestFixture { ASSERT(srcMatcher.match("project/src/module/")); } + void onemaskcwd() const { + ASSERT(!srcMatcher.match("./src")); + } + void twomasklongerpath1() const { std::vector masks = { "src/", "module/" }; PathMatch match(std::move(masks)); @@ -189,6 +196,10 @@ class TestPathMatch : public TestFixture { ASSERT(fooCppMatcher.match("src/foo.cpp")); } + void filemaskcwd() const { + ASSERT(fooCppMatcher.match("./lib/foo.cpp")); + } + // Test PathMatch containing "src/foo.cpp" void filemaskpath1() const { ASSERT(srcFooCppMatcher.match("src/foo.cpp")); @@ -205,6 +216,14 @@ class TestPathMatch : public TestFixture { void filemaskpath4() const { ASSERT(!srcFooCppMatcher.match("bar/foo.cpp")); } + + void mixedallmatch() const { // #13570 + // when trying to match a directory against a directory entry it erroneously modified a local variable also used for file matching + std::vector masks = { "tests/", "file.c" }; + PathMatch match(std::move(masks)); + ASSERT(match.match("tests/")); + ASSERT(match.match("lib/file.c")); + } }; REGISTER_TEST(TestPathMatch)