1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 05:47:34 +00:00

LibC: Use 'long long' specialisations of scanf's read_element_concrete

...for 'long long' and 'unsigned long long', instead of reading them as
'long's and 'unsigned long's.
Also add a test for values that can only fit in (unsigned) long long.
Fixes #6096.
This commit is contained in:
AnotherTest 2021-04-04 03:01:43 +04:30 committed by Andreas Kling
parent f05cca7a9a
commit 143c68755b
2 changed files with 44 additions and 4 deletions

View file

@ -163,6 +163,40 @@ struct read_element_concrete<unsigned, ApT, kind> {
}
};
template<typename ApT, ReadKind kind>
struct read_element_concrete<long long, ApT, kind> {
bool operator()(GenericLexer& lexer, va_list* ap)
{
lexer.ignore_while(isspace);
auto* ptr = va_arg(*ap, ApT*);
long long value = 0;
char* endptr = nullptr;
auto nptr = lexer.remaining().characters_without_null_termination();
if constexpr (kind == ReadKind::Normal)
value = strtoll(nptr, &endptr, 10);
if constexpr (kind == ReadKind::Octal)
value = strtoll(nptr, &endptr, 8);
if constexpr (kind == ReadKind::Hex)
value = strtoll(nptr, &endptr, 16);
if constexpr (kind == ReadKind::Infer)
value = strtoll(nptr, &endptr, 0);
if (!endptr)
return false;
if (endptr == nptr)
return false;
auto diff = endptr - nptr;
VERIFY(diff > 0);
lexer.ignore((size_t)diff);
*ptr = value;
return true;
}
};
template<typename ApT, ReadKind kind>
struct read_element_concrete<unsigned long long, ApT, kind> {
bool operator()(GenericLexer& lexer, va_list* ap)
@ -248,15 +282,15 @@ struct read_element {
if constexpr (IsSame<T, unsigned>::value)
return read_element_concrete<T, unsigned, kind> {}(input_lexer, ap);
if constexpr (IsSame<T, float>::value)
return read_element_concrete<T, double, kind> {}(input_lexer, ap);
return read_element_concrete<int, double, kind> {}(input_lexer, ap);
return false;
case LongLong:
if constexpr (IsSame<T, int>::value)
return read_element_concrete<T, long long, kind> {}(input_lexer, ap);
return read_element_concrete<long long, long long, kind> {}(input_lexer, ap);
if constexpr (IsSame<T, unsigned>::value)
return read_element_concrete<T, unsigned long long, kind> {}(input_lexer, ap);
return read_element_concrete<unsigned long long, unsigned long long, kind> {}(input_lexer, ap);
if constexpr (IsSame<T, float>::value)
return read_element_concrete<T, double, kind> {}(input_lexer, ap);
return read_element_concrete<long long, double, kind> {}(input_lexer, ap);
return false;
case IntMax:
return read_element_concrete<T, intmax_t, kind> {}(input_lexer, ap);