1
0
Fork 0

Codefix: StringConsumer integer parsing failed for the most negative value, which has no positive equivalent.

pull/14048/head
frosch 2025-04-20 19:44:13 +02:00
parent 26de3404a4
commit 05e4e581b5
2 changed files with 17 additions and 2 deletions

View File

@ -813,10 +813,10 @@ private:
/* Try negative hex */
if (std::is_signed_v<T> && (src.starts_with("-0x") || src.starts_with("-0X"))) {
using Unsigned = std::make_signed_t<T>;
using Unsigned = std::make_unsigned_t<T>;
auto [len, uvalue] = ParseIntegerBase<Unsigned>(src.substr(3), 16, log_errors);
if (len == 0) return {};
T value = -uvalue;
T value = static_cast<T>(0 - uvalue);
if (value > 0) {
if (log_errors) LogError(fmt::format("Integer out of range: '{}'", src.substr(0, len + 3)));
return {};

View File

@ -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<uint32_t>(16) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
CHECK(consumer.PeekIntegerBase<int32_t>(16) == std::pair<StringConsumer::size_type, int32_t>(9, 0x80000000));
consumer.SkipIntegerBase(16);
CHECK(consumer.ReadUtf8() == ' ');
CHECK(consumer.PeekIntegerBase<uint32_t>(0) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
CHECK(consumer.PeekIntegerBase<int32_t>(0) == std::pair<StringConsumer::size_type, int32_t>(11, 0x80000000));
consumer.SkipIntegerBase(0);
CHECK(consumer.ReadUtf8() == ' ');
CHECK(consumer.PeekIntegerBase<uint32_t>(10) == std::pair<StringConsumer::size_type, uint32_t>(0, 0));
CHECK(consumer.PeekIntegerBase<int32_t>(10) == std::pair<StringConsumer::size_type, int32_t>(11, 0x80000000));
}