From 26741bcfda78a307ed2a92b9a7137e6b50091769 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 5 Dec 2024 16:02:35 +0100 Subject: [PATCH 1/4] nix hash convert: Support SRI hashes that lack trailing '=' characters Fixes #11996. (cherry picked from commit 52f1cd05956b7745985c5565a463633f0b805639) --- src/libutil/hash.cc | 3 ++- src/nix/hash.cc | 9 ++++++--- tests/functional/hash-convert.sh | 14 ++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 748176d33..b69dec685 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -134,7 +134,8 @@ std::string Hash::to_string(HashFormat hashFormat, bool includeAlgo) const Hash Hash::dummy(HashAlgorithm::SHA256); -Hash Hash::parseSRI(std::string_view original) { +Hash Hash::parseSRI(std::string_view original) +{ auto rest = original; // Parse the has type before the separater, if there was one. diff --git a/src/nix/hash.cc b/src/nix/hash.cc index 62266fda1..f2761e1cf 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -222,9 +222,12 @@ struct CmdHashConvert : Command Category category() override { return catUtility; } void run() override { - for (const auto& s: hashStrings) { - Hash h = Hash::parseAny(s, algo); - if (from && h.to_string(*from, from == HashFormat::SRI) != s) { + for (const auto & s: hashStrings) { + Hash h = + from == HashFormat::SRI + ? Hash::parseSRI(s) + : Hash::parseAny(s, algo); + if (from && from != HashFormat::SRI && h.to_string(*from, false) != s) { auto from_as_string = printHashFormat(*from); throw BadHash("input hash '%s' does not have the expected format '--from %s'", s, from_as_string); } diff --git a/tests/functional/hash-convert.sh b/tests/functional/hash-convert.sh index 3a099950f..1cbe864f3 100755 --- a/tests/functional/hash-convert.sh +++ b/tests/functional/hash-convert.sh @@ -93,15 +93,17 @@ try3() { # Asserting input format fails. # - fail=$(nix hash convert --hash-algo "$1" --from nix32 "$2" 2>&1 || echo "exit: $?") - [[ "$fail" == *"error: input hash"*"exit: 1" ]] - fail=$(nix hash convert --hash-algo "$1" --from base16 "$3" 2>&1 || echo "exit: $?") - [[ "$fail" == *"error: input hash"*"exit: 1" ]] - fail=$(nix hash convert --hash-algo "$1" --from nix32 "$4" 2>&1 || echo "exit: $?") - [[ "$fail" == *"error: input hash"*"exit: 1" ]] + expectStderr 1 nix hash convert --hash-algo "$1" --from sri "$2" | grepQuiet "is not SRI" + expectStderr 1 nix hash convert --hash-algo "$1" --from nix32 "$2" | grepQuiet "input hash" + expectStderr 1 nix hash convert --hash-algo "$1" --from base16 "$3" | grepQuiet "input hash" + expectStderr 1 nix hash convert --hash-algo "$1" --from nix32 "$4" | grepQuiet "input hash" } try3 sha1 "800d59cfcd3c05e900cb4e214be48f6b886a08df" "vw46m23bizj4n8afrc0fj19wrp7mj3c0" "gA1Zz808BekAy04hS+SPa4hqCN8=" try3 sha256 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" "1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s" "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=" try3 sha512 "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445" "12k9jiq29iyqm03swfsgiw5mlqs173qazm3n7daz43infy12pyrcdf30fkk3qwv4yl2ick8yipc2mqnlh48xsvvxl60lbx8vp38yji0" "IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ==" + +# Test SRI hashes that lack trailing '=' characters. These are incorrect but we need to support them for backward compatibility. +[[ $(nix hash convert --from sri "sha256-ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0") = sha256-ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0= ]] +[[ $(nix hash convert --from sri "sha512-IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ") = sha512-IEqPxt2oLwoM7XvrjgikFlfBbvRosiioJ5vjMacDwzWW/RXBOxsH+aodO+pXeJygMa2Fx6cd1wNU7GMSOMo0RQ== ]] From 97f0c68389b4ec23a69c41d25bf605da80fcdf4c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 5 Dec 2024 16:19:21 +0100 Subject: [PATCH 2/4] nix hash convert: Don't fail on uppercase base-16 hashes (cherry picked from commit 33b645cedfabd4f275644ac4df0eac220f444278) --- src/nix/hash.cc | 10 +++++++--- tests/functional/hash-convert.sh | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/nix/hash.cc b/src/nix/hash.cc index f2761e1cf..4f2d8eef0 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -222,14 +222,18 @@ struct CmdHashConvert : Command Category category() override { return catUtility; } void run() override { - for (const auto & s: hashStrings) { + for (const auto & s : hashStrings) { Hash h = from == HashFormat::SRI ? Hash::parseSRI(s) : Hash::parseAny(s, algo); - if (from && from != HashFormat::SRI && h.to_string(*from, false) != s) { + if (from + && from != HashFormat::SRI + && h.to_string(*from, false) != + (from == HashFormat::Base16 ? toLower(s) : s)) + { auto from_as_string = printHashFormat(*from); - throw BadHash("input hash '%s' does not have the expected format '--from %s'", s, from_as_string); + throw BadHash("input hash '%s' does not have the expected format for '--from %s'", s, from_as_string); } logger->cout(h.to_string(to, to == HashFormat::SRI)); } diff --git a/tests/functional/hash-convert.sh b/tests/functional/hash-convert.sh index 1cbe864f3..c40cb469c 100755 --- a/tests/functional/hash-convert.sh +++ b/tests/functional/hash-convert.sh @@ -98,6 +98,8 @@ try3() { expectStderr 1 nix hash convert --hash-algo "$1" --from base16 "$3" | grepQuiet "input hash" expectStderr 1 nix hash convert --hash-algo "$1" --from nix32 "$4" | grepQuiet "input hash" + # Base-16 hashes can be in uppercase. + nix hash convert --hash-algo "$1" --from base16 "$(echo $2 | tr [a-z] [A-Z])" } try3 sha1 "800d59cfcd3c05e900cb4e214be48f6b886a08df" "vw46m23bizj4n8afrc0fj19wrp7mj3c0" "gA1Zz808BekAy04hS+SPa4hqCN8=" From 0a2545b23ad2409eaf8bbe778d7edbd2211e25be Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 5 Dec 2024 16:25:05 +0100 Subject: [PATCH 3/4] nix hash: Don't print 'nix hash' deprecation message Fixes #11997. (cherry picked from commit 408c2faf9365ab1b6f9e28551429d9352f9e7f1a) # Conflicts: # src/nix/hash.cc --- src/nix/hash.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/nix/hash.cc b/src/nix/hash.cc index 4f2d8eef0..61601f21e 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -163,8 +163,11 @@ struct CmdToBase : Command HashFormat hashFormat; std::optional hashAlgo; std::vector args; + bool legacyCli; - CmdToBase(HashFormat hashFormat) : hashFormat(hashFormat) + CmdToBase(HashFormat hashFormat, bool legacyCli = false) + : hashFormat(hashFormat) + , legacyCli(legacyCli) { addFlag(flag::hashAlgoOpt("type", &hashAlgo)); expectArgs("strings", &args); @@ -181,8 +184,14 @@ struct CmdToBase : Command void run() override { +<<<<<<< HEAD warn("The old format conversion sub commands of `nix hash` were deprecated in favor of `nix hash convert`."); for (auto s : args) +======= + if (!legacyCli) + warn("The old format conversion subcommands of `nix hash` were deprecated in favor of `nix hash convert`."); + for (const auto & s : args) +>>>>>>> 408c2faf9 (nix hash: Don't print 'nix hash' deprecation message) logger->cout(Hash::parseAny(s, hashAlgo).to_string(hashFormat, hashFormat == HashFormat::SRI)); } }; @@ -328,7 +337,7 @@ static int compatNixHash(int argc, char * * argv) } else { - CmdToBase cmd(hashFormat); + CmdToBase cmd(hashFormat, true); cmd.args = ss; if (hashAlgo.has_value()) cmd.hashAlgo = hashAlgo; cmd.run(); From a5ee9a3e9922d998d3263d58994f182c3aa8c035 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 6 Dec 2024 12:13:51 +0100 Subject: [PATCH 4/4] Resolve conflicts --- src/nix/hash.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/nix/hash.cc b/src/nix/hash.cc index 61601f21e..a98f0c77a 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -184,14 +184,9 @@ struct CmdToBase : Command void run() override { -<<<<<<< HEAD - warn("The old format conversion sub commands of `nix hash` were deprecated in favor of `nix hash convert`."); - for (auto s : args) -======= if (!legacyCli) warn("The old format conversion subcommands of `nix hash` were deprecated in favor of `nix hash convert`."); for (const auto & s : args) ->>>>>>> 408c2faf9 (nix hash: Don't print 'nix hash' deprecation message) logger->cout(Hash::parseAny(s, hashAlgo).to_string(hashFormat, hashFormat == HashFormat::SRI)); } };