From 884086ba763a8794a00ef5cd4c2a86c064ce8394 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 24 May 2023 19:34:04 +1000 Subject: [PATCH] StringUtil: Fix incorrect value of endptr And add associated unit tests. --- common/StringUtil.h | 10 ++----- tests/ctest/common/string_util_tests.cpp | 33 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/common/StringUtil.h b/common/StringUtil.h index e0195b2c10..4b93490617 100644 --- a/common/StringUtil.h +++ b/common/StringUtil.h @@ -100,10 +100,7 @@ namespace StringUtil return std::nullopt; if (endptr) - { - const size_t remaining_len = end - ptr - 1; - *endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view(); - } + *endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view(); return value; } @@ -131,10 +128,7 @@ namespace StringUtil return std::nullopt; if (endptr) - { - const size_t remaining_len = end - ptr - 1; - *endptr = (remaining_len > 0) ? std::string_view(result.ptr, remaining_len) : std::string_view(); - } + *endptr = (result.ptr < end) ? std::string_view(result.ptr, end - result.ptr) : std::string_view(); return value; } diff --git a/tests/ctest/common/string_util_tests.cpp b/tests/ctest/common/string_util_tests.cpp index b7b788772b..6bc40a535f 100644 --- a/tests/ctest/common/string_util_tests.cpp +++ b/tests/ctest/common/string_util_tests.cpp @@ -43,6 +43,39 @@ TEST(StringUtil, FromChars) ASSERT_EQ(StringUtil::FromChars("ff", 16).value_or(0), 255); } +TEST(StringUtil, FromCharsWithEndPtr) +{ + using namespace std::literals; + + std::string_view endptr; + ASSERT_EQ(StringUtil::FromChars("123x456", 16, &endptr), std::optional(0x123)); + ASSERT_EQ(endptr, "x456"sv); + + ASSERT_EQ(StringUtil::FromChars("0x1234", 16, &endptr), std::optional(0u)); + ASSERT_EQ(endptr, "x1234"sv); + + ASSERT_EQ(StringUtil::FromChars("1234", 16, &endptr), std::optional(0x1234u)); + ASSERT_TRUE(endptr.empty()); + + ASSERT_EQ(StringUtil::FromChars("abcdefg", 16, &endptr), std::optional(0xabcdef)); + ASSERT_EQ(endptr, "g"sv); + + ASSERT_EQ(StringUtil::FromChars("123abc", 10, &endptr), std::optional(123)); + ASSERT_EQ(endptr, "abc"sv); + + ASSERT_EQ(StringUtil::FromChars("1.0g", &endptr), std::optional(1.0f)); + ASSERT_EQ(endptr, "g"sv); + + ASSERT_EQ(StringUtil::FromChars("2x", &endptr), std::optional(2.0f)); + ASSERT_EQ(endptr, "x"sv); + + ASSERT_EQ(StringUtil::FromChars(".1p", &endptr), std::optional(0.1f)); + ASSERT_EQ(endptr, "p"sv); + + ASSERT_EQ(StringUtil::FromChars("1", &endptr), std::optional(1.0f)); + ASSERT_TRUE(endptr.empty()); +} + #if 0 // NOTE: These tests are disabled, because they require the da_DK locale to actually be present. // Which probably isn't going to be the case on the CI.