diff options
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r-- | src/libstore/store-api.cc | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index af002dcc8c33..5dd56f905d57 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -202,6 +202,22 @@ Path Store::makeFixedOutputPath(bool recursive, } +Path Store::makeTextPath(const string & name, const Hash & hash, + const PathSet & references) const +{ + assert(hash.type == htSHA256); + /* Stuff the references (if any) into the type. This is a bit + hacky, but we can't put them in `s' since that would be + ambiguous. */ + string type = "text"; + for (auto & i : references) { + type += ":"; + type += i; + } + return makeStorePath(type, hash, name); +} + + std::pair<Path, Hash> Store::computeStorePathForPath(const Path & srcPath, bool recursive, HashType hashAlgo, PathFilter & filter) const { @@ -215,16 +231,7 @@ std::pair<Path, Hash> Store::computeStorePathForPath(const Path & srcPath, Path Store::computeStorePathForText(const string & name, const string & s, const PathSet & references) const { - Hash hash = hashString(htSHA256, s); - /* Stuff the references (if any) into the type. This is a bit - hacky, but we can't put them in `s' since that would be - ambiguous. */ - string type = "text"; - for (auto & i : references) { - type += ":"; - type += i; - } - return makeStorePath(type, hash, name); + return makeTextPath(name, hashString(htSHA256, s), references); } @@ -432,9 +439,38 @@ void ValidPathInfo::sign(const SecretKey & secretKey) } -unsigned int ValidPathInfo::checkSignatures(const PublicKeys & publicKeys) const +bool ValidPathInfo::isContentAddressed(const Store & store) const +{ + auto warn = [&]() { + printMsg(lvlError, format("warning: path ‘%s’ claims to be content-addressed but isn't") % path); + }; + + if (hasPrefix(ca, "text:")) { + auto hash = parseHash(std::string(ca, 5)); + if (store.makeTextPath(storePathToName(path), hash, references) == path) + return true; + else + warn(); + } + + else if (hasPrefix(ca, "fixed:")) { + bool recursive = ca.compare(6, 2, "r:") == 0; + auto hash = parseHash(std::string(ca, recursive ? 8 : 6)); + if (store.makeFixedOutputPath(recursive, hash, storePathToName(path)) == path) + return true; + else + warn(); + } + + return false; +} + + +size_t ValidPathInfo::checkSignatures(const Store & store, const PublicKeys & publicKeys) const { - unsigned int good = 0; + if (isContentAddressed(store)) return maxSigs; + + size_t good = 0; for (auto & sig : sigs) if (checkSignature(publicKeys, sig)) good++; |