Revert "libutil: extract Base32 helpers from Hash"
Revert submission 3850 Reason for revert: caused multiple regressions noticed in https://git.lix.systems/lix-project/lix/issues/975 and https://git.lix.systems/lix-project/lix/issues/966 (suspected). Root cause analysis has not been done yet and this breaks Lix on Darwin on HEAD. Reverted changes: /q/submissionid:3850 Change-Id: I2dae7147030c883a57be8a8c205e492e16425a23
This commit is contained in:
+48
-3
@@ -80,6 +80,33 @@ static std::string printHash16(const Hash & hash)
|
||||
}
|
||||
|
||||
|
||||
// omitted: E O U T
|
||||
const std::string base32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
||||
|
||||
static std::string printHash32(const Hash & hash)
|
||||
{
|
||||
assert(hash.hashSize);
|
||||
size_t len = hash.base32Len();
|
||||
assert(len);
|
||||
|
||||
std::string s;
|
||||
s.reserve(len);
|
||||
|
||||
for (int n = (int) len - 1; n >= 0; n--) {
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
unsigned char c =
|
||||
(hash.hash[i] >> j)
|
||||
| (i >= hash.hashSize - 1 ? 0 : hash.hash[i + 1] << (8 - j));
|
||||
s.push_back(base32Chars[c & 0x1f]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::string printHash16or32(const Hash & hash)
|
||||
{
|
||||
return hash.to_string(hash.type == HashType::MD5 ? Base::Base16 : Base::Base32, false);
|
||||
@@ -98,7 +125,7 @@ std::string Hash::to_string(Base base, bool includeType) const
|
||||
s += printHash16(*this);
|
||||
break;
|
||||
case Base::Base32:
|
||||
s += base32Encode(std::string_view(charptr_cast<const char *>(hash), hashSize));
|
||||
s += printHash32(*this);
|
||||
break;
|
||||
case Base::Base64:
|
||||
case Base::SRI:
|
||||
@@ -198,8 +225,26 @@ Hash::Hash(std::string_view rest, HashType type, bool isSRI)
|
||||
}
|
||||
|
||||
else if (!isSRI && rest.size() == base32Len()) {
|
||||
auto d = base32Decode(rest);
|
||||
memcpy(hash, d.data(), hashSize);
|
||||
|
||||
for (unsigned int n = 0; n < rest.size(); ++n) {
|
||||
char c = rest[rest.size() - n - 1];
|
||||
size_t digit;
|
||||
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
|
||||
if (base32Chars[digit] == c) break;
|
||||
if (digit >= 32)
|
||||
throw BadHash("invalid base-32 hash '%s'", rest);
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
hash[i] |= digit << j;
|
||||
|
||||
if (i < hashSize - 1) {
|
||||
hash[i + 1] |= digit >> (8 - j);
|
||||
} else {
|
||||
if (digit >> (8 - j))
|
||||
throw BadHash("invalid base-32 hash '%s'", rest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (isSRI || rest.size() == base64Len()) {
|
||||
|
||||
@@ -32,6 +32,8 @@ const int sha512HashSize = 64;
|
||||
|
||||
extern std::set<std::string> hashTypes;
|
||||
|
||||
extern const std::string base32Chars;
|
||||
|
||||
enum class Base : int { Base64, Base32, Base16, SRI };
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "lix/libutil/references.hh"
|
||||
#include "lix/libutil/strings.hh"
|
||||
#include "lix/libutil/hash.hh"
|
||||
#include "lix/libutil/logging.hh"
|
||||
|
||||
|
||||
@@ -195,66 +195,6 @@ std::string base64Decode(std::string_view s)
|
||||
return res;
|
||||
}
|
||||
|
||||
// omitted: E O U T
|
||||
const std::string base32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
||||
std::string base32Encode(std::string_view s)
|
||||
{
|
||||
if (s.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t len = (s.size() * 8 - 1) / 5 + 1;
|
||||
|
||||
std::string res;
|
||||
res.reserve(len);
|
||||
|
||||
for (int n = (int) len - 1; n >= 0; n--) {
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
unsigned char c = (static_cast<unsigned char>(s[i]) >> j) | (i >= s.size() - 1 ? 0 : static_cast<unsigned char>(s[i + 1]) << (8 - j));
|
||||
res.push_back(base32Chars[c & 0x1f]);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string base32Decode(std::string_view s)
|
||||
{
|
||||
if (s.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string res(((s.size() - 1) * 5) / 8 + 1, 0);
|
||||
|
||||
for (unsigned int n = 0; n < s.size(); ++n) {
|
||||
char c = s[s.size() - n - 1];
|
||||
size_t digit;
|
||||
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */ {
|
||||
if (base32Chars[digit] == c) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (digit >= 32) {
|
||||
throw Error("invalid character in base-32 string '%s'", s);
|
||||
}
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
res[i] |= digit << j;
|
||||
|
||||
if (i < s.size() - 1) {
|
||||
res[i + 1] |= digit >> (8 - j);
|
||||
} else {
|
||||
if (digit >> (8 - j)) {
|
||||
throw Error("invalid base-32 string '%s'", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string stripIndentation(std::string_view s)
|
||||
{
|
||||
|
||||
@@ -197,12 +197,6 @@ std::string shellEscape(const std::string_view s);
|
||||
std::string base64Encode(std::string_view s);
|
||||
std::string base64Decode(std::string_view s);
|
||||
|
||||
/**
|
||||
* Base32 encoding/decoding.
|
||||
*/
|
||||
extern const std::string base32Chars;
|
||||
std::string base32Encode(std::string_view s);
|
||||
std::string base32Decode(std::string_view s);
|
||||
|
||||
/**
|
||||
* Remove common leading whitespace from the lines in the string
|
||||
|
||||
@@ -364,53 +364,6 @@ namespace nix {
|
||||
ASSERT_THROW(base64Decode("cXVvZCBlcm_0IGRlbW9uc3RyYW5kdW0="), Error);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* base32Encode
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(base32Encode, emptyString) {
|
||||
ASSERT_EQ(base32Encode(""), "");
|
||||
}
|
||||
|
||||
TEST(base32Encode, encodesAString) {
|
||||
ASSERT_EQ(base32Encode("quod erat demonstrandum"), "6sxb4drhp4x3kdrpnsrb441s62wk541j6yxbi");
|
||||
}
|
||||
|
||||
TEST(base32Encode, encodeAndDecode) {
|
||||
auto s = "quod erat demonstrandum";
|
||||
auto encoded = base32Encode(s);
|
||||
auto decoded = base32Decode(encoded);
|
||||
|
||||
ASSERT_EQ(decoded, s);
|
||||
}
|
||||
|
||||
TEST(base32Encode, encodeAndDecodeNonPrintable) {
|
||||
char s[256];
|
||||
std::iota(std::rbegin(s), std::rend(s), 0);
|
||||
|
||||
auto encoded = base32Encode(s);
|
||||
auto decoded = base32Decode(encoded);
|
||||
|
||||
EXPECT_EQ(decoded.length(), 255);
|
||||
ASSERT_EQ(decoded, s);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* base32Decode
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(base32Decode, emptyString) {
|
||||
ASSERT_EQ(base32Decode(""), "");
|
||||
}
|
||||
|
||||
TEST(base32Decode, decodeAString) {
|
||||
ASSERT_EQ(base32Decode("6sxb4drhp4x3kdrpnsrb441s62wk541j6yxbi"), "quod erat demonstrandum");
|
||||
}
|
||||
|
||||
TEST(base32Decode, decodeThrowsOnInvalidChar) {
|
||||
ASSERT_THROW(base32Decode("6sxb4drhp4x3kdrpnsrb441s62wk541j6yxbe"), Error);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* getLine
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user