summaryrefslogtreecommitdiff
path: root/absl/strings/escaping.cc
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2024-02-05 18:31:36 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2024-02-05 18:32:37 -0800
commit0e289dc594da4b30eb03cb7cb2aa097f5d5f6eb5 (patch)
treecbdd9e5f0b6a31d006a960bf1799afd325dfd73c /absl/strings/escaping.cc
parentddcf8be90575d494e40fcd4e0c408f0237efe0da (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.cc42
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;