about summary refs log tree commit diff
path: root/third_party/nix/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libutil')
-rw-r--r--third_party/nix/src/libutil/hash.cc39
-rw-r--r--third_party/nix/src/libutil/hash.hh6
2 files changed, 43 insertions, 2 deletions
diff --git a/third_party/nix/src/libutil/hash.cc b/third_party/nix/src/libutil/hash.cc
index 9165182ed70f..5596ef01784f 100644
--- a/third_party/nix/src/libutil/hash.cc
+++ b/third_party/nix/src/libutil/hash.cc
@@ -78,6 +78,45 @@ static std::string printHash16(const Hash& hash) {
 // omitted: E O U T
 const std::string base32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
 
+constexpr signed char kUnBase32[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, /* unprintables */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* unprintables */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* unprintables */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* unprintables */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* SP..' */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* (../ */
+    0,  1,  2,  3,  4,  5,  6,  7,  /* 0..7 */
+    8,  9,  -1, -1, -1, -1, -1, -1, /* 8..? */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* @..G */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* H..O */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* P..W */
+    -1, -1, -1, -1, -1, -1, -1, -1, /* X.._ */
+    -1, 10, 11, 12, 13, -1, 14, 15, /* `..g */
+    16, 17, 18, 19, 20, 21, 22, -1, /* h..o */
+    23, 24, 25, 26, -1, -1, 27, 28, /* p..w */
+    29, 30, 31, -1, -1, -1, -1, -1, /* x..DEL */
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* high */
+};
+
+bool Hash::IsValidBase32(absl::string_view s) {
+  static_assert(sizeof(kUnBase32) == 256);
+
+  for (char c : s) {
+    if (kUnBase32[static_cast<unsigned char>(c)] == -1) {
+      return false;
+    }
+  }
+  return true;
+}
+
 static std::string printHash32(const Hash& hash) {
   assert(hash.hashSize);
   size_t len = hash.base32Len();
diff --git a/third_party/nix/src/libutil/hash.hh b/third_party/nix/src/libutil/hash.hh
index 34cb41c48784..58f808896fe2 100644
--- a/third_party/nix/src/libutil/hash.hh
+++ b/third_party/nix/src/libutil/hash.hh
@@ -14,8 +14,6 @@ const int sha1HashSize = 20;
 const int sha256HashSize = 32;
 const int sha512HashSize = 64;
 
-extern const std::string base32Chars;
-
 enum Base : int { Base64, Base32, Base16, SRI };
 
 struct Hash {
@@ -65,6 +63,10 @@ struct Hash {
      or base-64. By default, this is prefixed by the hash type
      (e.g. "sha256:"). */
   std::string to_string(Base base = Base32, bool includeType = true) const;
+
+  /* Returns whether the passed string contains entirely valid base32
+     characters. */
+  static bool IsValidBase32(absl::string_view s);
 };
 
 /* Print a hash in base-16 if it's MD5, or base-32 otherwise. */