mirror of https://github.com/OpenTTD/OpenTTD
Codefix: StringConsumer integer parsing failed for the most negative value, which has no positive equivalent.
parent
26de3404a4
commit
05e4e581b5
|
@ -813,10 +813,10 @@ private:
|
||||||
|
|
||||||
/* Try negative hex */
|
/* Try negative hex */
|
||||||
if (std::is_signed_v<T> && (src.starts_with("-0x") || src.starts_with("-0X"))) {
|
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);
|
auto [len, uvalue] = ParseIntegerBase<Unsigned>(src.substr(3), 16, log_errors);
|
||||||
if (len == 0) return {};
|
if (len == 0) return {};
|
||||||
T value = -uvalue;
|
T value = static_cast<T>(0 - uvalue);
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
if (log_errors) LogError(fmt::format("Integer out of range: '{}'", src.substr(0, len + 3)));
|
if (log_errors) LogError(fmt::format("Integer out of range: '{}'", src.substr(0, len + 3)));
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -485,3 +485,18 @@ TEST_CASE("StringConsumer - invalid int")
|
||||||
consumer.SkipIntegerBase(0);
|
consumer.SkipIntegerBase(0);
|
||||||
CHECK(consumer.ReadUtf8() == 'y');
|
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));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue