From: Leigh Date: Mon, 31 Oct 2016 16:25:33 +0000 (+0000) Subject: Fixed bug #73374 X-Git-Tag: php-7.1.2RC1~90 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f7b498d12b04ae25ae59a711e76410e77455a94;p=php Fixed bug #73374 Add "0b" prefix detection to intval($str, 0). The implementation is relatively complicated because we need to handle whitespace and sign. --- diff --git a/NEWS b/NEWS index a8eeb9a787..2a4b137417 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,7 @@ PHP NEWS "Transfer-Encoding: chunked"). (Rowan Collins) . Fixed bug #72974 (imap is undefined service on AIX). (matthieu.sarter) . Fixed bug #72979 (money_format stores wrong length AIX). (matthieu.sarter) + . Fixed bug #73374 (intval() with base 0 should detect binary). (Leigh) - ZIP: . Fixed bug #70103 (ZipArchive::addGlob ignores remove_all_path option). (cmb, diff --git a/ext/standard/tests/general_functions/intval_binary_prefix.phpt b/ext/standard/tests/general_functions/intval_binary_prefix.phpt new file mode 100644 index 0000000000..af49515396 --- /dev/null +++ b/ext/standard/tests/general_functions/intval_binary_prefix.phpt @@ -0,0 +1,119 @@ +--TEST-- +Test intval() function with "0b" string prefix +--SKIPIF-- +--FILE-- + +--EXPECTF-- +--- Good Inputs - Base = 0 --- +int(2147483647) +int(2147483647) +int(-2147483647) +int(2147483647) +int(2147483647) +int(-2147483647) +int(0) +int(0) +int(1) +int(0) +int(1) +int(4) +int(1) +--- Good Inputs - Base = 2 --- +int(2147483647) +int(2147483647) +int(-2147483647) +int(2147483647) +int(2147483647) +int(-2147483647) +int(0) +int(0) +int(1) +int(0) +int(1) +int(4) +int(1) +--- Good Inputs - Base = default --- +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +--- Bad Inputs - Base = 0 --- +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +--- Done --- 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)); } /* }}} */