Skip to content

Commit

Permalink
Perl_my_atof3: disallow double signs for Inf/NaN
Browse files Browse the repository at this point in the history
Perl_my_atof3 used to call S_my_atof_infnan after parsing sign character,
but this led Inf/NaN with double signs (e.g. "+-Inf") to be wrongly accepted
because S_my_atof_infnan will also parse sign itself.

Also improved comment per suggestion from @hvds.
  • Loading branch information
t-a-k authored and khwilliamson committed Jul 25, 2021
1 parent 7035863 commit e79f3c0
Showing 1 changed file with 11 additions and 13 deletions.
24 changes: 11 additions & 13 deletions numeric.c
Expand Up @@ -1648,6 +1648,14 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
while (s < send && isSPACE(*s))
++s;

# if defined(NV_INF) || defined(NV_NAN)
{
char* endp;
if ((endp = S_my_atof_infnan(aTHX_ s, FALSE, send, value)))
return endp;
}
# endif

/* sign */
switch (*s) {
case '-':
Expand All @@ -1663,9 +1671,6 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
char* endp;
char* copy = NULL;

if ((endp = S_my_atof_infnan(aTHX_ s, negative, send, value)))
return endp;

/* strtold() accepts 0x-prefixed hex and in POSIX implementations,
0b-prefixed binary numbers, which is backward incompatible
*/
Expand All @@ -1675,8 +1680,9 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
return (char *)s+1;
}

/* strtod will parse a sign (and skip leading whitespaces) by itself,
* so rewind s to the beginning of the string. */
/* We do not want strtod to parse whitespace after the sign, since
* that would give backward-incompatible results. So we rewind and
* let strtod handle the whitespace and sign character itself. */
s = orig;

/* If the length is passed in, the input string isn't NUL-terminated,
Expand Down Expand Up @@ -1737,14 +1743,6 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
/* the max number we can accumulate in a UV, and still safely do 10*N+9 */
#define MAX_ACCUMULATE ( (UV) ((UV_MAX - 9)/10))

#if defined(NV_INF) || defined(NV_NAN)
{
char* endp;
if ((endp = S_my_atof_infnan(aTHX_ s, negative, send, value)))
return endp;
}
#endif

/* we accumulate digits into an integer; when this becomes too
* large, we add the total to NV and start again */

Expand Down

0 comments on commit e79f3c0

Please sign in to comment.