summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-06-27 12:33:20 +0300
committerDmitry Stogov <dmitry@zend.com>2018-06-27 12:33:20 +0300
commit6dc0cd868d972885249ce40f2d64097cd0ba6c1f (patch)
treea4ebb76a86ad86bdb1dc8fd2cca1319885858df9 /Zend/zend_object_handlers.c
parent1231b49271ca0fc933a00d657dcb6a34c388c41a (diff)
downloadphp-git-6dc0cd868d972885249ce40f2d64097cd0ba6c1f.tar.gz
Fixed ZTS race condition (zend_class_entry->ce_flags of internal classes must not be modified, because internal class enties are shared between threads)
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 86029ee4b9..fda969cd30 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1420,6 +1420,34 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
}
/* }}} */
+static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{ */
+{
+ int i;
+ zval *p;
+
+ if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
+ if (class_type->parent) {
+ zend_intenal_class_init_statics(class_type->parent);
+ }
+
+#if ZTS
+ CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
+#else
+ class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
+#endif
+ for (i = 0; i < class_type->default_static_members_count; i++) {
+ p = &class_type->default_static_members_table[i];
+ if (Z_TYPE_P(p) == IS_INDIRECT) {
+ zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
+ ZVAL_DEINDIRECT(q);
+ ZVAL_INDIRECT(&CE_STATIC_MEMBERS(class_type)[i], q);
+ } else {
+ ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
+ }
+ }
+ }
+} /* }}} */
+
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent) /* {{{ */
{
zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, property_name);
@@ -1448,11 +1476,15 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
/* check if static properties were destoyed */
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
+ if (ce->type == ZEND_INTERNAL_CLASS) {
+ zend_intenal_class_init_statics(ce);
+ } else {
undeclared_property:
- if (!silent) {
- zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
+ if (!silent) {
+ zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
+ }
+ return NULL;
}
- return NULL;
}
ret = CE_STATIC_MEMBERS(ce) + property_info->offset;