diff --git a/src/libutil/canon-path.cc b/src/libutil/canon-path.cc index 7aeabe8d9..79951c933 100644 --- a/src/libutil/canon-path.cc +++ b/src/libutil/canon-path.cc @@ -16,14 +16,13 @@ CanonPath::CanonPath(std::string_view raw, const CanonPath & root) std::optional CanonPath::parent() const { if (isRoot()) return std::nullopt; - return CanonPath(unchecked_t(), path.substr(0, path.rfind('/'))); + return CanonPath(unchecked_t(), path.substr(0, std::max((size_t) 1, path.rfind('/')))); } void CanonPath::pop() { assert(!isRoot()); - auto slash = path.rfind('/'); - path.resize(std::max((size_t) 1, slash)); + path.resize(std::max((size_t) 1, path.rfind('/'))); } bool CanonPath::isWithin(const CanonPath & parent) const diff --git a/src/libutil/tests/canon-path.cc b/src/libutil/tests/canon-path.cc index 28fa789a0..c1c5adadf 100644 --- a/src/libutil/tests/canon-path.cc +++ b/src/libutil/tests/canon-path.cc @@ -11,6 +11,7 @@ namespace nix { ASSERT_EQ(p.rel(), ""); ASSERT_EQ(p.baseName(), std::nullopt); ASSERT_EQ(p.dirOf(), std::nullopt); + ASSERT_FALSE(p.parent()); } { @@ -19,6 +20,7 @@ namespace nix { ASSERT_EQ(p.rel(), "foo"); ASSERT_EQ(*p.baseName(), "foo"); ASSERT_EQ(*p.dirOf(), ""); // FIXME: do we want this? + ASSERT_EQ(p.parent()->abs(), "/"); } { @@ -27,6 +29,7 @@ namespace nix { ASSERT_EQ(p.rel(), "foo/bar"); ASSERT_EQ(*p.baseName(), "bar"); ASSERT_EQ(*p.dirOf(), "/foo"); + ASSERT_EQ(p.parent()->abs(), "/foo"); } {