Skip to content

Commit

Permalink
Add base::AppendHexEncodedByte(), and use hex-encoding APIs more.
Browse files Browse the repository at this point in the history
No behavior change intended; this is merely code cleanup.

Bug: none
Change-Id: Ia3d1ad322fa1f7fdf11e4c8f82669b59701d7438
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4977165
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Owners-Override: Mark Mentovai <mark@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Mark Mentovai <mark@chromium.org>
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1216404}
  • Loading branch information
pkasting authored and Chromium LUCI CQ committed Oct 27, 2023
1 parent 5d655df commit abc2bc3
Show file tree
Hide file tree
Showing 25 changed files with 150 additions and 199 deletions.
12 changes: 4 additions & 8 deletions base/hash/md5_nacl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <stddef.h>

#include "base/hash/md5.h"
#include "base/strings/string_number_conversions.h"

namespace {

Expand Down Expand Up @@ -262,15 +263,10 @@ void MD5Final(MD5Digest* digest, MD5Context* context) {
}

std::string MD5DigestToBase16(const MD5Digest& digest) {
static char const zEncode[] = "0123456789abcdef";

std::string ret;
ret.resize(32);

for (size_t i = 0, j = 0; i < 16; i++, j += 2) {
uint8_t a = digest.a[i];
ret[j] = zEncode[(a >> 4) & 0xf];
ret[j + 1] = zEncode[a & 0xf];
ret.reserve(32);
for (uint8_t byte : digest.a) {
base::AppendHexEncodedByte(byte, ret, false);
}
return ret;
}
Expand Down
11 changes: 2 additions & 9 deletions base/strings/escape.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/features.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
Expand All @@ -19,13 +20,6 @@ namespace base {

namespace {

const char kHexString[] = "0123456789ABCDEF";
inline char IntToHex(int i) {
DCHECK_GE(i, 0) << i << " not a hex value";
DCHECK_LE(i, 15) << i << " not a hex value";
return kHexString[i];
}

// A fast bit-vector map for ascii characters.
//
// Internally stores 256 bits in an array of 8 ints.
Expand Down Expand Up @@ -58,8 +52,7 @@ std::string Escape(StringPiece text,
escaped.push_back('%');
} else if (charmap.Contains(c)) {
escaped.push_back('%');
escaped.push_back(IntToHex(c >> 4));
escaped.push_back(IntToHex(c & 0xf));
AppendHexEncodedByte(c, escaped);
} else {
escaped.push_back(static_cast<char>(c));
}
Expand Down
19 changes: 8 additions & 11 deletions base/strings/string_number_conversions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,20 @@ bool StringToDouble(StringPiece16 input, double* output) {
}

std::string HexEncode(const void* bytes, size_t size) {
static const char kHexChars[] = "0123456789ABCDEF";
return HexEncode(span(reinterpret_cast<const uint8_t*>(bytes), size));
}

std::string HexEncode(span<const uint8_t> bytes) {
// Each input byte creates two output hex characters.
std::string ret(size * 2, '\0');
std::string ret;
ret.reserve(bytes.size() * 2);

for (size_t i = 0; i < size; ++i) {
char b = reinterpret_cast<const char*>(bytes)[i];
ret[(i * 2)] = kHexChars[(b >> 4) & 0xf];
ret[(i * 2) + 1] = kHexChars[b & 0xf];
for (uint8_t byte : bytes) {
AppendHexEncodedByte(byte, ret);
}
return ret;
}

std::string HexEncode(base::span<const uint8_t> bytes) {
return HexEncode(bytes.data(), bytes.size());
}

bool HexStringToInt(StringPiece input, int* output) {
return internal::HexStringToIntImpl(input, *output);
}
Expand Down Expand Up @@ -165,7 +162,7 @@ bool HexStringToString(StringPiece input, std::string* output) {
std::back_inserter(*output));
}

bool HexStringToSpan(StringPiece input, base::span<uint8_t> output) {
bool HexStringToSpan(StringPiece input, span<uint8_t> output) {
if (input.size() / 2 != output.size())
return false;

Expand Down
16 changes: 16 additions & 0 deletions base/strings/string_number_conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ BASE_EXPORT bool StringToDouble(StringPiece16 input, double* output);
BASE_EXPORT std::string HexEncode(const void* bytes, size_t size);
BASE_EXPORT std::string HexEncode(base::span<const uint8_t> bytes);

// Appends a hex representation of `byte`, as two uppercase (by default)
// characters, to `output`. This is a useful primitive in larger conversion
// routines.
inline void AppendHexEncodedByte(uint8_t byte,
std::string& output,
bool uppercase = true) {
static constexpr char kHexCharsUpper[] = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F'};
static constexpr char kHexCharsLower[] = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f'};
const char* const hex_chars = uppercase ? kHexCharsUpper : kHexCharsLower;
output.append({hex_chars[byte >> 4], hex_chars[byte & 0xf]});
}

// Best effort conversion, see StringToInt above for restrictions.
// Will only successful parse hex values that will fit into |output|, i.e.
// -0x80000000 < |input| < 0x7FFFFFFF.
Expand Down
19 changes: 18 additions & 1 deletion base/strings/string_number_conversions_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -919,12 +919,29 @@ TEST(StringNumberConversionsTest, DoubleToString) {
EXPECT_EQ("1.33489033216e+12", NumberToString(input));
}

TEST(StringNumberConversionsTest, AppendHexEncodedByte) {
std::string hex;
AppendHexEncodedByte(0, hex);
AppendHexEncodedByte(0, hex, false);
AppendHexEncodedByte(1, hex);
AppendHexEncodedByte(1, hex, false);
AppendHexEncodedByte(0xf, hex);
AppendHexEncodedByte(0xf, hex, false);
AppendHexEncodedByte(0x8a, hex);
AppendHexEncodedByte(0x8a, hex, false);
AppendHexEncodedByte(0xe0, hex);
AppendHexEncodedByte(0xe0, hex, false);
AppendHexEncodedByte(0xff, hex);
AppendHexEncodedByte(0xff, hex, false);
EXPECT_EQ(hex, "000001010F0f8A8aE0e0FFff");
}

TEST(StringNumberConversionsTest, HexEncode) {
std::string hex(HexEncode(nullptr, 0));
EXPECT_EQ(hex.length(), 0U);
unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
hex = HexEncode(bytes, sizeof(bytes));
EXPECT_EQ(hex.compare("01FF02FE038081"), 0);
EXPECT_EQ(hex, "01FF02FE038081");
}

// Test cases of known-bad strtod conversions that motivated the use of dmg_fp.
Expand Down
16 changes: 7 additions & 9 deletions chrome/browser/devtools/device/adb/adb_client_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ const char kHostTransportCommand[] = "host:transport:%s";
const char kLocalhost[] = "127.0.0.1";

std::string EncodeMessage(const std::string& message) {
static const char kHexChars[] = "0123456789ABCDEF";

size_t length = message.length();
std::string result(4, '\0');
char b = reinterpret_cast<const char*>(&length)[1];
result[0] = kHexChars[(b >> 4) & 0xf];
result[1] = kHexChars[b & 0xf];
b = reinterpret_cast<const char*>(&length)[0];
result[2] = kHexChars[(b >> 4) & 0xf];
result[3] = kHexChars[b & 0xf];
CHECK_LE(length, 0xffffu);
std::string result;
result.reserve(4);
base::AppendHexEncodedByte(reinterpret_cast<const uint8_t*>(&length)[1],
result);
base::AppendHexEncodedByte(reinterpret_cast<const uint8_t*>(&length)[0],
result);
return result + message;
}

Expand Down
9 changes: 4 additions & 5 deletions chrome/browser/devtools/device/adb/mock_adb_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,10 @@ class AdbParser : public SimpleHttpServer::Parser,
buffer = std::string();
}

int size = response.size();
if (size > 0) {
static const char kHexChars[] = "0123456789ABCDEF";
for (int i = 3; i >= 0; i--)
buffer += kHexChars[ (size >> 4*i) & 0x0f ];
if (size_t size = response.size(); size > 0) {
CHECK_LE(size, 0xffffu);
base::AppendHexEncodedByte(static_cast<uint8_t>(size >> 8), buffer);
base::AppendHexEncodedByte(static_cast<uint8_t>(size), buffer);
if (flush_mode_ == FlushWithSize) {
callback_.Run(buffer);
buffer = std::string();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <string_view>

#include "base/json/json_reader.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "third_party/abseil-cpp/absl/strings/ascii.h"

namespace reporting {
Expand Down Expand Up @@ -226,8 +228,7 @@ bool RequestIdMatcher::MatchAndExplain(const base::Value::Dict& arg,
*listener << "Request ID is empty.";
return false;
}
if (request_id->find_first_not_of("0123456789abcdefABCDEF") !=
std::string::npos) {
if (!base::ranges::all_of(*request_id, base::IsHexDigit<char>)) {
*listener << "Request ID is not a hexadecimal number.";
return false;
}
Expand Down
11 changes: 2 additions & 9 deletions chrome/common/net/x509_certificate_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,6 @@ constexpr auto kNameStringHandling =
std::string ProcessRawBytesWithSeparators(base::span<const unsigned char> data,
char hex_separator,
char line_separator) {
static const char kHexChars[] = "0123456789ABCDEF";

// Each input byte creates two output hex characters + a space or newline,
// except for the last byte.
std::string ret;
Expand All @@ -301,14 +299,9 @@ std::string ProcessRawBytesWithSeparators(base::span<const unsigned char> data,
ret.reserve(std::max(kMin, data.size() * 3 - 1));

for (size_t i = 0; i < data.size(); ++i) {
unsigned char b = data[i];
ret.push_back(kHexChars[(b >> 4) & 0xf]);
ret.push_back(kHexChars[b & 0xf]);
base::AppendHexEncodedByte(data[i], ret);
if (i + 1 < data.size()) {
if ((i + 1) % 16 == 0)
ret.push_back(line_separator);
else
ret.push_back(hex_separator);
ret.push_back(((i + 1) % 16) ? hex_separator : line_separator);
}
}
return ret;
Expand Down
16 changes: 7 additions & 9 deletions chrome/test/chromedriver/net/adb_client_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,14 @@ typedef base::RepeatingCallback<void(int, net::StreamSocket*)> SocketCallback;
typedef base::RepeatingCallback<void(const std::string&)> ParserCallback;

std::string EncodeMessage(const std::string& message) {
static const char kHexChars[] = "0123456789ABCDEF";

size_t length = message.length();
std::string result(4, '\0');
char b = reinterpret_cast<const char*>(&length)[1];
result[0] = kHexChars[(b >> 4) & 0xf];
result[1] = kHexChars[b & 0xf];
b = reinterpret_cast<const char*>(&length)[0];
result[2] = kHexChars[(b >> 4) & 0xf];
result[3] = kHexChars[b & 0xf];
CHECK_LE(length, 0xffffu);
std::string result;
result.reserve(4);
base::AppendHexEncodedByte(reinterpret_cast<const uint8_t*>(&length)[1],
result);
base::AppendHexEncodedByte(reinterpret_cast<const uint8_t*>(&length)[0],
result);
return result + message;
}

Expand Down
11 changes: 2 additions & 9 deletions chrome/updater/util/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "base/ranges/algorithm.h"
#include "base/strings/escape.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
Expand Down Expand Up @@ -59,13 +60,6 @@ namespace {

constexpr int64_t kLogRotateAtSize = 1024 * 1024; // 1 MiB.

const char kHexString[] = "0123456789ABCDEF";
inline char IntToHex(int i) {
CHECK_GE(i, 0) << i << " not a hex value";
CHECK_LE(i, 15) << i << " not a hex value";
return kHexString[i];
}

// A fast bit-vector map for ascii characters.
//
// Internally stores 256 bits in an array of 8 ints.
Expand Down Expand Up @@ -104,8 +98,7 @@ std::string Escape(base::StringPiece text,
escaped.push_back('%');
} else if (charmap.Contains(c)) {
escaped.push_back('%');
escaped.push_back(IntToHex(c >> 4));
escaped.push_back(IntToHex(c & 0xf));
base::AppendHexEncodedByte(c, escaped);
} else {
escaped.push_back(c);
}
Expand Down
13 changes: 4 additions & 9 deletions chrome/updater/win/installer/string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

#include <windows.h>

#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"

namespace {

// Returns true if the given two ASCII characters are same (ignoring case).
Expand All @@ -30,16 +33,8 @@ bool HexEncode(const void* bytes, size_t size, wchar_t* str, size_t str_size) {
return false;
}

static const wchar_t kHexChars[] = L"0123456789ABCDEF";

base::ranges::copy(base::HexEncode(bytes, size), str);
str[size * 2] = L'\0';

for (size_t i = 0; i < size; ++i) {
char b = reinterpret_cast<const char*>(bytes)[i];
str[(i * 2)] = kHexChars[(b >> 4) & 0xf];
str[(i * 2) + 1] = kHexChars[b & 0xf];
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

#include "components/reporting/health/health_module_delegate_impl.h"

#include "base/containers/span.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

Expand All @@ -22,20 +24,6 @@ constexpr uint32_t kMaxStorage =
kMaxWriteCount * (kRepeatedPtrFieldSizeOverhead + kDefaultCallSize);
constexpr uint32_t kTinyStorage = 2u;

constexpr char kHexCharLookup[0x10] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
};

std::string BytesToHexString(std::string_view bytes) {
std::string result;
for (char byte : bytes) {
result.push_back(kHexCharLookup[(byte >> 4) & 0xf]);
result.push_back(kHexCharLookup[byte & 0xf]);
}
return result;
}

void CompareHealthData(std::string_view expected, ERPHealthData got) {
EXPECT_THAT(expected, StrEq(got.SerializeAsString()));
}
Expand All @@ -62,7 +50,8 @@ TEST_F(HealthModuleDelegateImplTest, TestInit) {
auto call = AddEnqueueRecordCall();
*ref_data.add_history() = call;
ASSERT_TRUE(AppendLine(temp_dir_.GetPath().AppendASCII(file_name),
BytesToHexString(call.SerializeAsString()))
base::HexEncode(base::as_bytes(
base::make_span(call.SerializeAsString()))))
.ok());

HealthModuleDelegateImpl delegate(temp_dir_.GetPath(), kMaxStorage,
Expand Down

0 comments on commit abc2bc3

Please sign in to comment.