diff options
20 files changed, 872 insertions, 4 deletions
@@ -65,6 +65,11 @@ PHP 8.1 UPGRADE NOTES 2. New Features ======================================== +- Core: + . It is now possible to specify octal integer by using the explicit "0o"/"0O" + prefix similar to hexadecimal ("0x"/"0X) and binary ("0b"/"0B") integer literals + RFC: https://wiki.php.net/rfc/explicit_octal_notation + - hash: . The following functions have changed signatures: @@ -101,6 +106,15 @@ PHP 8.1 UPGRADE NOTES 5. Changed Functions ======================================== +- Filter: + . The FILTER_FLAG_ALLOW_OCTAL flag of the FILTER_VALIDATE_INT filter now accept + octal string with the leading octal prefix ("0o"/"0O") + RFC: https://wiki.php.net/rfc/explicit_octal_notation + +- GMP: + . All GMP function now accept octal string with the leading octal prefix ("0o"/"0O") + RFC: https://wiki.php.net/rfc/explicit_octal_notation + ======================================== 6. New Functions ======================================== diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index c381d50a28..d82f67d0c7 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1366,6 +1366,7 @@ DNUM ({LNUM}?"."{LNUM})|({LNUM}"."{LNUM}?) EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM}) HNUM "0x"[0-9a-fA-F]+(_[0-9a-fA-F]+)* BNUM "0b"[01]+(_[01]+)* +ONUM "0o"[0-7]+(_[0-7]+)* LABEL [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]* WHITESPACE [ \n\r\t]+ TABS_AND_SPACES [ \t]* @@ -1950,6 +1951,51 @@ NEWLINE ("\r"|"\n"|"\r\n") } } +<ST_IN_SCRIPTING>{ONUM} { + /* The +/- 2 skips "0o" */ + size_t len = yyleng - 2; + char *end, *octal = yytext + 2; + zend_bool contains_underscores = (memchr(octal, '_', len) != NULL); + + /* Skip any leading 0s */ + while (len > 0 && (*octal == '0' || *octal == '_')) { + ++octal; + --len; + } + + if (contains_underscores) { + octal = estrndup(octal, len); + strip_underscores(octal, &len); + } + + errno = 0; + + ZVAL_LONG(zendlval, ZEND_STRTOL(octal, &end, 8)); + + ZEND_ASSERT(end == octal + len); + + if (!errno) { + if (contains_underscores) { + efree(octal); + } + RETURN_TOKEN_WITH_VAL(T_LNUMBER); + } + + /* Overflow */ + ZEND_ASSERT(errno == ERANGE); + /* Reset errno */ + errno = 0; + + /* zend_oct_strtod skips leading '0' */ + ZVAL_DOUBLE(zendlval, zend_oct_strtod(octal, (const char **)&end)); + ZEND_ASSERT(!errno); + ZEND_ASSERT(end == octal + len); + if (contains_underscores) { + efree(octal); + } + RETURN_TOKEN_WITH_VAL(T_DNUMBER); +} + <ST_IN_SCRIPTING>{LNUM} { size_t len = yyleng; char *end, *lnum = yytext; @@ -2071,7 +2117,7 @@ string: RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */ +<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM}|{ONUM} { /* Offset must be treated as a string */ if (yyleng == 1) { ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext))); } else { diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index e88fbd001f..9173a15031 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -4467,9 +4467,6 @@ ZEND_API double zend_oct_strtod(const char *str, const char **endptr) return 0.0; } - /* skip leading zero */ - s++; - while ((c = *s++)) { if (c < '0' || c > '7') { /* break and return the current value if the number is not well-formed diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 392156b539..1e4925b421 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -240,6 +240,13 @@ void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ error = 1; } } else if (allow_octal) { + /* Support explicit octal prefix notation */ + if (*p == 'o' || *p == 'O') { + p++; len--; + if (len == 0) { + RETURN_VALIDATION_FAILED + } + } if (php_filter_parse_octal(p, len, &ctx_value) < 0) { error = 1; } diff --git a/ext/filter/tests/013.phpt b/ext/filter/tests/013.phpt index c9dd915d83..3f663ac762 100644 --- a/ext/filter/tests/013.phpt +++ b/ext/filter/tests/013.phpt @@ -38,6 +38,11 @@ var_dump(filter_var(345, FILTER_VALIDATE_INT, array("options" => array("min_rang var_dump(filter_var("0ff", FILTER_VALIDATE_INT)); var_dump(filter_var("010", FILTER_VALIDATE_INT)); +// Explicit octal prefix +var_dump(filter_var("0o16", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("0O16", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); +var_dump(filter_var("0o016", FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); + echo "Done\n"; ?> --EXPECT-- @@ -71,4 +76,7 @@ bool(false) bool(false) bool(false) bool(false) +int(14) +int(14) +int(14) Done diff --git a/ext/filter/tests/surprising_integer_literals.phpt b/ext/filter/tests/surprising_integer_literals.phpt new file mode 100644 index 0000000000..abb7b9caea --- /dev/null +++ b/ext/filter/tests/surprising_integer_literals.phpt @@ -0,0 +1,36 @@ +--TEST-- +Surprising result with integer literals (hex/octal) +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php +echo 'Hex', \PHP_EOL; +var_dump(filter_var('0x', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); +var_dump(filter_var('0xg', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); +var_dump(filter_var('0X', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); +var_dump(filter_var('0Xg', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); +var_dump(filter_var('', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX)); +echo 'Octal', \PHP_EOL; +var_dump(filter_var('0o', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('0og', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('0O', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('0Og', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('O', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('Og', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +var_dump(filter_var('', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL)); +?> +--EXPECT-- +Hex +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +Octal +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 0f4b317fd0..da1ab3047f 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -605,6 +605,9 @@ static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, ui if ((base == 0 || base == 16) && (numstr[1] == 'x' || numstr[1] == 'X')) { base = 16; skip_lead = 1; + } else if ((base == 0 || base == 8) && (numstr[1] == 'o' || numstr[1] == 'O')) { + base = 8; + skip_lead = 1; } else if ((base == 0 || base == 2) && (numstr[1] == 'b' || numstr[1] == 'B')) { base = 2; skip_lead = 1; diff --git a/ext/gmp/tests/gmp_init_integer_notations.phpt b/ext/gmp/tests/gmp_init_integer_notations.phpt new file mode 100644 index 0000000000..0a705f7cd3 --- /dev/null +++ b/ext/gmp/tests/gmp_init_integer_notations.phpt @@ -0,0 +1,50 @@ +--TEST-- +gmp_init() with various integer notations +--SKIPIF-- +<?php if (!extension_loaded("gmp")) print "skip"; ?> +--FILE-- +<?php + +var_dump(gmp_init("0x16")); +var_dump(gmp_init("0X16")); +var_dump(gmp_init("0o16")); +var_dump(gmp_init("0o16")); +var_dump(gmp_init("016")); +var_dump(gmp_init("016")); +var_dump(gmp_init("0b11")); +var_dump(gmp_init("0b11")); + +?> +--EXPECT-- +object(GMP)#1 (1) { + ["num"]=> + string(2) "22" +} +object(GMP)#1 (1) { + ["num"]=> + string(2) "22" +} +object(GMP)#1 (1) { + ["num"]=> + string(2) "14" +} +object(GMP)#1 (1) { + ["num"]=> + string(2) "14" +} +object(GMP)#1 (1) { + ["num"]=> + string(2) "14" +} +object(GMP)#1 (1) { + ["num"]=> + string(2) "14" +} +object(GMP)#1 (1) { + ["num"]=> + string(1) "3" +} +object(GMP)#1 (1) { + ["num"]=> + string(1) "3" +} diff --git a/ext/gmp/tests/surprising_integer_literals.phpt b/ext/gmp/tests/surprising_integer_literals.phpt new file mode 100644 index 0000000000..de7289ea0b --- /dev/null +++ b/ext/gmp/tests/surprising_integer_literals.phpt @@ -0,0 +1,33 @@ +--TEST-- +Surprising result with integer literals (hex/binary/octal) +--SKIPIF-- +<?php if (!extension_loaded("gmp")) print "skip"; ?> +--FILE-- +<?php + +$values = [ + '0x', + '0X', + '0b', + '0B', + '0o', + '0O', + '' +]; + +foreach ($values as $value) { + try { + var_dump(gmp_init($value)); + } catch (\ValueError $e) { + echo $e->getMessage(), \PHP_EOL; + } +} +?> +--EXPECT-- +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string diff --git a/ext/standard/tests/math/base_convert_variation2.phpt b/ext/standard/tests/math/base_convert_variation2.phpt new file mode 100644 index 0000000000..279cff9920 --- /dev/null +++ b/ext/standard/tests/math/base_convert_variation2.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test base_convert() function : strange literals +--FILE-- +<?php +echo 'Binary to decimal:', \PHP_EOL; +var_dump(base_convert('0b', 2, 10)); +var_dump(base_convert('0B', 2, 10)); +var_dump(base_convert('', 2, 10)); +echo 'Octal to decimal:', \PHP_EOL; +var_dump(base_convert('0o', 8, 10)); +var_dump(base_convert('0O', 8, 10)); +var_dump(base_convert('0', 8, 10)); +var_dump(base_convert('', 8, 10)); +echo 'Hexadecimal to decimal:', \PHP_EOL; +var_dump(base_convert('0x', 16, 10)); +var_dump(base_convert('0X', 16, 10)); +var_dump(base_convert('', 16, 10)); +?> +--EXPECT-- +Binary to decimal: +string(1) "0" +string(1) "0" +string(1) "0" +Octal to decimal: +string(1) "0" +string(1) "0" +string(1) "0" +string(1) "0" +Hexadecimal to decimal: +string(1) "0" +string(1) "0" +string(1) "0" diff --git a/ext/standard/tests/math/base_convert_variation3.phpt b/ext/standard/tests/math/base_convert_variation3.phpt new file mode 100644 index 0000000000..27e0841108 --- /dev/null +++ b/ext/standard/tests/math/base_convert_variation3.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test base_convert() function: converting '0' +--FILE-- +<?php +echo 'Binary to decimal:', \PHP_EOL; +var_dump(base_convert('0', 2, 10)); +echo 'Octal to decimal:', \PHP_EOL; +var_dump(base_convert('0', 8, 10)); +echo 'Hexadecimal to decimal:', \PHP_EOL; +var_dump(base_convert('0', 16, 10)); +?> +--EXPECT-- +Binary to decimal: +string(1) "0" +Octal to decimal: +string(1) "0" +Hexadecimal to decimal: +string(1) "0" diff --git a/ext/standard/tests/math/bindec_variation2.phpt b/ext/standard/tests/math/bindec_variation2.phpt new file mode 100644 index 0000000000..3fddc5d856 --- /dev/null +++ b/ext/standard/tests/math/bindec_variation2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test bindec() function : strange literals +--FILE-- +<?php + +var_dump(bindec('0b')); +var_dump(bindec('0B')); +var_dump(bindec('')); + +?> +--EXPECT-- +int(0) +int(0) +int(0) diff --git a/ext/standard/tests/math/hexdec_variation2.phpt b/ext/standard/tests/math/hexdec_variation2.phpt new file mode 100644 index 0000000000..81ebae5c3f --- /dev/null +++ b/ext/standard/tests/math/hexdec_variation2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test hexdec() function : strange literals +--FILE-- +<?php + +var_dump(hexdec('0x')); +var_dump(hexdec('0X')); +var_dump(hexdec('')); + +?> +--EXPECT-- +int(0) +int(0) +int(0) diff --git a/ext/standard/tests/math/octdec_variation2.phpt b/ext/standard/tests/math/octdec_variation2.phpt new file mode 100644 index 0000000000..bf26f45736 --- /dev/null +++ b/ext/standard/tests/math/octdec_variation2.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test octdec() function : strange literals +--FILE-- +<?php + +var_dump(octdec('0o')); +var_dump(octdec('0O')); +var_dump(octdec('0')); +var_dump(octdec('')); + +?> +--EXPECT-- +int(0) +int(0) +int(0) +int(0) diff --git a/tests/lang/integer_literals/binary_32bit.phpt b/tests/lang/integer_literals/binary_32bit.phpt new file mode 100644 index 0000000000..4318940446 --- /dev/null +++ b/tests/lang/integer_literals/binary_32bit.phpt @@ -0,0 +1,82 @@ +--TEST-- +Binary integer strings (32bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); +?> +--FILE-- +<?php +/* Using binary prefix notation lowercase */ +/* Maximum value representable as integer */ +$binary = 0b1111111111111111111111111111111; +var_dump($binary); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$binary = 0b111111010000101010101010101010111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Integer */ +$binary = 0b1010110; +var_dump($binary); + +/* underscore separator */ +$binary = 0b1_010110; +var_dump($binary); + +/* Ignore leading 0 and _ */ +$binary = 0b0_01010110; +var_dump($binary); +$binary = 0b0_1010110; +var_dump($binary); + +/* Overflow to infinity */ +$binary = 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Using binary prefix notation uppercase */ +/* Maximum value representable as integer */ +$binary = 0B1111111111111111111111111111111; +var_dump($binary); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$binary = 0B111111010000101010101010101010111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Integer */ +$binary = 0B1010110; +var_dump($binary); + +/* underscore separator */ +$binary = 0B1_010110; +var_dump($binary); + +/* Ignore leading 0 and _ */ +$binary = 0B0_01010110; +var_dump($binary); +$binary = 0B0_1010110; +var_dump($binary); + +/* Overflow to infinity */ +$binary = 0B111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +?> +--EXPECT-- +int(2147483647) +int(2147483647) +float(1.9119287772983036E+25) +int(86) +int(86) +int(86) +int(86) +float(INF) +int(2147483647) +int(2147483647) +float(1.9119287772983036E+25) +int(86) +int(86) +int(86) +int(86) +float(INF) diff --git a/tests/lang/integer_literals/binary_64bit.phpt b/tests/lang/integer_literals/binary_64bit.phpt new file mode 100644 index 0000000000..9b6c3997ae --- /dev/null +++ b/tests/lang/integer_literals/binary_64bit.phpt @@ -0,0 +1,82 @@ +--TEST-- +Binary integer strings (64bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); +?> +--FILE-- +<?php +/* Using binary prefix notation lowercase */ +/* Maximum value representable as integer */ +$binary = 0b111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$binary = 0b111111010000101010101010101010111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Integer */ +$binary = 0b1010110; +var_dump($binary); + +/* underscore separator */ +$binary = 0b1_010110; +var_dump($binary); + +/* Ignore leading 0 and _ */ +$binary = 0b0_01010110; +var_dump($binary); +$binary = 0b0_1010110; +var_dump($binary); + +/* Overflow to infinity */ +$binary = 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Using binary prefix notation uppercase */ +/* Maximum value representable as integer */ +$binary = 0B111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$binary = 0B111111010000101010101010101010111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +/* Integer */ +$binary = 0B1010110; +var_dump($binary); + +/* underscore separator */ +$binary = 0B1_010110; +var_dump($binary); + +/* Ignore leading 0 and _ */ +$binary = 0B0_01010110; +var_dump($binary); +$binary = 0B0_1010110; +var_dump($binary); + +/* Overflow to infinity */ +$binary = 0B111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111; +var_dump($binary); + +?> +--EXPECT-- +int(9223372036854775807) +int(9223372036854775807) +float(1.9119287772983036E+25) +int(86) +int(86) +int(86) +int(86) +float(INF) +int(9223372036854775807) +int(9223372036854775807) +float(1.9119287772983036E+25) +int(86) +int(86) +int(86) +int(86) +float(INF) diff --git a/tests/lang/integer_literals/hexadecimal_32bit.phpt b/tests/lang/integer_literals/hexadecimal_32bit.phpt new file mode 100644 index 0000000000..1793354a5d --- /dev/null +++ b/tests/lang/integer_literals/hexadecimal_32bit.phpt @@ -0,0 +1,82 @@ +--TEST-- +Hexadecimal integer strings (32bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); +?> +--FILE-- +<?php +/* Using hexadecimal prefix notation lowercase */ +/* Maximum value representable as integer */ +$hex = 0x7FFFFFFF; +var_dump($hex); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$hex = 0x45FFFABCDE0000000; +var_dump($hex); + +/* Integer */ +$hex = 0x1C; +var_dump($hex); + +/* underscore separator */ +$hex = 0x1_C; +var_dump($hex); + +/* Ignore leading 0 and _ */ +$hex = 0x0_01C; +var_dump($hex); +$hex = 0x0_1C; +var_dump($hex); + +/* Overflow to infinity */ +$hex = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; +var_dump($hex); + +/* Using hexadecimal prefix notation uppercase */ +/* Maximum value representable as integer */ +$hex = 0X7FFFFFFF; +var_dump($hex); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$hex = 0X45FFFABCDE0000000; +var_dump($hex); + +/* Integer */ +$hex = 0X1C; +var_dump($hex); + +/* underscore separator */ +$hex = 0X1_C; +var_dump($hex); + +/* Ignore leading 0 and _ */ +$hex = 0X0_01C; +var_dump($hex); +$hex = 0X0_1C; +var_dump($hex); + +/* Overflow to infinity */ +$hex = 0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; +var_dump($hex); + +?> +--EXPECT-- +int(2147483647) +int(2147483647) +float(8.070441274821732E+19) +int(28) +int(28) +int(28) +int(28) +float(INF) +int(2147483647) +int(2147483647) +float(8.070441274821732E+19) +int(28) +int(28) +int(28) +int(28) +float(INF) diff --git a/tests/lang/integer_literals/hexadecimal_64bit.phpt b/tests/lang/integer_literals/hexadecimal_64bit.phpt new file mode 100644 index 0000000000..780591d101 --- /dev/null +++ b/tests/lang/integer_literals/hexadecimal_64bit.phpt @@ -0,0 +1,83 @@ +--TEST-- +Hexadecimal integer strings (64bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); +?> +--FILE-- +<?php +/* Using hexadecimal prefix notation lowercase */ +/* Maximum value representable as integer */ +$hex = 0x7FFFFFFFFFFFFFFF; +var_dump($hex); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$hex = 0x45FFFABCDE0000000; +var_dump($hex); + +/* Integer */ +$hex = 0x1C; +var_dump($hex); + +/* underscore separator */ +$hex = 0x1_C; +var_dump($hex); + +/* Ignore leading 0 and _ */ +$hex = 0x0_01C; +var_dump($hex); +$hex = 0x0_1C; +var_dump($hex); + +/* Overflow to infinity */ +$hex = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; +var_dump($hex); + + +/* Using hexadecimal prefix notation uppercase */ +/* Maximum value representable as integer */ +$hex = 0X7FFFFFFFFFFFFFFF; +var_dump($hex); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$hex = 0X45FFFABCDE0000000; +var_dump($hex); + +/* Integer */ +$hex = 0X1C; +var_dump($hex); + +/* underscore separator */ +$hex = 0X1_C; +var_dump($hex); + +/* Ignore leading 0 and _ */ +$hex = 0X0_01C; +var_dump($hex); +$hex = 0X0_1C; +var_dump($hex); + +/* Overflow to infinity */ +$hex = 0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; +var_dump($hex); + +?> +--EXPECT-- +int(9223372036854775807) +int(9223372036854775807) +float(8.070441274821732E+19) +int(28) +int(28) +int(28) +int(28) +float(INF) +int(9223372036854775807) +int(9223372036854775807) +float(8.070441274821732E+19) +int(28) +int(28) +int(28) +int(28) +float(INF) diff --git a/tests/lang/integer_literals/octal_32bit.phpt b/tests/lang/integer_literals/octal_32bit.phpt new file mode 100644 index 0000000000..472fe602c0 --- /dev/null +++ b/tests/lang/integer_literals/octal_32bit.phpt @@ -0,0 +1,118 @@ +--TEST-- +Octal integer strings (32bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); +?> +--FILE-- +<?php +/* Using octal prefix notation lowercase */ +/* Maximum value representable as integer */ +$octal = 0o17777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$octal = 0o45734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 0o16; +var_dump($octal); + +/* underscore separator */ +$octal = 0o1_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 0o0_016; +var_dump($octal); +$octal = 0o0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 0o77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +/* Using octal prefix notation uppercase */ +/* Maximum value representable as integer */ +$octal = 0O17777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$octal = 0O45734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 0O16; +var_dump($octal); + +/* underscore separator */ +$octal = 0O1_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 0O0_016; +var_dump($octal); +$octal = 0O0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 0O77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +/* Using no dedicated prefix */ +/* Maximum value representable as integer */ +$octal = 017777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* Floating number */ +$octal = 045734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 016; +var_dump($octal); + +/* underscore separator */ +$octal = 01_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 00_016; +var_dump($octal); +$octal = 0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 077777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +?> +--EXPECT-- +int(2147483647) +int(2147483647) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) +int(2147483647) +int(2147483647) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) +int(2147483647) +int(2147483647) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) diff --git a/tests/lang/integer_literals/octal_64bit.phpt b/tests/lang/integer_literals/octal_64bit.phpt new file mode 100644 index 0000000000..742900e4e8 --- /dev/null +++ b/tests/lang/integer_literals/octal_64bit.phpt @@ -0,0 +1,133 @@ +--TEST-- +Octal integer strings (64bit) +--SKIPIF-- +<?php +if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); +?> +--FILE-- +<?php +/* Using octal prefix notation lowercase */ +/* Maximum value representable as integer */ +$octal = 0o777777777777777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* *technically* this should work but treat this as a degenerate case */ +$octal = 0o1000000000000000000000; +var_dump($octal); + +/* Floating number */ +$octal = 0o45734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 0o16; +var_dump($octal); + +/* underscore separator */ +$octal = 0o1_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 0o0_016; +var_dump($octal); +$octal = 0o0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 0o77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +/* Using octal prefix notation uppercase */ +/* Maximum value representable as integer */ +$octal = 0O777777777777777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* *technically* this should work but treat this as a degenerate case */ +$octal = 0O1000000000000000000000; +var_dump($octal); + +/* Floating number */ +$octal = 0O45734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 0O16; +var_dump($octal); + +/* underscore separator */ +$octal = 0O1_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 0O0_016; +var_dump($octal); +$octal = 0O0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 0O77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +/* Using no dedicated prefix */ +/* Maximum value representable as integer */ +$octal = 0777777777777777777777; +var_dump($octal); +var_dump(PHP_INT_MAX); + +/* *technically* this should work but treat this as a degenerate case */ +$octal = 01000000000000000000000; +var_dump($octal); + +/* Floating number */ +$octal = 045734321536435450000000000; +var_dump($octal); + +/* Integer */ +$octal = 016; +var_dump($octal); + +/* underscore separator */ +$octal = 01_6; +var_dump($octal); + +/* Ignore leading 0 and _ */ +$octal = 00_016; +var_dump($octal); +$octal = 0_16; +var_dump($octal); + +/* Overflow to infinity */ +$octal = 077777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777; +var_dump($octal); + +?> +--EXPECT-- +int(9223372036854775807) +int(9223372036854775807) +float(9.223372036854776E+18) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) +int(9223372036854775807) +int(9223372036854775807) +float(9.223372036854776E+18) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) +int(9223372036854775807) +int(9223372036854775807) +float(9.223372036854776E+18) +float(1.7912166229916324E+23) +int(14) +int(14) +int(14) +int(14) +float(INF) |