From 05e4e581b58cb64c34965f2dbbc87115d656584a Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 20 Apr 2025 19:44:13 +0200 Subject: [PATCH] Codefix: StringConsumer integer parsing failed for the most negative value, which has no positive equivalent. --- src/core/string_consumer.hpp | 4 ++-- src/tests/string_consumer.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/string_consumer.hpp b/src/core/string_consumer.hpp index e4e9145fa3..6e314d5489 100644 --- a/src/core/string_consumer.hpp +++ b/src/core/string_consumer.hpp @@ -813,10 +813,10 @@ private: /* Try negative hex */ if (std::is_signed_v && (src.starts_with("-0x") || src.starts_with("-0X"))) { - using Unsigned = std::make_signed_t; + using Unsigned = std::make_unsigned_t; auto [len, uvalue] = ParseIntegerBase(src.substr(3), 16, log_errors); if (len == 0) return {}; - T value = -uvalue; + T value = static_cast(0 - uvalue); if (value > 0) { if (log_errors) LogError(fmt::format("Integer out of range: '{}'", src.substr(0, len + 3))); return {}; diff --git a/src/tests/string_consumer.cpp b/src/tests/string_consumer.cpp index 1cf470a0cc..c884cbc7f3 100644 --- a/src/tests/string_consumer.cpp +++ b/src/tests/string_consumer.cpp @@ -485,3 +485,18 @@ TEST_CASE("StringConsumer - invalid int") consumer.SkipIntegerBase(0); CHECK(consumer.ReadUtf8() == 'y'); } + +TEST_CASE("StringConsumer - most negative") +{ + StringConsumer consumer("-80000000 -0x80000000 -2147483648"sv); + CHECK(consumer.PeekIntegerBase(16) == std::pair(0, 0)); + CHECK(consumer.PeekIntegerBase(16) == std::pair(9, 0x80000000)); + consumer.SkipIntegerBase(16); + CHECK(consumer.ReadUtf8() == ' '); + CHECK(consumer.PeekIntegerBase(0) == std::pair(0, 0)); + CHECK(consumer.PeekIntegerBase(0) == std::pair(11, 0x80000000)); + consumer.SkipIntegerBase(0); + CHECK(consumer.ReadUtf8() == ' '); + CHECK(consumer.PeekIntegerBase(10) == std::pair(0, 0)); + CHECK(consumer.PeekIntegerBase(10) == std::pair(11, 0x80000000)); +}