summaryrefslogtreecommitdiff
path: root/ext/standard/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/math.c')
-rw-r--r--ext/standard/math.c31
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 {