Fix C++17 implementation of wxString::ToCULong()
Do use std::from_chars<unsigned long>() in it as otherwise values greater than LONG_MAX failed to parse. Handle negative numbers explicitly to still parse them in this function as well, as needs to be done for compatibility. Add a test case for the previously failing numbers. Closes #23957.
This commit is contained in:
parent
9a620bf920
commit
8d6a722ed8
2 changed files with 34 additions and 9 deletions
|
|
@ -1633,20 +1633,34 @@ bool wxString::ToCLong(long *pVal, int base) const
|
|||
|
||||
bool wxString::ToCULong(unsigned long *pVal, int base) const
|
||||
{
|
||||
// We intentionally don't use std::from_chars() here because this function
|
||||
// is supposed to be compatible with strtoul() and so _succeed_ for "-1",
|
||||
// for example, instead of returning an error as from_chars() (much more
|
||||
// logically) does.
|
||||
|
||||
wxCHECK_MSG( pVal, false, "null output pointer" );
|
||||
|
||||
long l;
|
||||
if ( !ToCLong(&l, base) )
|
||||
const wxScopedCharBuffer& buf = utf8_str();
|
||||
auto start = buf.data();
|
||||
const auto end = start + buf.length();
|
||||
|
||||
if ( !SetBaseAndSkipPrefix(base, start, end) )
|
||||
return false;
|
||||
|
||||
*pVal = static_cast<unsigned long>(l);
|
||||
// Extra complication: for compatibility reasons, this function does accept
|
||||
// "-1" as valid input (as strtoul() does!), but from_chars() doesn't, for
|
||||
// unsigned values, so check for this separately.
|
||||
if ( *start == '-' )
|
||||
{
|
||||
long l;
|
||||
const auto res = std::from_chars(start, end, l, base);
|
||||
|
||||
return true;
|
||||
if ( res.ec != std::errc{} || res.ptr != end )
|
||||
return false;
|
||||
|
||||
*pVal = static_cast<unsigned long>(l);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto res = std::from_chars(start, end, *pVal, base);
|
||||
|
||||
return res.ec == std::errc{} && res.ptr == end;
|
||||
}
|
||||
|
||||
bool wxString::ToCDouble(double *pVal) const
|
||||
|
|
|
|||
|
|
@ -607,6 +607,17 @@ static const struct ToLongData
|
|||
{ wxT("0x11"), 17, Number_Ok, 0 },
|
||||
{ wxT("0x11"), 0, Number_Invalid, 8 },
|
||||
{ wxT("0x11"), 17, Number_Ok, 16 },
|
||||
|
||||
{
|
||||
#if SIZEOF_LONG == 4
|
||||
wxT("0xffffffff"),
|
||||
#elif SIZEOF_LONG == 8
|
||||
wxT("0xffffffffffffffff"),
|
||||
#else
|
||||
#error "Unknown sizeof(long)"
|
||||
#endif
|
||||
(TestValue_t)ULONG_MAX, Number_Unsigned, 0
|
||||
},
|
||||
};
|
||||
|
||||
wxGCC_WARNING_RESTORE(missing-field-initializers)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue