aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2024-03-28 20:40:17 -0700
committerCopybara-Service <copybara-worker@google.com>2024-03-28 20:41:28 -0700
commit770d078368f66da606ad98187f33fbc5b8cdd3ae (patch)
treec351f13972bcdaa68975a39e4a3e56351b282945
parent00f8c3996718913e40aa2699cba1489df1760450 (diff)
downloadabseil-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.cc13
-rw-r--r--absl/strings/escaping_test.cc7
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));