summaryrefslogtreecommitdiff
path: root/ext/standard/type.c
diff options
context:
space:
mode:
authorLeigh <leigh@php.net>2016-10-31 16:25:33 +0000
committerNikita Popov <nikic@php.net>2017-01-12 18:53:28 +0100
commit4f7b498d12b04ae25ae59a711e76410e77455a94 (patch)
treef53448525d23084297d2bc2ba5761d86b5ccf4c2 /ext/standard/type.c
parente65760f878a116d7ffc858c5a0e30f6075230443 (diff)
downloadphp-git-4f7b498d12b04ae25ae59a711e76410e77455a94.tar.gz
Fixed bug #73374
Add "0b" prefix detection to intval($str, 0). The implementation is relatively complicated because we need to handle whitespace and sign.
Diffstat (limited to 'ext/standard/type.c')
-rw-r--r--ext/standard/type.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/ext/standard/type.c b/ext/standard/type.c
index 0c7be1f177..d022a1eda3 100644
--- a/ext/standard/type.c
+++ b/ext/standard/type.c
@@ -150,9 +150,48 @@ PHP_FUNCTION(intval)
if (Z_TYPE_P(num) != IS_STRING || base == 10) {
RETVAL_LONG(zval_get_long(num));
- } else {
- RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
+ return;
+ }
+
+
+ if (base == 0 || base == 2) {
+ char *strval = Z_STRVAL_P(num);
+ size_t strlen = Z_STRLEN_P(num);
+
+ while (isspace(*strval) && strlen) {
+ strval++;
+ strlen--;
+ }
+
+ /* Length of 3+ covers "0b#" and "-0b" (which results in 0) */
+ if (strlen > 2) {
+ int offset = 0;
+ if (strval[0] == '-' || strval[0] == '+') {
+ offset = 1;
+ }
+
+ if (strval[offset] == '0' && (strval[offset + 1] == 'b' || strval[offset + 1] == 'B')) {
+ char *tmpval;
+ strlen -= 2; /* Removing "0b" */
+ tmpval = emalloc(strlen + 1);
+
+ /* Place the unary symbol at pos 0 if there was one */
+ if (offset) {
+ tmpval[0] = strval[0];
+ }
+
+ /* Copy the data from after "0b" to the end of the buffer */
+ memcpy(tmpval + offset, strval + offset + 2, strlen - offset);
+ tmpval[strlen] = 0;
+
+ RETVAL_LONG(ZEND_STRTOL(tmpval, NULL, 2));
+ efree(tmpval);
+ return;
+ }
+ }
}
+
+ RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
}
/* }}} */