Skip to content

Commit 008bfcc

Browse files
committed
Use NO_DYNAMIC_PROPERTIES for Closure
Instead of manually implementing this, use the standard mechanism. This has minor behavior changes (e.g. doing an isset() will now return false instead of throwing) which are more in line with typical behavior.
1 parent e7135cb commit 008bfcc

7 files changed

+10
-58
lines changed

Zend/tests/bug50146.phpt

+2-6
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ var_dump($ref->hasProperty('b'));
1313
var_dump(isset($obj->a));
1414

1515
?>
16-
--EXPECTF--
16+
--EXPECT--
17+
bool(false)
1718
bool(false)
1819
bool(false)
19-
20-
Fatal error: Uncaught Error: Closure object cannot have properties in %s:%d
21-
Stack trace:
22-
#0 {main}
23-
thrown in %s on line %d

Zend/tests/closure_022.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ $foo = function() use ($a) {
88
$foo->a = 1;
99
?>
1010
--EXPECTF--
11-
Fatal error: Uncaught Error: Closure object cannot have properties in %sclosure_022.php:5
11+
Fatal error: Uncaught Error: Cannot create dynamic property Closure::$a in %s:%d
1212
Stack trace:
1313
#0 {main}
1414
thrown in %sclosure_022.php on line 5

Zend/tests/closure_031.phpt

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Closure 031: Closure properties with custom error handlers
33
--FILE--
44
<?php
55
function foo($errno, $errstr, $errfile, $errline) {
6-
echo "Error: $errstr\n";
6+
echo "Warning: $errstr\n";
77
}
88
set_error_handler('foo');
99
$foo = function() {
@@ -15,4 +15,5 @@ try {
1515
}
1616
?>
1717
--EXPECT--
18-
Error: Closure object cannot have properties
18+
Warning: Undefined property: Closure::$a
19+
NULL

Zend/tests/closure_write_prop.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ try {
1919

2020
?>
2121
--EXPECT--
22-
Closure object cannot have properties
22+
Cannot create dynamic property Closure::$b

Zend/zend_closures.c

-46
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@
2828
#include "zend_globals.h"
2929
#include "zend_closures_arginfo.h"
3030

31-
#define ZEND_CLOSURE_PRINT_NAME "Closure object"
32-
33-
#define ZEND_CLOSURE_PROPERTY_ERROR() \
34-
zend_throw_error(NULL, "Closure object cannot have properties")
35-
3631
typedef struct _zend_closure {
3732
zend_object std;
3833
zend_function func;
@@ -442,42 +437,6 @@ static zend_function *zend_closure_get_method(zend_object **object, zend_string
442437
}
443438
/* }}} */
444439

445-
static ZEND_COLD zval *zend_closure_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv) /* {{{ */
446-
{
447-
ZEND_CLOSURE_PROPERTY_ERROR();
448-
return &EG(uninitialized_zval);
449-
}
450-
/* }}} */
451-
452-
static ZEND_COLD zval *zend_closure_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot) /* {{{ */
453-
{
454-
ZEND_CLOSURE_PROPERTY_ERROR();
455-
return &EG(error_zval);
456-
}
457-
/* }}} */
458-
459-
static ZEND_COLD zval *zend_closure_get_property_ptr_ptr(zend_object *object, zend_string *member, int type, void **cache_slot) /* {{{ */
460-
{
461-
ZEND_CLOSURE_PROPERTY_ERROR();
462-
return NULL;
463-
}
464-
/* }}} */
465-
466-
static ZEND_COLD int zend_closure_has_property(zend_object *object, zend_string *member, int has_set_exists, void **cache_slot) /* {{{ */
467-
{
468-
if (has_set_exists != ZEND_PROPERTY_EXISTS) {
469-
ZEND_CLOSURE_PROPERTY_ERROR();
470-
}
471-
return 0;
472-
}
473-
/* }}} */
474-
475-
static ZEND_COLD void zend_closure_unset_property(zend_object *object, zend_string *member, void **cache_slot) /* {{{ */
476-
{
477-
ZEND_CLOSURE_PROPERTY_ERROR();
478-
}
479-
/* }}} */
480-
481440
static void zend_closure_free_storage(zend_object *object) /* {{{ */
482441
{
483442
zend_closure *closure = (zend_closure *)object;
@@ -645,11 +604,6 @@ void zend_register_closure_ce(void) /* {{{ */
645604
closure_handlers.free_obj = zend_closure_free_storage;
646605
closure_handlers.get_constructor = zend_closure_get_constructor;
647606
closure_handlers.get_method = zend_closure_get_method;
648-
closure_handlers.write_property = zend_closure_write_property;
649-
closure_handlers.read_property = zend_closure_read_property;
650-
closure_handlers.get_property_ptr_ptr = zend_closure_get_property_ptr_ptr;
651-
closure_handlers.has_property = zend_closure_has_property;
652-
closure_handlers.unset_property = zend_closure_unset_property;
653607
closure_handlers.compare = zend_closure_compare;
654608
closure_handlers.clone_obj = zend_closure_clone;
655609
closure_handlers.get_debug_info = zend_closure_get_debug_info;

Zend/zend_closures.stub.php

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
/** @generate-class-entries */
44

5+
/** @strict-properties */
56
final class Closure
67
{
78
private function __construct() {}

Zend/zend_closures_arginfo.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 62da9b1e75331f30a0c63e82c9fd366e26b5724d */
2+
* Stub hash: 7c4df531cdb30ac4206f43f0d40098666466b9a6 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Closure___construct, 0, 0, 0)
55
ZEND_END_ARG_INFO()
@@ -47,7 +47,7 @@ static zend_class_entry *register_class_Closure(void)
4747

4848
INIT_CLASS_ENTRY(ce, "Closure", class_Closure_methods);
4949
class_entry = zend_register_internal_class_ex(&ce, NULL);
50-
class_entry->ce_flags |= ZEND_ACC_FINAL;
50+
class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES;
5151

5252
return class_entry;
5353
}

0 commit comments

Comments
 (0)