diff options
Diffstat (limited to 'Zend/tests')
61 files changed, 1262 insertions, 29 deletions
diff --git a/Zend/tests/bug39304.phpt b/Zend/tests/bug39304.phpt index 5540135fa4..2e9ebcdee4 100644 --- a/Zend/tests/bug39304.phpt +++ b/Zend/tests/bug39304.phpt @@ -8,9 +8,5 @@ echo "I am alive"; ?> --EXPECTF-- Notice: Uninitialized string offset: 0 in %sbug39304.php on line %d - -Notice: Uninitialized string offset: 0 in %sbug39304.php on line %d - -Notice: Uninitialized string offset: 1 in %sbug39304.php on line %d I am alive diff --git a/Zend/tests/bug39304_2_4.phpt b/Zend/tests/bug39304_2_4.phpt index cc0709b424..917c64e2cd 100644 --- a/Zend/tests/bug39304_2_4.phpt +++ b/Zend/tests/bug39304_2_4.phpt @@ -10,9 +10,5 @@ Bug #39304 (Segmentation fault with list unpacking of string offset) ?> --EXPECTF-- Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line %d - -Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line %d - -Notice: Uninitialized string offset: 1 in %sbug39304_2_4.php on line %d -string(0) "" -string(0) "" +NULL +NULL diff --git a/Zend/tests/bug68118.phpt b/Zend/tests/bug68118.phpt new file mode 100644 index 0000000000..c56e70a112 --- /dev/null +++ b/Zend/tests/bug68118.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #68118: $a->foo .= 'test'; can leave $a->foo undefined +--FILE-- +<?php + +set_error_handler(function() { + $obj = new stdClass; + $obj->test = 'meow'; + return true; +}); + +$a = new stdClass; +$a->undefined .= 'test'; +var_dump($a); + +?> +--EXPECT-- +object(stdClass)#2 (1) { + ["undefined"]=> + string(4) "test" +} diff --git a/Zend/tests/bug68148.phpt b/Zend/tests/bug68148.phpt new file mode 100644 index 0000000000..fcbf69bb87 --- /dev/null +++ b/Zend/tests/bug68148.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #68148: $this is null inside include +--FILE-- +<?php + +class Test { + public function method() { + eval('var_dump($this);'); + } +} + +(new Test)->method(); + +?> +--EXPECT-- +object(Test)#1 (0) { +} diff --git a/Zend/tests/bug68162.phpt b/Zend/tests/bug68162.phpt new file mode 100644 index 0000000000..24e412f18d --- /dev/null +++ b/Zend/tests/bug68162.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #68162: isset($$varname) always true +--FILE-- +<?php + +$name = 'var'; +var_dump(isset($$name)); +$var = 42; +var_dump(isset($$name)); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/Zend/tests/bug68163.phpt b/Zend/tests/bug68163.phpt new file mode 100644 index 0000000000..2ea0da33d6 --- /dev/null +++ b/Zend/tests/bug68163.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #68163: Using reference as object property name +--FILE-- +<?php + +$obj = (object) ['foo' => 'bar']; +$foo = 'foo'; +$ref =& $foo; +var_dump($obj->$foo); + +?> +--EXPECT-- +string(3) "bar" diff --git a/Zend/tests/bug68191.phpt b/Zend/tests/bug68191.phpt new file mode 100644 index 0000000000..198c5c7dce --- /dev/null +++ b/Zend/tests/bug68191.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #68191: Broken reference across objects +--FILE-- +<?php + +$obj = new stdClass; + +$obj->prop1 = 'abc'; +$obj->prop2 =& $obj->prop1; +$obj->prop2 .= 'xyz'; +var_dump($obj->prop1); + +$obj->prop3 = 1; +$obj->prop4 =& $obj->prop3; +++$obj->prop4; +var_dump($obj->prop3); + +?> +--EXPECT-- +string(6) "abcxyz" +int(2) diff --git a/Zend/tests/bug68215.phpt b/Zend/tests/bug68215.phpt new file mode 100644 index 0000000000..c4e8da8515 --- /dev/null +++ b/Zend/tests/bug68215.phpt @@ -0,0 +1,91 @@ +--TEST-- +Bug #68215 (Behavior of foreach has changed) +--FILE-- +<?php +$arr = array( + 'a' => array( + 'a' => 'apple', + 'b' => 'banana', + 'c' => 'cranberry', + 'd' => 'mango', + 'e' => 'pineapple' + ), + 'b' => array( + 'a' => 'apple', + 'b' => 'banana', + 'c' => 'cranberry', + 'd' => 'mango', + 'e' => 'pineapple' + ), + 'c' => 'cranberry', + 'd' => 'mango', + 'e' => 'pineapple' +); + +function test(&$child, $entry) +{ + $i = 1; + + foreach ($child AS $key => $fruit) + { + if (!is_numeric($key)) + { + $child[$i] = $fruit; + unset($child[$key]); + $i++; + } + } +} + +$i = 1; + +foreach ($arr AS $key => $fruit) +{ + $arr[$i] = $fruit; + + if (is_array($fruit)) + { + test($arr[$i], $fruit); + } + + unset($arr[$key]); + $i++; +} + +var_dump($arr); +?> +--EXPECT-- +array(5) { + [1]=> + array(5) { + [1]=> + string(5) "apple" + [2]=> + string(6) "banana" + [3]=> + string(9) "cranberry" + [4]=> + string(5) "mango" + [5]=> + string(9) "pineapple" + } + [2]=> + array(5) { + [1]=> + string(5) "apple" + [2]=> + string(6) "banana" + [3]=> + string(9) "cranberry" + [4]=> + string(5) "mango" + [5]=> + string(9) "pineapple" + } + [3]=> + string(9) "cranberry" + [4]=> + string(5) "mango" + [5]=> + string(9) "pineapple" +} diff --git a/Zend/tests/bug68262.phpt b/Zend/tests/bug68262.phpt new file mode 100644 index 0000000000..8d009f621e --- /dev/null +++ b/Zend/tests/bug68262.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #68262: Broken reference across cloned objects +--FILE-- +<?php + +class C { + public $p; +} + +$first = new C; +$first->p = 'init'; + +$clone = clone $first; +$ref =& $first->p; +unset($ref); + +$clone = clone $first; +$clone->p = 'foo'; + +var_dump($first->p); + +?> +--EXPECT-- +string(4) "init" diff --git a/Zend/tests/builtin_in_write_context_error1.phpt b/Zend/tests/builtin_in_write_context_error1.phpt new file mode 100644 index 0000000000..eed03cc3c1 --- /dev/null +++ b/Zend/tests/builtin_in_write_context_error1.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use built-in functions in write context (assignment) +--FILE-- +<?php + +strlen("foo")[0] = 1; + +?> +--EXPECTF-- +Fatal error: Cannot use result of built-in function in write context in %s on line %d diff --git a/Zend/tests/builtin_in_write_context_error2.phpt b/Zend/tests/builtin_in_write_context_error2.phpt new file mode 100644 index 0000000000..aac23e4f4e --- /dev/null +++ b/Zend/tests/builtin_in_write_context_error2.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use built-in functions in write context (reference) +--FILE-- +<?php + +$ref =& strlen("foo"); + +?> +--EXPECTF-- +Fatal error: Cannot use result of built-in function in write context in %s on line %d diff --git a/Zend/tests/bw_or_assign_with_ref.phpt b/Zend/tests/bw_or_assign_with_ref.phpt new file mode 100644 index 0000000000..27ccf6299b --- /dev/null +++ b/Zend/tests/bw_or_assign_with_ref.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bitwise or assign with referenced value +--FILE-- +<?php + +$num1 = 1; +$num2 = '2'; +$ref =& $num2; +$num1 |= $num2; +var_dump($num1); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/class_name_as_scalar_error_007.phpt b/Zend/tests/class_name_as_scalar_error_007.phpt new file mode 100644 index 0000000000..2bfa5f38f8 --- /dev/null +++ b/Zend/tests/class_name_as_scalar_error_007.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot access self::class when no class scope is active +--FILE-- +<?php + +var_dump(self::class); + +?> +--EXPECTF-- +Fatal error: Cannot access self::class when no class scope is active in %s on line %d diff --git a/Zend/tests/constant_expressions_dynamic.phpt b/Zend/tests/constant_expressions_dynamic.phpt index 21c9216cc1..d4e06ee258 100644 --- a/Zend/tests/constant_expressions_dynamic.phpt +++ b/Zend/tests/constant_expressions_dynamic.phpt @@ -2,10 +2,76 @@ Dynamic Constant Expressions --FILE-- <?php -const FOO = 1; -const BAR = FOO | 2; -echo BAR; +const C_0 = 0; +const C_1 = 1; +const C_foo = "foo"; +const C_arr = [0 => 0, "foo" => "foo"]; + +const T_1 = C_1 | 2; +const T_2 = C_1 . "foo"; +const T_3 = C_1 > 1; +const T_4 = C_1 >= 1; +const T_5 = -C_1; +const T_6 = +C_1; +const T_7 = +C_foo; +const T_8 = !C_1; +const T_9 = C_0 || 0; +const T_10 = C_1 || 0; +const T_11 = C_0 && 1; +const T_12 = C_1 && 1; +const T_13 = C_0 ? "foo" : "bar"; +const T_14 = C_1 ? "foo" : "bar"; +const T_15 = C_0 ?: "bar"; +const T_16 = C_1 ?: "bar"; +const T_17 = C_arr[0]; +const T_18 = C_arr["foo"]; +const T_19 = [ + C_0, + "foo" => "foo", + 42 => 42, + 3.14 => 3.14, + null => null, + false => false, + true => true, +]; + +var_dump( + T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9, T_10, + T_11, T_12, T_13, T_14, T_15, T_16, T_17, T_18, T_19 +); + ?> ---EXPECTF-- -3 +--EXPECT-- +int(3) +string(4) "1foo" +bool(false) +bool(true) +int(-1) +int(1) +int(0) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +string(3) "bar" +string(3) "foo" +string(3) "bar" +int(1) +int(0) +string(3) "foo" +array(6) { + [0]=> + bool(false) + ["foo"]=> + string(3) "foo" + [42]=> + int(42) + [3]=> + float(3.14) + [""]=> + NULL + [1]=> + bool(true) +} diff --git a/Zend/tests/constant_expressions_dynamic_class_name_error.phpt b/Zend/tests/constant_expressions_dynamic_class_name_error.phpt new file mode 100644 index 0000000000..3ce5844649 --- /dev/null +++ b/Zend/tests/constant_expressions_dynamic_class_name_error.phpt @@ -0,0 +1,11 @@ +--TEST-- +Dynamic class names can't be used in compile-time constant refs +--FILE-- +<?php + +$foo = 'test'; +const C = $foo::BAR; + +?> +--EXPECTF-- +Fatal error: Dynamic class names are not allowed in compile-time class constant references in %s on line %d diff --git a/Zend/tests/constant_expressions_invalid_offset_type_error.phpt b/Zend/tests/constant_expressions_invalid_offset_type_error.phpt new file mode 100644 index 0000000000..440eabc652 --- /dev/null +++ b/Zend/tests/constant_expressions_invalid_offset_type_error.phpt @@ -0,0 +1,11 @@ +--TEST-- +Can't use arrays as key for constant array +--FILE-- +<?php + +const C1 = 1; // force dynamic evaluation +const C2 = [C1, [] => 1]; + +?> +--EXPECTF-- +Fatal error: Illegal offset type in %s on line %d diff --git a/Zend/tests/constant_expressions_static_class_name_error.phpt b/Zend/tests/constant_expressions_static_class_name_error.phpt new file mode 100644 index 0000000000..f03a88b87e --- /dev/null +++ b/Zend/tests/constant_expressions_static_class_name_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use static::FOO in constant expressions +--FILE-- +<?php + +const C = static::FOO; + +?> +--EXPECTF-- +Fatal error: "static::" is not allowed in compile-time constants in %s on line %d diff --git a/Zend/tests/debug_backtrace_with_include_and_this.phpt b/Zend/tests/debug_backtrace_with_include_and_this.phpt new file mode 100644 index 0000000000..171ad9f451 --- /dev/null +++ b/Zend/tests/debug_backtrace_with_include_and_this.phpt @@ -0,0 +1,39 @@ +--TEST-- +debug_backtrace segmentation fault with include and error handler +--FILE-- +<?php +class CLWrapper { + function stream_open($path, $mode, $options, $opened_path) { + return false; + } +} + +class CL { + public function load($class) { + if (!include($class)) { + throw new Exception('Failed loading '.$class); + } + } +} + +stream_wrapper_register('class', 'CLWrapper'); +set_error_handler(function($code, $msg, $file, $line) { + $bt= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + echo "ERR#$code: $msg @ ", $bt[1]['function'], "\n"; +}); + +try { + (new CL())->load('class://non.existant.Class'); +} catch (CLException $e) { + echo $e."\n"; +} +--EXPECTF-- +ERR#2: include(class://non.existant.Class): failed to open stream: "CLWrapper::stream_open" call failed @ include +ERR#2: include(): Failed opening 'class://non.existant.Class' for inclusion (include_path='%s') @ include + +Fatal error: Uncaught exception 'Exception' with message 'Failed loading class://non.existant.Class' in %s +Stack trace: +#0 %s(%d): CL->load('class://non.exi...') +#1 {main} + thrown in %s on line %d + diff --git a/Zend/tests/dereference_002.phpt b/Zend/tests/dereference_002.phpt index da13decc39..cc0f27d534 100644 --- a/Zend/tests/dereference_002.phpt +++ b/Zend/tests/dereference_002.phpt @@ -76,4 +76,4 @@ NULL Notice: Undefined offset: 3 in %s on line %d -Fatal error: Call to a member function bar() on null in %s on line %d +Catchable fatal error: Call to a member function bar() on null in %s on line %d diff --git a/Zend/tests/double_array_cast.phpt b/Zend/tests/double_array_cast.phpt new file mode 100644 index 0000000000..aaee8cd919 --- /dev/null +++ b/Zend/tests/double_array_cast.phpt @@ -0,0 +1,18 @@ +--TEST-- +Double array cast +--FILE-- +<?php + +$array = [1, 2, $x = 3]; +var_dump((array) (array) $array); + +?> +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/Zend/tests/duplicate_label_error.phpt b/Zend/tests/duplicate_label_error.phpt new file mode 100644 index 0000000000..c89d7a6991 --- /dev/null +++ b/Zend/tests/duplicate_label_error.phpt @@ -0,0 +1,12 @@ +--TEST-- +Duplicate labels are not allowed +--FILE-- +<?php + +foo: +foo: +goto foo; + +?> +--EXPECTF-- +Fatal error: Label 'foo' already defined in %s on line %d diff --git a/Zend/tests/exception_with_by_ref_message.phpt b/Zend/tests/exception_with_by_ref_message.phpt new file mode 100644 index 0000000000..f15c3e2719 --- /dev/null +++ b/Zend/tests/exception_with_by_ref_message.phpt @@ -0,0 +1,21 @@ +--TEST-- +Exception with by-ref message +--FILE-- +<?php + +class MyException extends Exception +{ + public function __construct(&$msg) { + $this->message =& $msg; + } +} + +$msg = 'Message'; +throw new MyException($msg); + +?> +--EXPECTF-- +Fatal error: Uncaught exception 'MyException' with message 'Message' in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/foreach_list_002.phpt b/Zend/tests/foreach_list_002.phpt index bc17d94268..1a7be521b2 100644 --- a/Zend/tests/foreach_list_002.phpt +++ b/Zend/tests/foreach_list_002.phpt @@ -18,9 +18,5 @@ foreach($array as list(, $a)) { int(1) int(3) string(1) "b" - -Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d -string(0) "" - -Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d -string(0) "" +NULL +NULL diff --git a/Zend/tests/gc_029_zts.phpt b/Zend/tests/gc_029_zts.phpt index fc77e1f3bd..5d16e83348 100644 --- a/Zend/tests/gc_029_zts.phpt +++ b/Zend/tests/gc_029_zts.phpt @@ -34,4 +34,4 @@ unset($bar); var_dump(gc_collect_cycles()); ?> --EXPECT-- -int(3) +int(6) diff --git a/Zend/tests/gc_033.phpt b/Zend/tests/gc_033.phpt index bcd1541254..dee426a385 100644 --- a/Zend/tests/gc_033.phpt +++ b/Zend/tests/gc_033.phpt @@ -1,5 +1,7 @@ --TEST-- GC 033: Crash in GC while run with phpspec +--XFAIL-- +Full GC root buffer not handled correctly yet --FILE-- <?php $a = new stdClass(); diff --git a/Zend/tests/incdec_ref_property.phpt b/Zend/tests/incdec_ref_property.phpt new file mode 100644 index 0000000000..a73b2912ab --- /dev/null +++ b/Zend/tests/incdec_ref_property.phpt @@ -0,0 +1,27 @@ +--TEST-- +Incrementing and decrementing a referenced property +--FILE-- +<?php + +$obj = new stdClass; +$obj->prop = 1; +$ref =& $obj->prop; +var_dump(++$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop++); +var_dump($obj->prop); +var_dump(--$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop--); +var_dump($obj->prop); + +?> +--EXPECT-- +int(2) +int(2) +int(2) +int(3) +int(2) +int(2) +int(2) +int(1) diff --git a/Zend/tests/line_const_in_array.phpt b/Zend/tests/line_const_in_array.phpt new file mode 100644 index 0000000000..181f67e3da --- /dev/null +++ b/Zend/tests/line_const_in_array.phpt @@ -0,0 +1,21 @@ +--TEST-- +Use of __LINE__ in arrays +--FILE-- +<?php + +var_dump([ + __LINE__, + __LINE__, + __LINE__, +]); + +?> +--EXPECT-- +array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) +} diff --git a/Zend/tests/list_005.phpt b/Zend/tests/list_005.phpt index ec5640a60a..a3b0d57434 100644 --- a/Zend/tests/list_005.phpt +++ b/Zend/tests/list_005.phpt @@ -35,9 +35,9 @@ var_dump($a, $b, $c); ?> --EXPECTF-- -string(1) "f" -string(1) "o" -string(1) "o" +NULL +NULL +NULL ---- NULL NULL diff --git a/Zend/tests/list_007.phpt b/Zend/tests/list_007.phpt index 35a25bce65..cc712406ec 100644 --- a/Zend/tests/list_007.phpt +++ b/Zend/tests/list_007.phpt @@ -8,6 +8,5 @@ list($x, $y) = function() { }; var_dump($x, $y); ?> ---EXPECT-- -NULL -NULL +--EXPECTF-- +Fatal error: Cannot use object of type Closure as array in %slist_007.php on line 3 diff --git a/Zend/tests/list_destructuring_to_special_variables.phpt b/Zend/tests/list_destructuring_to_special_variables.phpt new file mode 100644 index 0000000000..4418c967c2 --- /dev/null +++ b/Zend/tests/list_destructuring_to_special_variables.phpt @@ -0,0 +1,49 @@ +--TEST-- +list() can be used to destructure to string offsets, __set and ArrayAccess::offsetSet +--FILE-- +<?php + +class Obj { + public $values = []; + public function __set($name, $value) { + $this->values[$name] = $value; + } +} + +class Arr implements ArrayAccess { + public $values = []; + public function offsetSet($name, $value) { + $this->values[$name] = $value; + } + public function offsetGet($name) {} + public function offsetExists($name) {} + public function offsetUnset($name) {} +} + +$str = 'ab'; +list($str[0], $str[1]) = ['x', 'y']; +var_dump($str); + +$obj = new Obj; +list($obj->foo, $obj->bar) = ['foo', 'bar']; +var_dump($obj->values); + +$arr = new Arr; +list($arr['foo'], $arr['bar']) = ['foo', 'bar']; +var_dump($arr->values); + +?> +--EXPECT-- +string(2) "xy" +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} +array(2) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" +} diff --git a/Zend/tests/magic_const_in_global_scope.phpt b/Zend/tests/magic_const_in_global_scope.phpt new file mode 100644 index 0000000000..31f7eae6d7 --- /dev/null +++ b/Zend/tests/magic_const_in_global_scope.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test use of magic constants in the global scope +--FILE-- +<?php + +var_dump( + __LINE__, + __FILE__, + __DIR__, + __FUNCTION__, + __METHOD__, + __CLASS__, + __TRAIT__, + __NAMESPACE__ +); + +?> +--EXPECTF-- +int(4) +string(%d) "%s" +string(%d) "%s" +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" diff --git a/Zend/tests/methods-on-non-objects-args-catch.phpt b/Zend/tests/methods-on-non-objects-args-catch.phpt new file mode 100644 index 0000000000..853d2d5602 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-args-catch.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump($x->method(1, 2, 3)); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on null" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-array-access.phpt b/Zend/tests/methods-on-non-objects-array-access.phpt new file mode 100755 index 0000000000..be87457c6c --- /dev/null +++ b/Zend/tests/methods-on-non-objects-array-access.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects inside array access +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +$a= [null => 'OK']; +var_dump($a[$x->method()]); +echo "Alive\n"; +?> +--EXPECTF-- +int(4096) +string(%d) "Call to a member function method() on null" +string(2) "OK" +Alive
\ No newline at end of file diff --git a/Zend/tests/methods-on-non-objects-array-creation.phpt b/Zend/tests/methods-on-non-objects-array-creation.phpt new file mode 100755 index 0000000000..74cbb9c179 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-array-creation.phpt @@ -0,0 +1,35 @@ +--TEST-- +Catch method calls on non-objects inside array creation +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump([$x->method() => 'OK']); +var_dump([$x->method(), $x->method(), $x->method()]); +echo "Alive\n"; +?> +--EXPECTF-- +int(4096) +string(%d) "Call to a member function method() on null" +array(1) { + [""]=> + string(2) "OK" +} +int(4096) +string(%d) "Call to a member function method() on null" +int(4096) +string(%d) "Call to a member function method() on null" +int(4096) +string(%d) "Call to a member function method() on null" +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +Alive
\ No newline at end of file diff --git a/Zend/tests/methods-on-non-objects-as-arg.phpt b/Zend/tests/methods-on-non-objects-as-arg.phpt new file mode 100755 index 0000000000..13b83cb06e --- /dev/null +++ b/Zend/tests/methods-on-non-objects-as-arg.phpt @@ -0,0 +1,47 @@ +--TEST-- +Catch method calls on non-objects as argument +--FILE-- +<?php +function nesting() { + return func_get_args(); +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; +var_dump(nesting($x->method())); +var_dump(nesting(nesting($x->method()))); +var_dump(nesting($x->method(nesting($x->method())))); +var_dump(nesting($x->method(), $x->method())); +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +array(1) { + [0]=> + NULL +} +Called #2 +array(1) { + [0]=> + array(1) { + [0]=> + NULL + } +} +Called #3 +array(1) { + [0]=> + NULL +} +Called #4 +Called #5 +array(2) { + [0]=> + NULL + [1]=> + NULL +} +Alive diff --git a/Zend/tests/methods-on-non-objects-call-user-func.phpt b/Zend/tests/methods-on-non-objects-call-user-func.phpt new file mode 100644 index 0000000000..f76b7d43a0 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-call-user-func.phpt @@ -0,0 +1,13 @@ +--TEST-- +call_user_func() in combination with "Call to a member function method() on a non-object" +--FILE-- +<?php +$comparator= null; +var_dump(call_user_func([$comparator, 'compare'], 1, 2)); +echo "Alive\n"; +?> +--EXPECTF-- +Warning: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in %s on line %d +NULL +Alive + diff --git a/Zend/tests/methods-on-non-objects-catch.phpt b/Zend/tests/methods-on-non-objects-catch.phpt new file mode 100644 index 0000000000..bbfadac107 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-catch.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump($x->method()); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on null" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-chain.phpt b/Zend/tests/methods-on-non-objects-chain.phpt new file mode 100644 index 0000000000..30da254cd5 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-chain.phpt @@ -0,0 +1,22 @@ +--TEST-- +Catch chained method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump($x->method()->chained()->invocations()); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on null" +int(4096) +string(%d) "Call to a member function chained() on null" +int(4096) +string(%d) "Call to a member function invocations() on null" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-concat.phpt b/Zend/tests/methods-on-non-objects-concat.phpt new file mode 100755 index 0000000000..4ff47aa454 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-concat.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects inside concatenation +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +echo "Before\n".$x->method()."After\n"; +echo "Alive\n"; +?> +--EXPECTF-- +int(4096) +string(%d) "Call to a member function method() on null" +Before +After +Alive
\ No newline at end of file diff --git a/Zend/tests/methods-on-non-objects-dynamic.phpt b/Zend/tests/methods-on-non-objects-dynamic.phpt new file mode 100755 index 0000000000..11c5c9f44b --- /dev/null +++ b/Zend/tests/methods-on-non-objects-dynamic.phpt @@ -0,0 +1,23 @@ +--TEST-- +Catch method calls on non-objects with dynamic lookups +--FILE-- +<?php +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$arr= [null, 'method']; +var_dump($arr[0]->{$arr[1]}()); + +$fun= function() { return null; }; +var_dump($fun()->{'method'}()); + +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-eval.phpt b/Zend/tests/methods-on-non-objects-eval.phpt new file mode 100644 index 0000000000..8ee494c434 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-eval.phpt @@ -0,0 +1,18 @@ +--TEST-- +Indirect call inside eval to member function on non-object +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +var_dump(eval('$x->method(1, 2, 3);')); +echo "Alive\n"; +?> +--EXPECTF-- + +int(4096) +string(%d) "Call to a member function method() on null" +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-in-echo.phpt b/Zend/tests/methods-on-non-objects-in-echo.phpt new file mode 100755 index 0000000000..a0267c0ea5 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-in-echo.phpt @@ -0,0 +1,18 @@ +--TEST-- +Catch method calls on non-objects inside echo +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$x= null; +echo "Before\n", $x->method(), "After\n"; +echo "Alive\n"; +?> +--EXPECTF-- +Before +int(4096) +string(%d) "Call to a member function method() on null" +After +Alive
\ No newline at end of file diff --git a/Zend/tests/methods-on-non-objects-nested-calls-dyn.phpt b/Zend/tests/methods-on-non-objects-nested-calls-dyn.phpt new file mode 100755 index 0000000000..267104f1b3 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls-dyn.phpt @@ -0,0 +1,37 @@ +--TEST-- +Catch method calls on non-objects with nested dynamic calls +--FILE-- +<?php +function nested() { + throw new LogicException('Should not be called'); +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; + +$closure= function() { return nested(); }; +var_dump($x->method($closure())); + +$lambda= create_function('', 'return nested();'); +var_dump($x->method($lambda())); + +$func= 'nested'; +var_dump($x->method($func())); + +var_dump($x->method(call_user_func('nested'))); + +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Called #4 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested-calls-new.phpt b/Zend/tests/methods-on-non-objects-nested-calls-new.phpt new file mode 100755 index 0000000000..d8e3dd21bf --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls-new.phpt @@ -0,0 +1,37 @@ +--TEST-- +Catch method calls on non-objects with nested calls to new +--FILE-- +<?php +class Nesting { +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; +var_dump($x->method(new Nesting())); +var_dump($x->method(new Nesting(), new Nesting())); +var_dump($x->method(new Nesting(new Nesting()))); +var_dump($x->method(new Nesting($x->nested()))); +var_dump($x->method(new Nesting($x->nested(new Nesting())))); +var_dump($x->method($x->nested(new Nesting($x->deep())))); +var_dump($x->method([new Nesting()])); +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Called #4 +NULL +Called #5 +NULL +Called #6 +NULL +Called #7 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested-calls-nonct.phpt b/Zend/tests/methods-on-non-objects-nested-calls-nonct.phpt new file mode 100755 index 0000000000..a4529eecdc --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls-nonct.phpt @@ -0,0 +1,43 @@ +--TEST-- +Catch method calls on non-objects with nested non-compile-time-resolveable calls +--FILE-- +<?php +require('methods-on-non-objects-nested.inc'); + +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; + +var_dump($x->method(nested())); + +$closure= function() { return nested(); }; +var_dump($x->method($closure())); + +$lambda= create_function('', 'return nested();'); +var_dump($x->method($lambda())); + +$func= 'nested'; +var_dump($x->method($func())); + +var_dump($x->method(call_user_func('nested'))); +var_dump($x->method(call_user_func_array('nested', []))); + +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Called #4 +NULL +Called #5 +NULL +Called #6 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested-calls-ns.phpt b/Zend/tests/methods-on-non-objects-nested-calls-ns.phpt new file mode 100755 index 0000000000..b16f579fa9 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls-ns.phpt @@ -0,0 +1,26 @@ +--TEST-- +Catch method calls on non-objects with nested calls to namespaced functions with core counterparts +--FILE-- +<?php namespace test; +function strlen($str) { + throw new LogicException('Should not be called'); +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; +var_dump($x->method(strlen('Test'))); +var_dump($x->method(strlen('Test'), strlen('Test'))); +var_dump($x->method([strlen('Test')])); +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested-calls-static.phpt b/Zend/tests/methods-on-non-objects-nested-calls-static.phpt new file mode 100755 index 0000000000..64972ee871 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls-static.phpt @@ -0,0 +1,33 @@ +--TEST-- +Catch method calls on non-objects with nested calls to static methods +--FILE-- +<?php +class Nesting { + static function nested() { + throw new LogicException('Should not be called'); + } +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; +$class= 'Nesting'; +$method= 'nested'; +var_dump($x->method(Nesting::nested())); +var_dump($x->method($class::nested())); +var_dump($x->method($class::{$method}())); +var_dump($x->method([Nesting::nested()])); +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Called #4 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested-calls.phpt b/Zend/tests/methods-on-non-objects-nested-calls.phpt new file mode 100644 index 0000000000..b25aeafd9c --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested-calls.phpt @@ -0,0 +1,47 @@ +--TEST-- +Catch method calls on non-objects with nested function and method calls +--FILE-- +<?php +function nested() { + throw new LogicException('Should not be called'); +} +set_error_handler(function($code, $message) { + static $i= 0; + echo 'Called #'.(++$i)."\n"; +}); + +$x= null; +var_dump($x->method(nested())); +var_dump($x->method(nested(), nested())); +var_dump($x->method(nested(nested()))); +var_dump($x->method($x->nested())); +var_dump($x->method($x->nested(), $x->nested())); +var_dump($x->method($x->nested(nested()))); +var_dump($x->method($x->nested($x->deep()))); +var_dump($x->method($x->nested(nested($x->deep())))); +var_dump($x->method(nested(nested($x->nested())))); +var_dump($x->method([nested()])); +echo "Alive\n"; +?> +--EXPECTF-- +Called #1 +NULL +Called #2 +NULL +Called #3 +NULL +Called #4 +NULL +Called #5 +NULL +Called #6 +NULL +Called #7 +NULL +Called #8 +NULL +Called #9 +NULL +Called #10 +NULL +Alive diff --git a/Zend/tests/methods-on-non-objects-nested.inc b/Zend/tests/methods-on-non-objects-nested.inc new file mode 100755 index 0000000000..8511414b82 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-nested.inc @@ -0,0 +1,4 @@ +<?php +function nested() { + throw new LogicException('Should not be called'); +}
\ No newline at end of file diff --git a/Zend/tests/methods-on-non-objects-return-unused.phpt b/Zend/tests/methods-on-non-objects-return-unused.phpt new file mode 100755 index 0000000000..ab2951f94f --- /dev/null +++ b/Zend/tests/methods-on-non-objects-return-unused.phpt @@ -0,0 +1,17 @@ +--TEST-- +Catch method calls on non-objects without using return value +--INI-- +report_memleaks=1 +--FILE-- +<?php +set_error_handler(function($code, $message) { + echo "Caught\n"; +}); + +$x= null; +$x->method(); +echo "Alive\n"; +?> +--EXPECTF-- +Caught +Alive diff --git a/Zend/tests/methods-on-non-objects-throw.phpt b/Zend/tests/methods-on-non-objects-throw.phpt new file mode 100644 index 0000000000..874f57cb24 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-throw.phpt @@ -0,0 +1,29 @@ +--TEST-- +Convert errors to exceptions from method calls on non-objects raise recoverable errors +--FILE-- +<?php +set_error_handler(function($code, $message) { + echo "Raising...\n"; + if (0 === strncmp('Call', $message, 4)) { + throw new BadMethodCallException($message); + } else if (0 === strncmp('Argument', $message, 8)) { + throw new InvalidArgumentException($message); + } else { + trigger_error($message, E_USER_ERROR); + } +}, E_RECOVERABLE_ERROR); + +$x= null; +echo "Calling...\n"; +try { + $x->method(); +} catch (BadMethodCallException $e) { + echo "Caught expected ", $e->getMessage(), "!\n"; +} +echo "Alive\n"; +?> +--EXPECTF-- +Calling... +Raising... +Caught expected Call to a member function method() on null! +Alive diff --git a/Zend/tests/methods-on-non-objects-usort.phpt b/Zend/tests/methods-on-non-objects-usort.phpt new file mode 100644 index 0000000000..760d481b27 --- /dev/null +++ b/Zend/tests/methods-on-non-objects-usort.phpt @@ -0,0 +1,43 @@ +--TEST-- +usort() in combination with "Call to a member function method() on null" +--FILE-- +<?php +set_error_handler(function($code, $message) { + var_dump($code, $message); +}); + +$comparator= null; +$list= [1, 4, 2, 3, -1]; +usort($list, function($a, $b) use ($comparator) { + return $comparator->compare($a, $b); +}); +var_dump($list); +echo "Alive\n"; +?> +--EXPECTF-- +int(4096) +string(43) "Call to a member function compare() on null" +int(4096) +string(43) "Call to a member function compare() on null" +int(4096) +string(43) "Call to a member function compare() on null" +int(4096) +string(43) "Call to a member function compare() on null" +int(4096) +string(43) "Call to a member function compare() on null" +int(4096) +string(43) "Call to a member function compare() on null" +array(5) { + [0]=> + int(-1) + [1]=> + int(3) + [2]=> + int(2) + [3]=> + int(4) + [4]=> + int(1) +} +Alive + diff --git a/Zend/tests/methods-on-non-objects.phpt b/Zend/tests/methods-on-non-objects.phpt new file mode 100644 index 0000000000..01031b8b1d --- /dev/null +++ b/Zend/tests/methods-on-non-objects.phpt @@ -0,0 +1,12 @@ +--TEST-- +Method calls on non-objects raise recoverable errors +--FILE-- +<?php + +$x= null; +$x->method(); +echo "Should not get here!\n"; +?> +--EXPECTF-- + +Catchable fatal error: Call to a member function method() on null in %s on line %d diff --git a/Zend/tests/object_array_cast.phpt b/Zend/tests/object_array_cast.phpt new file mode 100644 index 0000000000..1cf3dbbd9c --- /dev/null +++ b/Zend/tests/object_array_cast.phpt @@ -0,0 +1,47 @@ +--TEST-- +(object) (array) and (array) (object) casts +--FILE-- +<?php + +$arr = [1, 2, 3]; +var_dump((object) (array) $arr); +var_dump($arr); + +$obj = (object) [1, 2, 3]; +var_dump((array) (object) $obj); +var_dump($obj); + +?> +--EXPECT-- +object(stdClass)#1 (3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +object(stdClass)#1 (3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/Zend/tests/special_name_error1.phpt b/Zend/tests/special_name_error1.phpt new file mode 100644 index 0000000000..63bf5a63fd --- /dev/null +++ b/Zend/tests/special_name_error1.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use special class name as namespace +--FILE-- +<?php + +namespace self; + +?> +--EXPECTF-- +Fatal error: Cannot use 'self' as namespace name in %s on line %d diff --git a/Zend/tests/special_name_error2.phpt b/Zend/tests/special_name_error2.phpt new file mode 100644 index 0000000000..08122b3249 --- /dev/null +++ b/Zend/tests/special_name_error2.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use special class name as alias +--FILE-- +<?php + +use Foo\Bar as self; + +?> +--EXPECTF-- +Fatal error: Cannot use Foo\Bar as self because 'self' is a special class name in %s on line %d diff --git a/Zend/tests/special_name_error3.phpt b/Zend/tests/special_name_error3.phpt new file mode 100644 index 0000000000..74e69f1938 --- /dev/null +++ b/Zend/tests/special_name_error3.phpt @@ -0,0 +1,10 @@ +--TEST-- +Cannot use special class name as trait name +--FILE-- +<?php + +trait self {} + +?> +--EXPECTF-- +Fatal error: Cannot use 'self' as class name as it is reserved in %s on line %d diff --git a/Zend/tests/this_as_lexical_var_error.phpt b/Zend/tests/this_as_lexical_var_error.phpt new file mode 100644 index 0000000000..d0e0106dae --- /dev/null +++ b/Zend/tests/this_as_lexical_var_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +Cannot use $this as lexical variable +--FILE-- +<?php + +class Foo { + public function fn() { + return function() use ($this) {}; + } +} + +?> +--EXPECTF-- +Fatal error: Cannot use $this as lexical variable in %s on line %d diff --git a/Zend/tests/varSyntax/indirectFcall.phpt b/Zend/tests/varSyntax/indirectFcall.phpt index 4cc5c1171a..5d616d59a2 100644 --- a/Zend/tests/varSyntax/indirectFcall.phpt +++ b/Zend/tests/varSyntax/indirectFcall.phpt @@ -34,6 +34,7 @@ $obj = new Test; ['Test', 'id']()()('var_dump')(11); 'id'()('id')('var_dump')(12); ('i' . 'd')()('var_dump')(13); +'\id'('var_dump')(14); ?> --EXPECT-- @@ -51,3 +52,4 @@ int(10) int(11) int(12) int(13) +int(14) diff --git a/Zend/tests/varSyntax/staticMember.phpt b/Zend/tests/varSyntax/staticMember.phpt index 22a1fa2b13..e32417771a 100644 --- a/Zend/tests/varSyntax/staticMember.phpt +++ b/Zend/tests/varSyntax/staticMember.phpt @@ -19,6 +19,7 @@ var_dump($A_str::$b); var_dump($A_obj::$b); var_dump(('A' . '')::$b); var_dump('A'::$b); +var_dump('\A'::$b); var_dump('A'[0]::$b); var_dump(A::$$b_str); var_dump(A::$$c_str[1]); @@ -33,5 +34,6 @@ int(0) int(0) int(0) int(0) +int(0) int(1) int(0) diff --git a/Zend/tests/varvars_by_ref.phpt b/Zend/tests/varvars_by_ref.phpt new file mode 100644 index 0000000000..3ee4776aba --- /dev/null +++ b/Zend/tests/varvars_by_ref.phpt @@ -0,0 +1,17 @@ +--TEST-- +Accessing variable variables using referenced names +--FILE-- +<?php + +$name = 'var'; +$ref =& $name; + +$$name = 42; +var_dump(isset($$name)); +unset($$name); +var_dump(isset($$name)); + +?> +--EXPECT-- +bool(true) +bool(false) |
