diff options
Diffstat (limited to 'ext/standard/math.c')
| -rw-r--r-- | ext/standard/math.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/ext/standard/math.c b/ext/standard/math.c index ddee343b1d..ba7e3944aa 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -850,22 +850,33 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) { zend_long num = 0; double fnum = 0; - zend_long i; int mode = 0; - char c, *s; + char c, *s, *e; zend_long cutoff; int cutlim; + int invalidchars = 0; if (Z_TYPE_P(arg) != IS_STRING || base < 2 || base > 36) { return FAILURE; } - s = Z_STRVAL_P(arg); + e = s + Z_STRLEN_P(arg); + + /* Skip leading whitespace */ + while (s < e && isspace(*s)) s++; + /* Skip trailing whitespace */ + while (s < e && isspace(*(e-1))) e--; + + if (e - s >= 2) { + if (base == 16 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s += 2; + if (base == 8 && s[0] == '0' && (s[1] == 'o' || s[1] == 'O')) s += 2; + if (base == 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B')) s += 2; + } cutoff = ZEND_LONG_MAX / base; cutlim = ZEND_LONG_MAX % base; - for (i = Z_STRLEN_P(arg); i > 0; i--) { + while (s < e) { c = *s++; /* might not work for EBCDIC */ @@ -875,11 +886,15 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; - else + else { + invalidchars++; continue; + } - if (c >= base) + if (c >= base) { + invalidchars++; continue; + } switch (mode) { case 0: /* Integer */ @@ -896,6 +911,10 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) } } + if (invalidchars > 0) { + zend_error(E_DEPRECATED, "Invalid characters passed for attempted conversion, these have been ignored"); + } + if (mode == 1) { ZVAL_DOUBLE(ret, fnum); } else { |
