diff options
author | Abseil Team <absl-team@google.com> | 2024-03-28 20:40:17 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-03-28 20:41:28 -0700 |
commit | 770d078368f66da606ad98187f33fbc5b8cdd3ae (patch) | |
tree | c351f13972bcdaa68975a39e4a3e56351b282945 | |
parent | 00f8c3996718913e40aa2699cba1489df1760450 (diff) | |
download | abseil-770d078368f66da606ad98187f33fbc5b8cdd3ae.tar.gz abseil-770d078368f66da606ad98187f33fbc5b8cdd3ae.tar.bz2 abseil-770d078368f66da606ad98187f33fbc5b8cdd3ae.zip |
Use local decoding buffer in HexStringToBytes
PiperOrigin-RevId: 620141661
Change-Id: I9dc9243b1d227f7cf32319bc1fec94aba850d4c1
-rw-r--r-- | absl/strings/escaping.cc | 13 | ||||
-rw-r--r-- | absl/strings/escaping_test.cc | 7 |
2 files changed, 15 insertions, 5 deletions
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index af50faeb..4ffef94b 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -21,6 +21,7 @@ #include <cstring> #include <limits> #include <string> +#include <utility> #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" @@ -969,25 +970,27 @@ std::string WebSafeBase64Escape(absl::string_view src) { bool HexStringToBytes(absl::string_view hex, absl::Nonnull<std::string*> bytes) { + std::string output; + size_t num_bytes = hex.size() / 2; - bytes->clear(); if (hex.size() != num_bytes * 2) { return false; } - absl::strings_internal::STLStringResizeUninitialized(bytes, num_bytes); + absl::strings_internal::STLStringResizeUninitialized(&output, num_bytes); auto hex_p = hex.cbegin(); - for (std::string::iterator bin_p = bytes->begin(); - bin_p != bytes->end(); ++bin_p) { + for (std::string::iterator bin_p = output.begin(); bin_p != output.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())); + output.resize(static_cast<size_t>(bin_p - output.begin())); return false; } *bin_p = static_cast<char>((h1 << 4) + h2); } + *bytes = std::move(output); return true; } diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc index ae3466a7..25cb685b 100644 --- a/absl/strings/escaping_test.cc +++ b/absl/strings/escaping_test.cc @@ -706,6 +706,13 @@ TEST(Escaping, HexStringToBytesBackToHex) { hex = absl::BytesToHexString(kTestBytes); EXPECT_EQ(hex, kTestHexLower); + // Same buffer. + // We do not care if this works since we do not promise it in the contract. + // The purpose of this test is to to see if the program will crash or if + // sanitizers will catch anything. + bytes = std::string(kTestHexUpper); + (void)absl::HexStringToBytes(bytes, &bytes); + // Length not a multiple of two. EXPECT_FALSE(absl::HexStringToBytes("1c2f003", &bytes)); |