diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/anon/006.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/anon/007.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/bug69761.phpt | 15 | ||||
-rw-r--r-- | Zend/zend_compile.c | 64 |
5 files changed, 51 insertions, 34 deletions
@@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug #69805 (null ptr deref and seg fault in zend_resolve_class_name). (Laruence) + . Fixed bug #69761 (Serialization of anonymous classes should be prevented). + (Laruence) . Fixed bug #69551 (parse_ini_file() and parse_ini_string() segmentation fault). (Christoph M. Becker) . Fixed bug #69781 (phpinfo() reports Professional Editions of Windows diff --git a/Zend/tests/anon/006.phpt b/Zend/tests/anon/006.phpt index e5dc1226d8..2b8888c497 100644 --- a/Zend/tests/anon/006.phpt +++ b/Zend/tests/anon/006.phpt @@ -10,6 +10,6 @@ namespace { var_dump ($hello); } --EXPECTF-- -object(lone\class@%s)#1 (0) { +object(class@%s)#1 (0) { } diff --git a/Zend/tests/anon/007.phpt b/Zend/tests/anon/007.phpt index 12f4da6653..59d2441760 100644 --- a/Zend/tests/anon/007.phpt +++ b/Zend/tests/anon/007.phpt @@ -18,6 +18,6 @@ namespace lone { new Outer(); } --EXPECTF-- -object(lone\class@%s)#2 (0) { +object(class@%s)#2 (0) { } diff --git a/Zend/tests/bug69761.phpt b/Zend/tests/bug69761.phpt new file mode 100644 index 0000000000..4b7e2787d8 --- /dev/null +++ b/Zend/tests/bug69761.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #69761 (Serialization of anonymous classes should be prevented) +--FILE-- +<?php +$instance = new class('foo') { + public function __construct($i) { + } +}; +var_dump(serialize($instance)); +?> +--EXPECTF-- +Fatal error: Uncaught Exception: Serialization of 'class@%s' is not allowed in %sbug69761.php:%d +Stack trace: +#0 %sbug69761.php(%d): serialize(Object(class@%s + thrown in %sbug69761.php on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 902d37c503..a4d6257d2c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4989,8 +4989,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ zend_ast *extends_ast = decl->child[0]; zend_ast *implements_ast = decl->child[1]; zend_ast *stmt_ast = decl->child[2]; - - zend_string *name = decl->name, *lcname, *import_name = NULL; + zend_string *name, *lcname, *import_name = NULL; zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry)); zend_op *opline; znode declare_node, extends_node; @@ -4998,43 +4997,37 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ zend_class_entry *original_ce = CG(active_class_entry); znode original_implementing_class = FC(implementing_class); - if (decl->flags & ZEND_ACC_ANON_CLASS) { - decl->name = name = zend_generate_anon_class_name(decl->lex_pos); - - /* Serialization is not supported for anonymous classes */ - ce->serialize = zend_class_serialize_deny; - ce->unserialize = zend_class_unserialize_deny; - } - - if (CG(active_class_entry) && !(decl->flags & ZEND_ACC_ANON_CLASS)) { - zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); - } - - zend_assert_valid_class_name(name); + if (EXPECTED(decl->flags & ZEND_ACC_ANON_CLASS) == 0) { + if (CG(active_class_entry)) { + zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); + } + name = decl->name; + zend_assert_valid_class_name(name); + lcname = zend_string_tolower(name); + if (FC(current_namespace)) { + name = zend_prefix_with_ns(name); - lcname = zend_string_tolower(name); + zend_string_release(lcname); + lcname = zend_string_tolower(name); + } else { + zend_string_addref(name); + } - if (FC(imports)) { - import_name = zend_hash_find_ptr(FC(imports), lcname); - } + if (FC(imports)) { + import_name = zend_hash_find_ptr(FC(imports), lcname); + } - if (FC(current_namespace)) { - name = zend_prefix_with_ns(name); + if (import_name && !zend_string_equals_ci(lcname, import_name)) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s " + "because the name is already in use", name->val); + } - zend_string_release(lcname); - lcname = zend_string_tolower(name); + name = zend_new_interned_string(name); + lcname = zend_new_interned_string(lcname); } else { - zend_string_addref(name); + lcname = name = zend_generate_anon_class_name(decl->lex_pos); } - if (import_name && !zend_string_equals_ci(lcname, import_name)) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s " - "because the name is already in use", name->val); - } - - name = zend_new_interned_string(name); - lcname = zend_new_interned_string(lcname); - ce->type = ZEND_USER_CLASS; ce->name = name; zend_initialize_class_data(ce, 1); @@ -5043,10 +5036,17 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ ce->info.user.filename = zend_get_compiled_filename(); ce->info.user.line_start = decl->start_lineno; ce->info.user.line_end = decl->end_lineno; + if (decl->doc_comment) { ce->info.user.doc_comment = zend_string_copy(decl->doc_comment); } + if (UNEXPECTED(decl->flags & ZEND_ACC_ANON_CLASS)) { + /* Serialization is not supported for anonymous classes */ + ce->serialize = zend_class_serialize_deny; + ce->unserialize = zend_class_unserialize_deny; + } + if (extends_ast) { if (!zend_is_const_default_class_ref(extends_ast)) { zend_string *extends_name = zend_ast_get_str(extends_ast); |