diff options
author | Derek Mauro <dmauro@google.com> | 2024-02-05 18:31:36 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-02-05 18:32:37 -0800 |
commit | 0e289dc594da4b30eb03cb7cb2aa097f5d5f6eb5 (patch) | |
tree | cbdd9e5f0b6a31d006a960bf1799afd325dfd73c /absl/strings/escaping.cc | |
parent | ddcf8be90575d494e40fcd4e0c408f0237efe0da (diff) |
Add a version of absl::HexStringToBytes() that returns a bool
to validate that the input was actually valid hexadecimal data.
Mark the version of absl::HexStringToBytes() that does not validate
the input as deprecated.
Fixes #141
PiperOrigin-RevId: 604495678
Change-Id: Iac3020c33c9dbc6d8e31a43b746783fb345edaa7
Diffstat (limited to 'absl/strings/escaping.cc')
-rw-r--r-- | absl/strings/escaping.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 5de12afa..bb58f99b 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -837,6 +837,24 @@ constexpr char kHexValueLenient[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +constexpr signed char kHexValueStrict[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // '0'..'9' + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 'A'..'F' + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 'a'..'f' + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; /* clang-format on */ // This is a templated function so that T can be either a char* @@ -931,6 +949,30 @@ std::string WebSafeBase64Escape(absl::string_view src) { return dest; } +bool HexStringToBytes(absl::string_view hex, + absl::Nonnull<std::string*> bytes) { + size_t num_bytes = hex.size() / 2; + bytes->clear(); + if (hex.size() != num_bytes * 2) { + return false; + } + + absl::strings_internal::STLStringResizeUninitialized(bytes, num_bytes); + auto hex_p = hex.cbegin(); + for (std::string::iterator bin_p = bytes->begin(); + bin_p != bytes->end(); ++bin_p) { + int h1 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)]; + int h2 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)]; + if (h1 == -1 || h2 == -1) { + bytes->resize(static_cast<size_t>(bin_p - bytes->begin())); + return false; + } + *bin_p = static_cast<char>((h1 << 4) + h2); + } + + return true; +} + std::string HexStringToBytes(absl::string_view from) { std::string result; const auto num = from.size() / 2; |