Commit 770d0783 by Abseil Team Committed by Copybara-Service

Use local decoding buffer in HexStringToBytes

PiperOrigin-RevId: 620141661
Change-Id: I9dc9243b1d227f7cf32319bc1fec94aba850d4c1
parent 00f8c399
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <cstring> #include <cstring>
#include <limits> #include <limits>
#include <string> #include <string>
#include <utility>
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/raw_logging.h"
...@@ -969,25 +970,27 @@ std::string WebSafeBase64Escape(absl::string_view src) { ...@@ -969,25 +970,27 @@ std::string WebSafeBase64Escape(absl::string_view src) {
bool HexStringToBytes(absl::string_view hex, bool HexStringToBytes(absl::string_view hex,
absl::Nonnull<std::string*> bytes) { absl::Nonnull<std::string*> bytes) {
std::string output;
size_t num_bytes = hex.size() / 2; size_t num_bytes = hex.size() / 2;
bytes->clear();
if (hex.size() != num_bytes * 2) { if (hex.size() != num_bytes * 2) {
return false; return false;
} }
absl::strings_internal::STLStringResizeUninitialized(bytes, num_bytes); absl::strings_internal::STLStringResizeUninitialized(&output, num_bytes);
auto hex_p = hex.cbegin(); auto hex_p = hex.cbegin();
for (std::string::iterator bin_p = bytes->begin(); for (std::string::iterator bin_p = output.begin(); bin_p != output.end();
bin_p != bytes->end(); ++bin_p) { ++bin_p) {
int h1 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)]; int h1 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)];
int h2 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)]; int h2 = absl::kHexValueStrict[static_cast<size_t>(*hex_p++)];
if (h1 == -1 || h2 == -1) { 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; return false;
} }
*bin_p = static_cast<char>((h1 << 4) + h2); *bin_p = static_cast<char>((h1 << 4) + h2);
} }
*bytes = std::move(output);
return true; return true;
} }
......
...@@ -706,6 +706,13 @@ TEST(Escaping, HexStringToBytesBackToHex) { ...@@ -706,6 +706,13 @@ TEST(Escaping, HexStringToBytesBackToHex) {
hex = absl::BytesToHexString(kTestBytes); hex = absl::BytesToHexString(kTestBytes);
EXPECT_EQ(hex, kTestHexLower); 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. // Length not a multiple of two.
EXPECT_FALSE(absl::HexStringToBytes("1c2f003", &bytes)); EXPECT_FALSE(absl::HexStringToBytes("1c2f003", &bytes));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment