summaryrefslogtreecommitdiff
path: root/ext/standard/math.c
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>2002-10-04 02:21:33 +0000
committerSascha Schumann <sas@php.net>2002-10-04 02:21:33 +0000
commitdf0ea33d2b974cda5e30840c512ddcb19febd9db (patch)
tree2775896f1a1362b094c5ffdf827bd5947305073e /ext/standard/math.c
parentcfaffd2185f8723d7251c51e335f6e5bb3a0ff54 (diff)
downloadphp-git-df0ea33d2b974cda5e30840c512ddcb19febd9db.tar.gz
peek at freebsd's libc and fix _php_math_basetozval
PR: #19733
Diffstat (limited to 'ext/standard/math.c')
-rw-r--r--ext/standard/math.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/ext/standard/math.c b/ext/standard/math.c
index 2368da4aa6..abc5fc9098 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -670,11 +670,13 @@ _php_math_basetolong(zval *arg, int base) {
*/
PHPAPI int
_php_math_basetozval(zval *arg, int base, zval *ret) {
- long num = 0, digit, onum;
+ long num = 0;
double fnum;
int i;
int mode = 0;
char c, *s;
+ unsigned long cutoff;
+ int cutlim;
if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) {
return FAILURE;
@@ -682,30 +684,37 @@ _php_math_basetozval(zval *arg, int base, zval *ret) {
s = Z_STRVAL_P(arg);
+ cutoff = LONG_MAX / base;
+ cutlim = LONG_MAX % base;
+
for (i = Z_STRLEN_P(arg); i > 0; i--) {
c = *s++;
- digit = (c >= '0' && c <= '9') ? c - '0'
- : (c >= 'A' && c <= 'Z') ? c - 'A' + 10
- : (c >= 'a' && c <= 'z') ? c - 'a' + 10
- : base;
+ /* might not work for EBCDIC */
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ continue;
- if (digit >= base)
+ if (c >= base)
continue;
switch (mode) {
case 0: /* Integer */
- onum = num;
- num = num * base + digit;
-
- if (num > onum)
- break; /* No overflow, continue */
-
- fnum = onum;
- mode = 1;
+ if (num < cutoff || (num == cutoff && c <= cutlim)) {
+ num = num * base + c;
+ break;
+ } else {
+ fnum = num;
+ mode = 1;
+ }
/* fall-through */
case 1: /* Float */
- fnum = fnum * base + digit;
+ fnum = fnum * base + c;
}
}