summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-06-13 10:49:07 +0800
committerXinchen Hui <laruence@php.net>2015-06-13 10:49:20 +0800
commitd96dda8d49711303d14471ac59ba929892bc532a (patch)
tree1a8580a5ab51c1d626f04937d2bee584bc1646d8
parent49a8f801c737516f7912212779090628dec224e6 (diff)
downloadphp-git-d96dda8d49711303d14471ac59ba929892bc532a.tar.gz
Fixed Bug #69761 (Serialization of anonymous classes should be prevented)
And also cleanup anonymous class compiling, it make no sense prefix a namespace to anonymous class name. and it is always lowcased and interned string.
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/anon/006.phpt2
-rw-r--r--Zend/tests/anon/007.phpt2
-rw-r--r--Zend/tests/bug69761.phpt15
-rw-r--r--Zend/zend_compile.c64
5 files changed, 51 insertions, 34 deletions
diff --git a/NEWS b/NEWS
index 77041ed089..d09da24c6b 100644
--- a/NEWS
+++ b/NEWS
@@ -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);