]> granicus.if.org Git - php/commitdiff
Fixed bug #39721 (Runtime inheritance causes data corruption)
authorDmitry Stogov <dmitry@php.net>
Tue, 5 Dec 2006 19:04:51 +0000 (19:04 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 5 Dec 2006 19:04:51 +0000 (19:04 +0000)
Zend/tests/bug39721.phpt [new file with mode: 0755]
Zend/zend_compile.c

diff --git a/Zend/tests/bug39721.phpt b/Zend/tests/bug39721.phpt
new file mode 100755 (executable)
index 0000000..63edfc2
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Bug #39721 (Runtime inheritance causes data corruption)
+--FILE--
+<?php
+class test2 {
+       private static $instances = 0;
+       public $instance;
+       
+       public function __construct() {
+               $this->instance = ++self::$instances;
+       }
+        
+}
+
+$foo = new test2();
+
+if (is_object($foo)) {
+       class test2_child extends test2 {
+        
+       }
+}
+
+$child = new test2_child();
+
+echo $foo->instance . "\n";
+echo $child->instance . "\n";
+?>
+--EXPECT--
+1
+2
index 1d89e7c3f24c369d1b2b35d7f299615ab15d9d50..0a6a230a78c892b18e3dc94cd331f4773f631293 100644 (file)
@@ -2316,10 +2316,17 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, zend_class_entry
 }
 
 
-static void inherit_static_prop(zval **p)
+static int inherit_static_prop(zval **p, int num_args, va_list args, zend_hash_key *key)
 {
-       (*p)->refcount++;
-       (*p)->is_ref = 1;
+       HashTable *target = va_arg(args, HashTable*);
+
+       if (!zend_u_hash_quick_exists(target, key->type, key->arKey, key->nKeyLength, key->h)) {
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
+               if (zend_u_hash_quick_add(target, key->type, key->arKey, key->nKeyLength, key->h, p, sizeof(zval*), NULL) == SUCCESS) {
+                       (*p)->refcount++;
+               }
+       }
+       return ZEND_HASH_APPLY_KEEP;
 }
 
 
@@ -2342,9 +2349,9 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
        if (parent_ce->type != ce->type) {
                /* User class extends internal class */
                zend_update_class_constants(parent_ce  TSRMLS_CC);
-               zend_hash_merge(&ce->default_static_members, CE_STATIC_MEMBERS(parent_ce), (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
+               zend_hash_apply_with_arguments(CE_STATIC_MEMBERS(parent_ce), (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);
        } else {
-               zend_hash_merge(&ce->default_static_members, &parent_ce->default_static_members, (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
+               zend_hash_apply_with_arguments(&parent_ce->default_static_members, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members TSRMLS_CC);
        }
        zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (copy_ctor_func_t) (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal : zend_duplicate_property_info), sizeof(zend_property_info), (merge_checker_func_t) do_inherit_property_access_check, ce);