Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions src/libutil/hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,19 @@ static std::string printHash16(const Hash & hash)
}

// omitted: E O U T
const std::string nix32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
constexpr char nix32Chars[] = "0123456789abcdfghijklmnpqrsvwxyz";

constexpr const std::array<unsigned char, 256> reverseNix32Map = [] {
std::array<unsigned char, 256> map{};

for (size_t i = 0; i < map.size(); ++i)
map[i] = 0xFF; // invalid

for (unsigned char i = 0; i < 32; ++i)
map[static_cast<unsigned char>(nix32Chars[i])] = i;

return map;
}();

static std::string printHash32(const Hash & hash)
{
Expand Down Expand Up @@ -217,12 +229,11 @@ Hash::Hash(std::string_view rest, HashAlgorithm algo, bool isSRI)

for (unsigned int n = 0; n < rest.size(); ++n) {
char c = rest[rest.size() - n - 1];
unsigned char digit;
for (digit = 0; digit < nix32Chars.size(); ++digit) /* !!! slow */
if (nix32Chars[digit] == c)
break;
if (digit >= 32)
throw BadHash("invalid base-32 hash '%s'", rest);
unsigned char digit = reverseNix32Map[static_cast<unsigned char>(c)];

if (digit == 0xFF)
throw BadHash("invalid base-32 hash: '%s'", rest);

unsigned int b = n * 5;
unsigned int i = b / 8;
unsigned int j = b % 8;
Expand Down
2 changes: 1 addition & 1 deletion src/libutil/include/nix/util/hash.hh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ constexpr inline size_t regularHashSize(HashAlgorithm type)

extern const StringSet hashAlgorithms;

extern const std::string nix32Chars;
extern const std::array<unsigned char, 256> reverseNix32Map;

/**
* @brief Enumeration representing the hash formats.
Expand Down
11 changes: 1 addition & 10 deletions src/libutil/references.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,11 @@ static size_t refLength = 32; /* characters */

static void search(std::string_view s, StringSet & hashes, StringSet & seen)
{
static std::once_flag initialised;
static bool isBase32[256];
std::call_once(initialised, []() {
for (unsigned int i = 0; i < 256; ++i)
isBase32[i] = false;
for (unsigned int i = 0; i < nix32Chars.size(); ++i)
isBase32[(unsigned char) nix32Chars[i]] = true;
});

for (size_t i = 0; i + refLength <= s.size();) {
int j;
bool match = true;
for (j = refLength - 1; j >= 0; --j)
if (!isBase32[(unsigned char) s[i + j]]) {
if (reverseNix32Map[(unsigned char) s[i + j]] == 0xFF) {
i += j + 1;
match = false;
break;
Expand Down
Loading