msvcrt: Fix strtof() error reporting for values out of float range.

If the values weren't out of range for the internal strtod() call,
we still must mark them as out of range when returning as float.

Signed-off-by: Martin Storsjo <martin@martin.st>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Martin Storsjo 2021-07-28 17:43:19 +03:00 committed by Alexandre Julliard
parent 868c9ee7c9
commit 057ecd41cc
3 changed files with 51 additions and 2 deletions

View File

@ -1065,7 +1065,13 @@ double CDECL strtod( const char *str, char **end )
*/ */
float CDECL _strtof_l( const char *str, char **end, _locale_t locale ) 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 (ret && isfinite(ret)) {
float f = ret;
if (!f || !isfinite(f))
*_errno() = ERANGE;
}
return ret;
} }
/********************************************************************* /*********************************************************************

View File

@ -798,7 +798,13 @@ double CDECL _wtof_l(const wchar_t *str, _locale_t locale)
*/ */
float CDECL _wcstof_l( const wchar_t *str, wchar_t **end, _locale_t locale ) float CDECL _wcstof_l( const wchar_t *str, wchar_t **end, _locale_t locale )
{ {
return _wcstod_l(str, end, locale); double ret = _wcstod_l(str, end, locale);
if (ret && isfinite(ret)) {
float f = ret;
if (!f || !isfinite(f))
*_errno() = ERANGE;
}
return ret;
} }
/********************************************************************* /*********************************************************************

View File

@ -152,6 +152,42 @@ static void test_strtod(void)
test_strtod_str_errno("2.47e-324", 0, 9, ERANGE); test_strtod_str_errno("2.47e-324", 0, 9, ERANGE);
} }
static void test_strtof(void)
{
static const struct {
const char *str;
int len;
float ret;
int err;
} tests[] = {
{ "12.1", 4, 12.1f },
{ "-13.721", 7, -13.721f },
{ "1.e40", 5, INFINITY, ERANGE },
{ "-1.e40", 6, -INFINITY, ERANGE },
{ "0.0", 3, 0.0f },
{ "-0.0", 4, 0.0f },
{ "1.4e-45", 7, 1.4e-45f },
{ "-1.4e-45", 8, -1.4e-45f },
{ "1.e-60", 6, 0, ERANGE },
{ "-1.e-60", 7, 0, ERANGE },
};
char *end;
float f;
int i;
for (i=0; i<ARRAY_SIZE(tests); i++)
{
errno = 0xdeadbeef;
f = strtof(tests[i].str, &end);
ok(f == tests[i].ret, "%d) f = %.16e\n", i, f);
ok(end == tests[i].str + tests[i].len, "%d) len = %d\n",
i, (int)(end - tests[i].str));
ok(errno == tests[i].err || (!tests[i].err && errno == 0xdeadbeef),
"%d) errno = %d\n", i, errno);
}
}
static void test__memicmp(void) static void test__memicmp(void)
{ {
static const char *s1 = "abc"; static const char *s1 = "abc";
@ -558,6 +594,7 @@ START_TEST(string)
"Invalid parameter handler was already set\n"); "Invalid parameter handler was already set\n");
test_strtod(); test_strtod();
test_strtof();
test__memicmp(); test__memicmp();
test__memicmp_l(); test__memicmp_l();
test___strncnt(); test___strncnt();