From 19aa892f2064d437d32a3c12758d6a623b7ae8e5 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Tue, 9 Jun 2020 11:10:54 -0500 Subject: [PATCH] Support empty hash in fetchers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fetchTarball, fetchTree, and fetchGit all have *optional* hash attrs. This means that we need to be careful with what we allow to avoid accidentally making these defaults. When ‘hash = ""’ we assume the empty hash is wanted. --- src/libexpr/primops.cc | 11 ++++++++--- src/libexpr/primops/fetchTree.cc | 11 ++++++++--- src/libfetchers/fetchers.cc | 11 ++++++++--- src/libfetchers/tarball.cc | 11 ++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index de04fd2be..df3d4a459 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1131,9 +1131,14 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value filterFun = attr.value; } else if (n == "recursive") method = FileIngestionMethod { state.forceBool(*attr.value, *attr.pos) }; - else if (n == "sha256") - expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); - else + else if (n == "sha256") { + auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); + if (hashStr == "") { + expectedHash = Hash(htSHA256); + printError("warning: found empty hash, assuming you wanted '%s'", expectedHash.to_string()); + } else + expectedHash = Hash(hashStr, htSHA256); + } else throw EvalError(format("unsupported argument '%1%' to 'addPath', at %2%") % attr.name % *attr.pos); } if (path.empty()) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index c5a0d9886..745f65adf 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,9 +102,14 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, string n(attr.name); if (n == "url") url = state.forceStringNoCtx(*attr.value, *attr.pos); - else if (n == "sha256") - expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); - else if (n == "name") + else if (n == "sha256") { + auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); + if (hashStr == "") { + expectedHash = Hash(htSHA256); + printError("warning: found empty hash, assuming you wanted '%s'", expectedHash->to_string()); + } else + expectedHash = Hash(hashStr, htSHA256); + } else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else throw EvalError("unsupported argument '%s' to '%s', at %s", diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 94ac30e38..988a8dc69 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -34,9 +34,14 @@ std::unique_ptr inputFromAttrs(const Attrs & attrs) for (auto & inputScheme : *inputSchemes) { auto res = inputScheme->inputFromAttrs(attrs2); if (res) { - if (auto narHash = maybeGetStrAttr(attrs, "narHash")) - // FIXME: require SRI hash. - res->narHash = Hash(*narHash); + if (auto narHash = maybeGetStrAttr(attrs, "narHash")) { + if (narHash->empty()) { + res->narHash = Hash(htUnknown); + printError("warning: found empty hash, assuming you wanted '%s'", res->narHash->to_string()); + } else + // FIXME: require SRI hash. + res->narHash = Hash(*narHash); + } return res; } } diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index b6e57379b..e4dafec0b 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -263,9 +263,14 @@ struct TarballInputScheme : InputScheme throw Error("unsupported tarball input attribute '%s'", name); auto input = std::make_unique(parseURL(getStrAttr(attrs, "url"))); - if (auto hash = maybeGetStrAttr(attrs, "hash")) - // FIXME: require SRI hash. - input->hash = Hash(*hash); + if (auto hash = maybeGetStrAttr(attrs, "hash")) { + if (hash->empty()) { + input->hash = Hash(htUnknown); + printError("warning: found empty hash, assuming you wanted '%s'", input->hash->to_string()); + } else + // FIXME: require SRI hash. + input->hash = Hash(*hash); + } return input; }