From 341e6049a75db5cb0b53c8c6410615741ba4633d Mon Sep 17 00:00:00 2001 From: gilice Date: Sat, 12 Apr 2025 11:46:59 +0200 Subject: [PATCH] libutil: canonPath: error instead of panic on empty path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This could previously crash lix: Before: $ nix eval -E '{type="derivation"; drvPath="";}' nix: lix/libutil/file-system.cc:45: Path nix::canonPath(PathView, bool): Assertion `path != ""' failed. Aborted (core dumped) After: $ nix eval -E '{type="derivation"; drvPath="";}' error: … while evaluating the drvPath of a derivation at «string»:1:21: 1| {type="derivation"; drvPath="";} | ^ error: path '' is not in the Nix store Fixes #536 Change-Id: I406dc9e58047be8f263cf2e4bc3ed5da75a46602 --- lix/libstore/path.cc | 2 +- lix/libutil/file-system.cc | 6 ++---- tests/unit/libutil/tests.cc | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lix/libstore/path.cc b/lix/libstore/path.cc index 4bdfb2483..838cb217d 100644 --- a/lix/libstore/path.cc +++ b/lix/libstore/path.cc @@ -77,7 +77,7 @@ std::optional Store::maybeParseStorePath(std::string_view path) const { // If it's not an absolute path, or if the dirname of the path isn't /nix/store // (or whatever our storeDir is), then it can't be a store path. - if ((path.size() > 0 && path[0] != '/') || dirOf(canonPath(path)) != config().storeDir) { + if (path.size() == 0 || path[0] != '/' || dirOf(canonPath(path)) != config().storeDir) { return std::nullopt; } try { diff --git a/lix/libutil/file-system.cc b/lix/libutil/file-system.cc index 49fb80bca..b29361719 100644 --- a/lix/libutil/file-system.cc +++ b/lix/libutil/file-system.cc @@ -42,14 +42,12 @@ Path absPath(Path path, std::optional dir, bool resolveSymlinks) Path canonPath(PathView path, bool resolveSymlinks) { - assert(path != ""); + if (path == "" || path[0] != '/') + throw Error("not an absolute path: '%1%'", path); std::string s; s.reserve(256); - if (path[0] != '/') - throw Error("not an absolute path: '%1%'", path); - std::string temp; /* Count the number of times we follow a symlink and stop at some diff --git a/tests/unit/libutil/tests.cc b/tests/unit/libutil/tests.cc index 00fcf8269..bbf285bea 100644 --- a/tests/unit/libutil/tests.cc +++ b/tests/unit/libutil/tests.cc @@ -89,7 +89,7 @@ namespace nix { ASSERT_ANY_THROW(canonPath(".")); ASSERT_ANY_THROW(canonPath("..")); ASSERT_ANY_THROW(canonPath("../")); - ASSERT_DEATH({ canonPath(""); }, "path != \"\""); + ASSERT_ANY_THROW(canonPath("")); } /* ----------------------------------------------------------------------------