com php-src: Fixed bug #73374: NEWS ext/standard/tests/general _functions/intval_binary_prefix.phpt ext/standard/typ e.c
| From: | Nikita Popov | Date: | Thu, 12 Jan 2017 17:53:28 +0000 |
| Subject: | com php-src: Fixed bug #73374: NEWS ext/standard/tests/general _functions/intval_binary_prefix.phpt ext/standard/typ e.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-96698@lists.php.net to get a copy of this message | ||
Commit: 4f7b498d12b04ae25ae59a711e76410e77455a94
Author: Leigh <leigh@php.net> Mon, 31 Oct 2016 16:25:33 +0000
Committer: Nikita Popov <nikic@php.net> Thu, 12 Jan 2017 18:53:28 +0100
Parents: e65760f878a116d7ffc858c5a0e30f6075230443
Branches: PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=4f7b498d12b04ae25ae59a711e76410e77455a94
Log:
Fixed bug #73374
Add "0b" prefix detection to intval($str, 0). The implementation
is relatively complicated because we need to handle whitespace and
sign.
Bugs:
https://bugs.php.net/73374
Changed paths:
M NEWS
A ext/standard/tests/general_functions/intval_binary_prefix.phpt
M ext/standard/type.c
Diff:
diff --git a/NEWS b/NEWS
index a8eeb9a..2a4b137 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 0000000..af49515
--- /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--
+<?php
+
+$isspaceChars = " \t\n\r\f\v";
+
+$goodInputs = [
+ '0b1111111111111111111111111111111',
+ '+0b1111111111111111111111111111111',
+ '-0b1111111111111111111111111111111',
+ $isspaceChars . '0b1111111111111111111111111111111',
+ $isspaceChars . '+0b1111111111111111111111111111111',
+ $isspaceChars . '-0b1111111111111111111111111111111',
+ '0b',
+ '0B',
+ '0B1',
+ '0b000',
+ '0b001',
+ '0b00100',
+ '0b1 1'
+];
+
+$badInputs = [
+ 'b101',
+ '0b00200',
+ '--0b123',
+ '++0b123',
+ '0bb123',
+ '0 b123',
+];
+
+print "--- Good Inputs - Base = 0 ---\n";
+
+foreach ($goodInputs as $input) {
+ var_dump(
+ intval($input, 0)
+ );
+}
+
+print "--- Good Inputs - Base = 2 ---\n";
+
+foreach ($goodInputs as $input) {
+ var_dump(
+ intval($input, 2)
+ );
+}
+
+print "--- Good Inputs - Base = default ---\n";
+
+foreach ($goodInputs as $input) {
+ var_dump(
+ intval($input)
+ );
+}
+
+print "--- Bad Inputs - Base = 0 ---\n";
+
+foreach ($badInputs as $input) {
+ var_dump(
+ intval($input, 0)
+ );
+}
+
+print '--- Done ---';
+
+?>
+--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 0c7be1f..d022a1e 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));
}
/* }}} */