com php-src: Fixed bug #73374: NEWS ext/standard/tests/general _functions/intval_binary_prefix.phpt ext/standard/typ e.c

From: 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)); } /* }}} */

« previous php.cvs (#96698) next »