From fca291afc358e4f1c9565dd236db1d0cc87fef24 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 12 Jun 2025 16:00:29 +0200 Subject: [PATCH] Fix NAR hash checking for fetchGit with lazy tees If a NAR hash is specified, we should probably check it. Unfortunately, for now this has the side effect of forcing NAR hash checking of any input that has a NAR hash. --- src/libexpr/paths.cc | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/libexpr/paths.cc b/src/libexpr/paths.cc index 40c0a23b6..d85f00470 100644 --- a/src/libexpr/paths.cc +++ b/src/libexpr/paths.cc @@ -77,25 +77,28 @@ StorePath EvalState::mountInput( allowPath(storePath); // FIXME: should just whitelist the entire virtual store + std::optional _narHash; + + auto getNarHash = [&]() + { + if (!_narHash) + // FIXME: use fetchToStore to make it cache this + _narHash = accessor->hashPath(CanonPath::root); + return _narHash; + }; + storeFS->mount(CanonPath(store->printStorePath(storePath)), accessor); - if (requireLockable && (!settings.lazyTrees || !input.isLocked()) && !input.getNarHash()) { - // FIXME: use fetchToStore to make it cache this - auto narHash = accessor->hashPath(CanonPath::root); - input.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true)); - } + if (requireLockable && (!settings.lazyTrees || !input.isLocked()) && !input.getNarHash()) + input.attrs.insert_or_assign("narHash", getNarHash()->to_string(HashFormat::SRI, true)); - // FIXME: what to do with the NAR hash in lazy mode? - if (!settings.lazyTrees && originalInput.getNarHash()) { - auto expected = originalInput.computeStorePath(*store); - if (storePath != expected) - throw Error( - (unsigned int) 102, - "NAR hash mismatch in input '%s', expected '%s' but got '%s'", - originalInput.to_string(), - store->printStorePath(storePath), - store->printStorePath(expected)); - } + if (originalInput.getNarHash() && *getNarHash() != *originalInput.getNarHash()) + throw Error( + (unsigned int) 102, + "NAR hash mismatch in input '%s', expected '%s' but got '%s'", + originalInput.to_string(), + getNarHash()->to_string(HashFormat::SRI, true), + originalInput.getNarHash()->to_string(HashFormat::SRI, true)); return storePath; }