diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-06-27 12:33:20 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-06-27 12:33:20 +0300 |
commit | 6dc0cd868d972885249ce40f2d64097cd0ba6c1f (patch) | |
tree | a4ebb76a86ad86bdb1dc8fd2cca1319885858df9 /Zend/zend_object_handlers.c | |
parent | 1231b49271ca0fc933a00d657dcb6a34c388c41a (diff) | |
download | php-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.c | 38 |
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; |