This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit d8a856cf47dc7b9c97eafc4424700eb17ecefae9
Author: Chris McFarlen <[email protected]>
AuthorDate: Tue Jun 11 12:50:44 2024 -0500

    support full range of unsigned char for hex conversion.   (#11429)
    
    * support full range of unsigned char for hex conversion.  Install 
StringConvert.h
    
    * test round trip for unsigned strings
    
    * interpret as unsigned char to avoid out of range
    
    (cherry picked from commit 348aedf77c2c19a3a2269c13aceced4d4f53e512)
---
 include/tsutil/StringConvert.h              | 12 ++++++++----
 src/tsutil/CMakeLists.txt                   |  1 +
 src/tsutil/unit_tests/test_StringConvert.cc | 12 ++++++++++++
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/include/tsutil/StringConvert.h b/include/tsutil/StringConvert.h
index 3465b5c7da..a4339aeeb7 100644
--- a/include/tsutil/StringConvert.h
+++ b/include/tsutil/StringConvert.h
@@ -44,9 +44,13 @@ hex(const std::string_view input)
 
   result.resize(input.size() * 2);
 
-  char *p = result.data();
-  for (auto x : input) {
-    if (auto [ptr, err] = std::to_chars(p, result.data() + result.size(), x, 
16); err == std::errc()) {
+  char *p   = result.data();
+  char *end = result.data() + result.size();
+  for (unsigned char x : input) {
+    if (x < 0x10) {
+      *p++ = '0';
+    }
+    if (auto [ptr, err] = std::to_chars(p, end, x, 16); err == std::errc()) {
       p = ptr;
     } else {
       throw std::runtime_error(std::make_error_code(err).message().c_str());
@@ -80,7 +84,7 @@ unhex(const std::string_view input)
 
   const char *p = input.data();
   for (auto &x : result) {
-    if (auto [ptr, err] = std::from_chars(p, p + 2, x, 16); err == 
std::errc()) {
+    if (auto [ptr, err] = std::from_chars(p, p + 2, reinterpret_cast<unsigned 
char &>(x), 16); err == std::errc()) {
       p = ptr;
     } else {
       throw std::runtime_error(std::make_error_code(err).message().c_str());
diff --git a/src/tsutil/CMakeLists.txt b/src/tsutil/CMakeLists.txt
index d018301f0c..dadf7564bd 100644
--- a/src/tsutil/CMakeLists.txt
+++ b/src/tsutil/CMakeLists.txt
@@ -30,6 +30,7 @@ set(TSUTIL_PUBLIC_HEADERS
     ${PROJECT_SOURCE_DIR}/include/tsutil/LocalBuffer.h
     ${PROJECT_SOURCE_DIR}/include/tsutil/PostScript.h
     ${PROJECT_SOURCE_DIR}/include/tsutil/Strerror.h
+    ${PROJECT_SOURCE_DIR}/include/tsutil/StringConvert.h
     ${PROJECT_SOURCE_DIR}/include/tsutil/Regex.h
     ${PROJECT_SOURCE_DIR}/include/tsutil/TsSharedMutex.h
     ${PROJECT_SOURCE_DIR}/include/tsutil/YamlCfg.h
diff --git a/src/tsutil/unit_tests/test_StringConvert.cc 
b/src/tsutil/unit_tests/test_StringConvert.cc
index 06f708b513..2ee1bba5ae 100644
--- a/src/tsutil/unit_tests/test_StringConvert.cc
+++ b/src/tsutil/unit_tests/test_StringConvert.cc
@@ -25,9 +25,21 @@
 
 #include <tsutil/StringConvert.h>
 
+std::string
+mkunsigned_string()
+{
+  const char data[] = {static_cast<char>(0xab), static_cast<char>(0x9e), 
static_cast<char>(0xff), 0x12, 0x04};
+
+  return std::string(data, 5);
+}
+
 TEST_CASE("StringConvert", "[STE]")
 {
   REQUIRE(ts::hex("01") == "3031");
   REQUIRE(ts::unhex("3031") == "01");
   REQUIRE(ts::hex("5pn2QM") == "35706e32514d");
+
+  auto usgn = mkunsigned_string();
+  REQUIRE(ts::hex(usgn) == "ab9eff1204");
+  REQUIRE(ts::unhex(ts::hex(usgn)) == usgn);
 }

Reply via email to