Skip to content

Commit

Permalink
fixed #13570 - PathMatch could no longer match a file after it tried …
Browse files Browse the repository at this point in the history
…to match a directory (#7242)
  • Loading branch information
firewave authored Feb 7, 2025
1 parent fe6a2e3 commit f447521
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
14 changes: 8 additions & 6 deletions lib/pathmatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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
Expand Down
26 changes: 26 additions & 0 deletions test/cli/other_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3038,4 +3038,30 @@ def test_debug_template(tmp_path):
assert stdout.find('### Symbol database ###') == -1
assert stdout.find('##AST') == -1
assert stdout.find('### Template Simplifier pass ') != -1
assert stderr.splitlines() == []


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() == []
19 changes: 19 additions & 0 deletions test/testpathmatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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<std::string> masks = { "src/", "module/" };
PathMatch match(std::move(masks));
Expand Down Expand Up @@ -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"));
Expand All @@ -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<std::string> masks = { "tests/", "file.c" };
PathMatch match(std::move(masks));
ASSERT(match.match("tests/"));
ASSERT(match.match("lib/file.c"));
}
};

REGISTER_TEST(TestPathMatch)

0 comments on commit f447521

Please sign in to comment.