[PATCH] msvcrt: Fix strtof() error reporting for values out of float range

Martin Storsjö martin at martin.st
Wed Jul 28 09:42:44 CDT 2021


On Wed, 28 Jul 2021, Piotr Caban wrote:

> Hi Martin,
>
> On 7/28/21 12:44 AM, Martin Storsjo wrote:
>>   float CDECL _strtof_l( const char *str, char **end, _locale_t locale )
>>   {
>> -    return _strtod_l(str, end, locale);
>> +    double ret = _strtod_l(str, end, locale);
>> +    if (isfinite(ret)) {
>> +        /* Check for cases that aren't out of range for doubles, but that 
>> are
>> +         * for floats. */
>> +        if (ret > FLT_MAX)
>> +            *_errno() = ERANGE;
>> +        else if (ret < -FLT_MAX)
>> +            *_errno() = ERANGE;
>> +        else if (ret > 0 && ret < FLT_MIN)
>> +            *_errno() = ERANGE;
>> +        else if (ret < 0 && ret > -FLT_MIN)
>> +            *_errno() = ERANGE;
>> +    }
>> +    return ret;
> It doesn't work for denormals (e.g. for "1.4e-45" input string).

Hmm, right... When I studied this aspect for mingw-w64, I noted that 
different CRTs seem to differ in what they do for denormals in 
strtod/strtof; some set ERANGE, some don't. But you're right that ucrtbase 
doesn't seem to set it for these denormals, so we shouldn't either.

> Maybe something along this lines will work better:
> if (ret && isfinite(ret)) {
>    float f = ret;
>    if (!f || !isfinite(f))
>        *_errno() = ERANGE;
> }

Thanks! That does seem to work. I'll amend the patch to include testcases 
for 0 too, in addition to denormals.

// Martin




More information about the wine-devel mailing list