summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorTAKAI Kousuke <62541129+t-a-k@users.noreply.github.com>2021-02-19 01:11:13 +0900
committerKarl Williamson <khw@cpan.org>2021-07-25 05:57:43 -0700
commit7035863f5fa4306e58c8157b2a5893ba5e0f1eaf (patch)
tree302631d6743ad1679b047b680df0f5ca97007594 /numeric.c
parentd44f69e7cc06ab513c9a2784013a0a8f91003726 (diff)
downloadperl-7035863f5fa4306e58c8157b2a5893ba5e0f1eaf.tar.gz
Perl_my_atof3: disallow double signs and spaces between a sign and number
Perl_my_atof3 used to pass a substring after the first (optional) sign to (S_)strtod, which causes wrong numifications for strings like "-+3" or "+ 0x123" (for the latter case, while Perl_my_atof3 already had the code to block "0x" prefixes, this string will slip through due to the space character in it). For GH #18584.
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/numeric.c b/numeric.c
index 72130dd9f5..76f7395d58 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1675,6 +1675,10 @@ 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. */
+ s = orig;
+
/* If the length is passed in, the input string isn't NUL-terminated,
* and in it turns out the function below assumes it is; therefore we
* create a copy and NUL-terminate that */
@@ -1682,7 +1686,7 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
Newx(copy, len + 1, char);
Copy(orig, copy, len, char);
copy[len] = '\0';
- s = copy + (s - orig);
+ s = copy;
}
result[2] = S_strtod(aTHX_ s, &endp);
@@ -1696,7 +1700,8 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
}
if (s != endp) {
- *value = negative ? -result[2] : result[2];
+ /* Note that negation is handled by strtod. */
+ *value = result[2];
return endp;
}
return NULL;