summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorTAKAI Kousuke <62541129+t-a-k@users.noreply.github.com>2021-02-23 01:11:59 +0900
committerKarl Williamson <khw@cpan.org>2021-07-25 05:57:43 -0700
commite79f3c064561c5843af40cda89f98bb44f956729 (patch)
tree8ae45db646010195a1a25c2446fc5b55d10bb40e /numeric.c
parent7035863f5fa4306e58c8157b2a5893ba5e0f1eaf (diff)
downloadperl-e79f3c064561c5843af40cda89f98bb44f956729.tar.gz
Perl_my_atof3: disallow double signs for Inf/NaN
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.
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/numeric.c b/numeric.c
index 76f7395d58..d2f4165f1d 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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 '-':
@@ -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
*/
@@ -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,
@@ -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 */