1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-05 16:31:47 +02:00

Merge pull request #12667 from NixOS/in-dir-cleanup

Cleanup `isInDir` and  `isDirOrInDir`
This commit is contained in:
John Ericson 2025-03-19 18:01:59 -04:00 committed by GitHub
commit 3d333e0aff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 16 additions and 18 deletions

View file

@ -245,7 +245,7 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R
else { else {
target = absPath(target, dirOf(path)); target = absPath(target, dirOf(path));
if (!pathExists(target)) { if (!pathExists(target)) {
if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) { if (isInDir(path, std::filesystem::path{stateDir.get()} / gcRootsDir / "auto")) {
printInfo("removing stale link from '%1%' to '%2%'", path, target); printInfo("removing stale link from '%1%' to '%2%'", path, target);
unlink(path.c_str()); unlink(path.c_str());
} }

View file

@ -1046,7 +1046,7 @@ void LocalDerivationGoal::startBuilder()
/* If only we had a trie to do this more efficiently :) luckily, these are generally going to be pretty small */ /* If only we had a trie to do this more efficiently :) luckily, these are generally going to be pretty small */
for (auto & a : allowedPaths) { for (auto & a : allowedPaths) {
Path canonA = canonPath(a); Path canonA = canonPath(a);
if (canonI == canonA || isInDir(canonI, canonA)) { if (isDirOrInDir(canonI, canonA)) {
found = true; found = true;
break; break;
} }

View file

@ -203,12 +203,10 @@ TEST(isInDir, notInDir)
ASSERT_EQ(p1, false); ASSERT_EQ(p1, false);
} }
// XXX: hm, bug or feature? :) Looking at the implementation
// this might be problematic.
TEST(isInDir, emptyDir) TEST(isInDir, emptyDir)
{ {
auto p1 = isInDir("/zes/foo/bar", ""); auto p1 = isInDir("/zes/foo/bar", "");
ASSERT_EQ(p1, true); ASSERT_EQ(p1, false);
} }
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
@ -233,14 +231,12 @@ TEST(isDirOrInDir, falseForDisjunctPaths)
TEST(isDirOrInDir, relativePaths) TEST(isDirOrInDir, relativePaths)
{ {
ASSERT_EQ(isDirOrInDir("/foo/..", "/foo"), true); ASSERT_EQ(isDirOrInDir("/foo/..", "/foo"), false);
} }
// XXX: while it is possible to use "." or ".." in the TEST(isDirOrInDir, relativePathsTwice)
// first argument this doesn't seem to work in the second.
TEST(isDirOrInDir, DISABLED_shouldWork)
{ {
ASSERT_EQ(isDirOrInDir("/foo/..", "/foo/."), true); ASSERT_EQ(isDirOrInDir("/foo/..", "/foo/."), false);
} }
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------

View file

@ -149,16 +149,18 @@ std::string_view baseNameOf(std::string_view path)
} }
bool isInDir(std::string_view path, std::string_view dir) bool isInDir(const fs::path & path, const fs::path & dir)
{ {
return path.substr(0, 1) == "/" /* Note that while the standard doesn't guarantee this, the
&& path.substr(0, dir.size()) == dir `lexically_*` functions should do no IO and not throw. */
&& path.size() >= dir.size() + 2 auto rel = path.lexically_relative(dir);
&& path[dir.size()] == '/'; /* Method from
https://stackoverflow.com/questions/62503197/check-if-path-contains-another-in-c++ */
return !rel.empty() && rel.native()[0] != OS_STR('.');
} }
bool isDirOrInDir(std::string_view path, std::string_view dir) bool isDirOrInDir(const fs::path & path, const fs::path & dir)
{ {
return path == dir || isInDir(path, dir); return path == dir || isInDir(path, dir);
} }

View file

@ -105,13 +105,13 @@ std::string_view baseNameOf(std::string_view path);
* Check whether 'path' is a descendant of 'dir'. Both paths must be * Check whether 'path' is a descendant of 'dir'. Both paths must be
* canonicalized. * canonicalized.
*/ */
bool isInDir(std::string_view path, std::string_view dir); bool isInDir(const std::filesystem::path & path, const std::filesystem::path & dir);
/** /**
* Check whether 'path' is equal to 'dir' or a descendant of * Check whether 'path' is equal to 'dir' or a descendant of
* 'dir'. Both paths must be canonicalized. * 'dir'. Both paths must be canonicalized.
*/ */
bool isDirOrInDir(std::string_view path, std::string_view dir); bool isDirOrInDir(const std::filesystem::path & path, const std::filesystem::path & dir);
/** /**
* Get status of `path`. * Get status of `path`.