diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index df3d4a459..083c7d398 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -720,12 +720,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
- Hash h;
- if (outputHash->empty()) {
- h = Hash(ht);
- printError("warning: found empty hash, assuming you wanted '%s'", h.to_string());
- } else
- h = Hash(*outputHash, ht);
+ Hash h = newHashAllowEmpty(*outputHash, ht);
auto outPath = state.store->makeFixedOutputPath(ingestionMethod, h, drvName);
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
@@ -1131,14 +1126,9 @@ 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") {
- 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
+ else if (n == "sha256")
+ expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), 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 745f65adf..1464aa8b4 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -102,14 +102,9 @@ 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") {
- 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")
+ else if (n == "sha256")
+ expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), 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 988a8dc69..91b897e62 100644
--- a/src/libfetchers/fetchers.cc
+++ b/src/libfetchers/fetchers.cc
@@ -34,14 +34,9 @@ std::unique_ptr inputFromAttrs(const Attrs & attrs)
for (auto & inputScheme : *inputSchemes) {
auto res = inputScheme->inputFromAttrs(attrs2);
if (res) {
- 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);
- }
+ if (auto narHash = maybeGetStrAttr(attrs, "narHash"))
+ // FIXME: require SRI hash.
+ res->narHash = newHashAllowEmpty(*narHash, htUnknown);
return res;
}
}
diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc
index e4dafec0b..937f86bc6 100644
--- a/src/libfetchers/tarball.cc
+++ b/src/libfetchers/tarball.cc
@@ -263,14 +263,8 @@ 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")) {
- 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);
- }
+ if (auto hash = maybeGetStrAttr(attrs, "hash"))
+ input->hash = newHashAllowEmpty(*hash, htUnknown);
return input;
}
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 7caee1da7..2c8085e42 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -205,6 +205,16 @@ Hash::Hash(const std::string & s, HashType type)
throw BadHash("hash '%s' has wrong length for hash type '%s'", s, printHashType(type));
}
+Hash newHashAllowEmpty(std::string hashStr, HashType ht)
+{
+ if (hashStr.empty())
+ {
+ Hash h(ht);
+ warn("found empty hash, assuming you wanted '%s'", h.to_string());
+ } else
+ return Hash(hashStr, ht);
+}
+
union Ctx
{
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index ea9fca3e7..449cb1b86 100644
--- a/src/libutil/hash.hh
+++ b/src/libutil/hash.hh
@@ -94,6 +94,8 @@ struct Hash
}
};
+/* Helper that defaults empty hashes to the 0 hash. */
+Hash newHashAllowEmpty(std::string hashStr, HashType ht);
/* Print a hash in base-16 if it's MD5, or base-32 otherwise. */
string printHash16or32(const Hash & hash);