]> granicus.if.org Git - php/commitdiff
Squashed commit of the following:
authorDmitry Stogov <dmitry@zend.com>
Tue, 11 Sep 2018 08:56:45 +0000 (11:56 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 11 Sep 2018 08:56:45 +0000 (11:56 +0300)
commit 2d3cac9e005d6bef9aa73ab57cc674aa53125954
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Tue Sep 11 11:54:47 2018 +0300

    Fixed static property access

commit 31786ee27282f319f3ef2a07635b1f325cbd67c6
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Tue Sep 11 11:05:29 2018 +0300

    Avoid duplicate checks

commit 5ae502b979ea33d058d01a9421eec5afd0084e8d
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Tue Sep 11 10:39:17 2018 +0300

    Optimization

commit 82c17f0e8af02c9cf7d1bbdae4e3158330148203
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Tue Sep 11 09:26:50 2018 +0300

    Removed unused zend_duplicate_property_info()

commit ba53d1d0dd91d5530328a11cac93ff9e75c462b5
Merge: eacc11b8fd c4b14370cf
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Tue Sep 11 09:24:13 2018 +0300

    Merge branch 'master' into shadow

    * master:
      7.0.33 next
      Sync NEWS [ci skip]
      add NEWS for 76582
      Enforce ordering of property compare in object comparisons
      Fixed wrong assertion
      Skip test on unsuitable env

commit eacc11b8fdeb002ee6a149defd8b5a8c3412896a
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Mon Sep 10 13:12:39 2018 +0300

    Fixed failure of ext/spl/tests/array_017.phpt

commit 62d1871430a1b81c84b790460afff0682648689a
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Mon Sep 10 11:55:07 2018 +0300

    Fixed issues

commit 1d37e3a40e4d07c4b933ed6f9d2e649dd01180f0
Merge: d6c3f098b6 1e550e6f7e
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Mon Sep 10 10:21:20 2018 +0300

    Merge branch 'master' into shadow

    * master:
      Update NEWS
      Fix for bug #76582
      Fix ssl stream reneg limit test to print only after first renegotiation
      Make a copy unconditionally
      Fix memory leak in pcre cache
      Remove not needed checking for <errno.h>
      Remove HAVE_ASSERT_H
      Add test for bug #76850
      Fixed bug #76850 Exit code mangled by set locale/preg_match
      Remove empty PHP tags from test
      Fix #75273: php_zlib_inflate_filter() may not update bytes_consumed
      Fix PCRE2 exclusion and remove dead libs in Makefile.gcov
      Report mem leaks to stderr if no Win debugger is present
      Use combined assignment contanation operator
      Fixed bug #76796
      Support fixed address mmap without replacement

commit d6c3f098b6015e76d042691de0af2e1426c66829
Author: Dmitry Stogov <dmitry@zend.com>
Date:   Fri Sep 7 13:56:30 2018 +0300

    Get rid of ZEND_ACC_SHADOW

UPGRADING.INTERNALS
Zend/tests/bug70873.phpt
Zend/zend_builtin_functions.c
Zend/zend_compile.h
Zend/zend_inheritance.c
Zend/zend_object_handlers.c
Zend/zend_opcode.c
ext/reflection/php_reflection.c
ext/tidy/tests/027.phpt

index f28e25aeca13beffac7fdbc95dc0ea542d709215..b9126ed3879c522f2eaa8c80784d96fe94d09727 100644 (file)
@@ -3,7 +3,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES
 1. Internal API changes
   a. php_sys_symlink() and php_sys_link()
   b. zend_lookup_class_ex() and zend_fetch_class_by_name()
-  c. Function flags
+  c. Function/property flags
 
 2. Build system changes
   a. Unix build system changes
@@ -23,12 +23,15 @@ PHP 7.4 INTERNALS UPGRADE NOTES
     changed to accept optional lower-case class name as zend_string*,
     instead of zval*.
 
- c. Function flags changes
+ c. Function/property flags changes
     - ZEND_ACC_CTOR and ZEND_ACC_DTOR are removed. It's possible to check if
       method is a constructor/destructor using the following condition
       (func->commpon.scope->constructor == func).
     - ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
       during inheritance).
+    - ZEND_ACC_SHADOW property flag is removed. Instead of creating shadow
+      clone, now we use the same private property_info, and should also
+      check property_info->ce (in the same way as with methods).
 
 ========================
 2. Build system changes
index 3edb7eac43de5a119b9763dc10642bac68c207dd..aecc0e879bcc83ebba3f23deeff82262b7561569 100644 (file)
@@ -27,7 +27,7 @@ $b = new C;
 $b->bar();
 ?>
 --EXPECTF--
-Fatal error: Uncaught Error: Cannot access  property B::$x in %sbug70873.php:%d
+Fatal error: Uncaught Error: Cannot access private property B::$x in %sbug70873.php:%d
 Stack trace:
 #0 %sbug70873.php(%d): B->bar()
 #1 {main}
index d83169cac8aded9c9d04734eb1e755ef52894180..88c24ba8aeb377f79f41ca8cb26bcd99aff3da00 100644 (file)
@@ -1097,13 +1097,10 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
        zend_string *key;
 
        ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
-               if (((prop_info->flags & ZEND_ACC_SHADOW) &&
-                    prop_info->ce != scope) ||
-                   ((prop_info->flags & ZEND_ACC_PROTECTED) &&
+               if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
                     !zend_check_protected(prop_info->ce, scope)) ||
                    ((prop_info->flags & ZEND_ACC_PRIVATE) &&
-                     ce != scope &&
-                         prop_info->ce != scope)) {
+                     prop_info->ce != scope)) {
                        continue;
                }
                prop = NULL;
@@ -1403,8 +1400,10 @@ ZEND_FUNCTION(property_exists)
                RETURN_NULL();
        }
 
-       if ((property_info = zend_hash_find_ptr(&ce->properties_info, property)) != NULL
-               && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
+       property_info = zend_hash_find_ptr(&ce->properties_info, property);
+       if (property_info != NULL
+        && (!(property_info->flags & ZEND_ACC_PRIVATE)
+         || property_info->ce == ce)) {
                RETURN_TRUE;
        }
 
index b7f7014281962422f83a7c50c34374ee867edff5..ba4550579ea32db420f67438e7a157c4ce0b67f8 100644 (file)
@@ -212,15 +212,12 @@ typedef struct _zend_oparray_context {
 #define ZEND_ACC_PROTECTED               (1 <<  9) /*     |  X  |  X  |  X  */
 #define ZEND_ACC_PRIVATE                 (1 << 10) /*     |  X  |  X  |  X  */
 /*                                                        |     |     |     */
-/* TODO: explain the name ???                             |     |     |     */
+/* Property or method overrides private one               |     |     |     */
 #define ZEND_ACC_CHANGED                 (1 << 11) /*     |  X  |  X  |     */
 /*                                                        |     |     |     */
 /* TODO: used only by ext/reflection ???                  |     |     |     */
 #define ZEND_ACC_IMPLICIT_PUBLIC         (1 << 12) /*     |  ?  |  ?  |  ?  */
 /*                                                        |     |     |     */
-/* Shadow of parent's private method/property             |     |     |     */
-#define ZEND_ACC_SHADOW                  (1 << 17) /*     |  ?  |  X  |     */
-/*                                                        |     |     |     */
 /* Class Flags (unused: 0, 1, 3, 11-18, 21, 25...)        |     |     |     */
 /* ===========                                            |     |     |     */
 /*                                                        |     |     |     */
index c6a89754c958e52478c19b98c2317b377e3956a9..eef6c5b3a594fa95a588d582b64c4dd74a06c17d 100644 (file)
@@ -31,20 +31,6 @@ static void overridden_ptr_dtor(zval *zv) /* {{{ */
 }
 /* }}} */
 
-static zend_property_info *zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
-{
-       zend_property_info* new_property_info;
-
-       new_property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
-       memcpy(new_property_info, property_info, sizeof(zend_property_info));
-       zend_string_addref(new_property_info->name);
-       if (new_property_info->doc_comment) {
-               zend_string_addref(new_property_info->doc_comment);
-       }
-       return new_property_info;
-}
-/* }}} */
-
 static zend_property_info *zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
 {
        zend_property_info* new_property_info = pemalloc(sizeof(zend_property_info), 1);
@@ -171,16 +157,14 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
 
 char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
 {
-       if (fn_flags & ZEND_ACC_PRIVATE) {
-               return "private";
-       }
-       if (fn_flags & ZEND_ACC_PROTECTED) {
-               return "protected";
-       }
        if (fn_flags & ZEND_ACC_PUBLIC) {
                return "public";
+       } else if (fn_flags & ZEND_ACC_PRIVATE) {
+               return "private";
+       } else {
+               ZEND_ASSERT(fn_flags & ZEND_ACC_PROTECTED);
+               return "protected";
        }
-       return "";
 }
 /* }}} */
 
@@ -684,7 +668,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
 
        if (UNEXPECTED(child)) {
                child_info = Z_PTR_P(child);
-               if (UNEXPECTED(parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_SHADOW))) {
+               if (UNEXPECTED(parent_info->flags & ZEND_ACC_PRIVATE)) {
                        child_info->flags |= ZEND_ACC_CHANGED;
                } else {
                        if (UNEXPECTED((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC))) {
@@ -711,20 +695,10 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
                        }
                }
        } else {
-               if (UNEXPECTED(parent_info->flags & ZEND_ACC_PRIVATE)) {
-                       if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
-                               child_info = zend_duplicate_property_info_internal(parent_info);
-                       } else {
-                               child_info = zend_duplicate_property_info(parent_info);
-                       }
-                       child_info->flags &= ~ZEND_ACC_PRIVATE; /* it's not private anymore */
-                       child_info->flags |= ZEND_ACC_SHADOW; /* but it's a shadow of private */
+               if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
+                       child_info = zend_duplicate_property_info_internal(parent_info);
                } else {
-                       if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
-                               child_info = zend_duplicate_property_info_internal(parent_info);
-                       } else {
-                               child_info = parent_info;
-                       }
+                       child_info = parent_info;
                }
                _zend_hash_append_ptr(&ce->properties_info, key, child_info);
        }
@@ -1681,11 +1655,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
 
                        /* next: check for conflicts with current class */
                        if ((coliding_prop = zend_hash_find_ptr(&ce->properties_info, prop_name)) != NULL) {
-                               if (coliding_prop->flags & ZEND_ACC_SHADOW) {
-                                       zend_string_release_ex(coliding_prop->name, 0);
-                                       if (coliding_prop->doc_comment) {
-                                               zend_string_release_ex(coliding_prop->doc_comment, 0);
-                    }
+                               if ((coliding_prop->flags & ZEND_ACC_PRIVATE) && coliding_prop->ce != ce) {
                                        zend_hash_del(&ce->properties_info, prop_name);
                                        flags |= ZEND_ACC_CHANGED;
                                } else {
index 29fd0b29bcc88800900dd70f513d972df3891a5a..a7a863ff120be651833849c8eb91a9c08a2a566e 100644 (file)
@@ -325,22 +325,19 @@ static zend_always_inline int zend_verify_property_access(zend_property_info *pr
 
        if (property_info->flags & ZEND_ACC_PUBLIC) {
                return 1;
-       } else if (property_info->flags & ZEND_ACC_PRIVATE) {
+       } else {
                if (EG(fake_scope)) {
                        scope = EG(fake_scope);
                } else {
                        scope = zend_get_executed_scope();
                }
-               return (ce == scope || property_info->ce == scope);
-       } else if (property_info->flags & ZEND_ACC_PROTECTED) {
-               if (EG(fake_scope)) {
-                       scope = EG(fake_scope);
+               if (property_info->flags & ZEND_ACC_PRIVATE) {
+                       return property_info->ce == scope;
                } else {
-                       scope = zend_get_executed_scope();
+                       ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
+                       return zend_check_protected(property_info->ce, scope);
                }
-               return zend_check_protected(property_info->ce, scope);
        }
-       return 0;
 }
 /* }}} */
 
@@ -377,39 +374,62 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
        if (EXPECTED(zv != NULL)) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
                flags = property_info->flags;
-               if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
-                       /* if it's a shadow - go to access it's private */
-                       property_info = NULL;
-               } else {
-                       if (EXPECTED(zend_verify_property_access(property_info, ce) != 0)) {
-                               if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
-                                       || UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
-                                       if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
-                                               if (!silent) {
-                                                       zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
-                                               }
-                                               return ZEND_DYNAMIC_PROPERTY_OFFSET;
+
+               if (flags & ZEND_ACC_PUBLIC) {
+                       if (!(flags & ZEND_ACC_CHANGED)) {
+no_changed:
+                               if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
+                                       if (!silent) {
+                                               zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
                                        }
-                                       goto exit;
+                                       return ZEND_DYNAMIC_PROPERTY_OFFSET;
+                               }
+                               goto exit;
+                       }
+                       goto check_scope;
+               } else {
+                       if (EG(fake_scope)) {
+                               scope = EG(fake_scope);
+                       } else {
+                               scope = zend_get_executed_scope();
+                       }
+                       if (flags & ZEND_ACC_PRIVATE) {
+                               if (property_info->ce == scope) {
+                                       goto no_changed;
+                               } else if (property_info->ce != ce) {
+                                       /* if it's a shadow - go to access it's private */
+                                       property_info = NULL;
+                               } else {
+                                       /* Try to look in the scope instead */
+                                       property_info = ZEND_WRONG_PROPERTY_INFO;
                                }
                        } else {
-                               /* Try to look in the scope instead */
-                               property_info = ZEND_WRONG_PROPERTY_INFO;
+                               ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
+                               if (zend_check_protected(property_info->ce, scope)) {
+                                       if (!(flags & ZEND_ACC_CHANGED)) {
+                                               goto no_changed;
+                                       }
+                               } else {
+                                       /* Try to look in the scope instead */
+                                       property_info = ZEND_WRONG_PROPERTY_INFO;
+                               }
                        }
                }
-       }
-
-       if (EG(fake_scope)) {
-               scope = EG(fake_scope);
        } else {
-               scope = zend_get_executed_scope();
+check_scope:
+               if (EG(fake_scope)) {
+                       scope = EG(fake_scope);
+               } else {
+                       scope = zend_get_executed_scope();
+               }
        }
 
        if (scope != ce
                && scope
                && is_derived_class(ce, scope)
                && (zv = zend_hash_find(&scope->properties_info, member)) != NULL
-               && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
+               && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE
+               && ((zend_property_info*)Z_PTR_P(zv))->ce == scope) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
                if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) {
                        return ZEND_DYNAMIC_PROPERTY_OFFSET;
@@ -457,38 +477,61 @@ ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_s
        if (EXPECTED(zv != NULL)) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
                flags = property_info->flags;
-               if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
-                       /* if it's a shadow - go to access it's private */
-                       property_info = NULL;
-               } else {
-                       if (EXPECTED(zend_verify_property_access(property_info, ce) != 0)) {
-                               if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
-                                       || UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
-                                       if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
-                                               if (!silent) {
-                                                       zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
-                                               }
+
+               if (flags & ZEND_ACC_PUBLIC) {
+                       if (!(flags & ZEND_ACC_CHANGED)) {
+no_changed:
+                               if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
+                                       if (!silent) {
+                                               zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
                                        }
-                                       goto exit;
+                               }
+                               goto exit;
+                       }
+                       goto check_scope;
+               } else {
+                       if (EG(fake_scope)) {
+                               scope = EG(fake_scope);
+                       } else {
+                               scope = zend_get_executed_scope();
+                       }
+                       if (flags & ZEND_ACC_PRIVATE) {
+                               if (property_info->ce == scope) {
+                                       goto no_changed;
+                               } else if (property_info->ce != ce) {
+                                       /* if it's a shadow - go to access it's private */
+                                       property_info = NULL;
+                               } else {
+                                       /* Try to look in the scope instead */
+                                       property_info = ZEND_WRONG_PROPERTY_INFO;
                                }
                        } else {
-                               /* Try to look in the scope instead */
-                               property_info = ZEND_WRONG_PROPERTY_INFO;
+                               ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
+                               if (zend_check_protected(property_info->ce, scope)) {
+                                       if (!(flags & ZEND_ACC_CHANGED)) {
+                                               goto no_changed;
+                                       }
+                               } else {
+                                       /* Try to look in the scope instead */
+                                       property_info = ZEND_WRONG_PROPERTY_INFO;
+                               }
                        }
                }
-       }
-
-       if (EG(fake_scope)) {
-               scope = EG(fake_scope);
        } else {
-               scope = zend_get_executed_scope();
+check_scope:
+               if (EG(fake_scope)) {
+                       scope = EG(fake_scope);
+               } else {
+                       scope = zend_get_executed_scope();
+               }
        }
 
        if (scope != ce
                && scope
                && is_derived_class(ce, scope)
                && (zv = zend_hash_find(&scope->properties_info, member)) != NULL
-               && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
+               && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE
+               && ((zend_property_info*)Z_PTR_P(zv))->ce == scope) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
        } else if (UNEXPECTED(property_info == NULL)) {
 exit_dynamic:
@@ -519,35 +562,43 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf
        const char *prop_name;
        zend_string *member;
        size_t prop_name_len;
+       zend_class_entry *scope;
 
        if (ZSTR_VAL(prop_info_name)[0] == 0) {
                zend_unmangle_property_name_ex(prop_info_name, &class_name, &prop_name, &prop_name_len);
                member = zend_string_init(prop_name, prop_name_len, 0);
-       } else {
-               member = zend_string_copy(prop_info_name);
-       }
-       property_info = zend_get_property_info(zobj->ce, member, 1);
-       zend_string_release_ex(member, 0);
-       if (property_info == NULL) {
-               /* undefined public property */
-               if (class_name && class_name[0] != '*') {
-                       /* we we're looking for a private prop */
+               property_info = zend_get_property_info(zobj->ce, member, 1);
+               zend_string_release_ex(member, 0);
+               if (property_info == NULL) {
+                       if (class_name[0] != '*') {
+                               /* we we're looking for a private prop */
+                               return FAILURE;
+                       }
+                       return SUCCESS;
+               } else if (property_info == ZEND_WRONG_PROPERTY_INFO) {
                        return FAILURE;
                }
-               return SUCCESS;
-       } else if (property_info == ZEND_WRONG_PROPERTY_INFO) {
-               return FAILURE;
-       }
-       if (class_name && class_name[0] != '*') {
-               if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
-                       /* we we're looking for a private prop but found a non private one of the same name */
-                       return FAILURE;
-               } else if (strcmp(ZSTR_VAL(prop_info_name)+1, ZSTR_VAL(property_info->name)+1)) {
-                       /* we we're looking for a private prop but found a private one of the same name but another class */
+               if (class_name[0] != '*') {
+                       if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
+                               /* we we're looking for a private prop but found a non private one of the same name */
+                               return FAILURE;
+                       } else if (strcmp(ZSTR_VAL(prop_info_name)+1, ZSTR_VAL(property_info->name)+1)) {
+                               /* we we're looking for a private prop but found a private one of the same name but another class */
+                               return FAILURE;
+                       }
+               } else {
+                       ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
+               }
+       } else {
+               property_info = zend_get_property_info(zobj->ce, prop_info_name, 1);
+               if (property_info == NULL) {
+                       return SUCCESS;
+               } else if (property_info == ZEND_WRONG_PROPERTY_INFO) {
                        return FAILURE;
                }
+               ZEND_ASSERT(property_info->flags & ZEND_ACC_PUBLIC);
        }
-       return zend_verify_property_access(property_info, zobj->ce) ? SUCCESS : FAILURE;
+       return SUCCESS;
 }
 /* }}} */
 
@@ -1457,40 +1508,38 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
        if (constructor) {
                if (constructor->op_array.fn_flags & ZEND_ACC_PUBLIC) {
                        /* No further checks necessary */
-               } else if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
-                       /* Ensure that if we're calling a private function, we're allowed to do so.
-                        */
+               } else {
                        if (EG(fake_scope)) {
                                scope = EG(fake_scope);
                        } else {
                                scope = zend_get_executed_scope();
                        }
-                       if (UNEXPECTED(constructor->common.scope != scope)) {
-                               if (scope) {
-                                       zend_throw_error(NULL, "Call to private %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
-                                       constructor = NULL;
-                               } else {
-                                       zend_throw_error(NULL, "Call to private %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
-                                       constructor = NULL;
+                       if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
+                               /* Ensure that if we're calling a private function, we're allowed to do so.
+                                */
+                               if (UNEXPECTED(constructor->common.scope != scope)) {
+                                       if (scope) {
+                                               zend_throw_error(NULL, "Call to private %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
+                                               constructor = NULL;
+                                       } else {
+                                               zend_throw_error(NULL, "Call to private %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
+                                               constructor = NULL;
+                                       }
                                }
-                       }
-               } else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) {
-                       /* Ensure that if we're calling a protected function, we're allowed to do so.
-                        * Constructors only have prototype if they are defined by an interface but
-                        * it is the compilers responsibility to take care of the prototype.
-                        */
-                       if (EG(fake_scope)) {
-                               scope = EG(fake_scope);
                        } else {
-                               scope = zend_get_executed_scope();
-                       }
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
-                               if (scope) {
-                                       zend_throw_error(NULL, "Call to protected %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
-                                       constructor = NULL;
-                               } else {
-                                       zend_throw_error(NULL, "Call to protected %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
-                                       constructor = NULL;
+                               ZEND_ASSERT(constructor->common.fn_flags & ZEND_ACC_PROTECTED);
+                               /* Ensure that if we're calling a protected function, we're allowed to do so.
+                                * Constructors only have prototype if they are defined by an interface but
+                                * it is the compilers responsibility to take care of the prototype.
+                                */
+                               if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
+                                       if (scope) {
+                                               zend_throw_error(NULL, "Call to protected %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
+                                               constructor = NULL;
+                                       } else {
+                                               zend_throw_error(NULL, "Call to protected %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
+                                               constructor = NULL;
+                                       }
                                }
                        }
                }
index 46f9508b956c66a91f0e79691026430eb0c33a54..3019174ff23583b5b6e8f668d2ec4b37a9f7beb1 100644 (file)
@@ -242,7 +242,7 @@ ZEND_API void destroy_zend_class(zval *zv)
                                efree(ce->default_static_members_table);
                        }
                        ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
-                               if (prop_info->ce == ce || (prop_info->flags & ZEND_ACC_SHADOW)) {
+                               if (prop_info->ce == ce) {
                                        zend_string_release_ex(prop_info->name, 0);
                                        if (prop_info->doc_comment) {
                                                zend_string_release_ex(prop_info->doc_comment, 0);
index eeb3ac66b803e38247a149acb5eccc903ade3226..fbacb9e92ef8fd91a3c654e6d34eb2d312d22a85 100644 (file)
@@ -366,7 +366,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
                zend_property_info *prop;
 
                ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
-                       if(prop->flags & ZEND_ACC_SHADOW) {
+                       if ((prop->flags & ZEND_ACC_PRIVATE) && prop->ce != ce) {
                                count_shadow_props++;
                        } else if (prop->flags & ZEND_ACC_STATIC) {
                                count_static_props++;
@@ -380,7 +380,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
                zend_property_info *prop;
 
                ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
-                       if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
+                       if ((prop->flags & ZEND_ACC_STATIC) && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
                                _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
                        }
                } ZEND_HASH_FOREACH_END();
@@ -427,7 +427,8 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
                zend_property_info *prop;
 
                ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
-                       if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
+                       if (!(prop->flags & ZEND_ACC_STATIC)
+                        && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
                                _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
                        }
                } ZEND_HASH_FOREACH_END();
@@ -1242,7 +1243,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
                        tmp_ce = tmp_ce->parent;
                }
 
-               if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
+               if (tmp_info && (!(tmp_info->flags & ZEND_ACC_PRIVATE) || tmp_info->ce == tmp_ce)) { /* found something and it's not a parent's private */
                        prop = tmp_info;
                } else { /* not found, use initial value */
                        ce = store_ce;
@@ -3764,9 +3765,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
        zend_string *key;
 
        ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
-               if (((prop_info->flags & ZEND_ACC_SHADOW) &&
-                    prop_info->ce != ce) ||
-                   ((prop_info->flags & ZEND_ACC_PROTECTED) &&
+               if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
                     !zend_check_protected(prop_info->ce, ce)) ||
                    ((prop_info->flags & ZEND_ACC_PRIVATE) &&
                     prop_info->ce != ce)) {
@@ -4220,7 +4219,7 @@ ZEND_METHOD(reflection_class, hasProperty)
 
        GET_REFLECTION_OBJECT_PTR(ce);
        if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
-               if (property_info->flags & ZEND_ACC_SHADOW) {
+               if ((property_info->flags & ZEND_ACC_PRIVATE) && property_info->ce != ce) {
                        RETURN_FALSE;
                }
                RETURN_TRUE;
@@ -4255,7 +4254,7 @@ ZEND_METHOD(reflection_class, getProperty)
 
        GET_REFLECTION_OBJECT_PTR(ce);
        if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
-               if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
+               if (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce) {
                        reflection_property_factory(ce, name, property_info, return_value);
                        return;
                }
@@ -4297,7 +4296,10 @@ ZEND_METHOD(reflection_class, getProperty)
                }
                ce = ce2;
 
-               if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
+               property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len);
+               if (property_info != NULL
+                && (!(property_info->flags & ZEND_ACC_PRIVATE)
+                 || property_info->ce == ce)) {
                        reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value);
                        return;
                }
@@ -4316,7 +4318,7 @@ static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *has
        zval *retval = va_arg(args, zval*);
        long filter = va_arg(args, long);
 
-       if (pptr->flags & ZEND_ACC_SHADOW) {
+       if ((pptr->flags & ZEND_ACC_PRIVATE) && pptr->ce != ce) {
                return 0;
        }
 
@@ -5278,7 +5280,10 @@ ZEND_METHOD(reflection_property, __construct)
                        /* returns out of this function */
        }
 
-       if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) == NULL || (property_info->flags & ZEND_ACC_SHADOW)) {
+       property_info = zend_hash_find_ptr(&ce->properties_info, name);
+       if (property_info == NULL
+        || ((property_info->flags & ZEND_ACC_PRIVATE)
+         && property_info->ce != ce)) {
                /* Check for dynamic properties */
                if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
                        if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name)) {
@@ -5530,7 +5535,7 @@ ZEND_METHOD(reflection_property, getDeclaringClass)
 
        ce = tmp_ce = ref->ce;
        while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) {
-               if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
+               if (tmp_info->flags & ZEND_ACC_PRIVATE) {
                        /* it's a private property, so it can't be inherited */
                        break;
                }
index cd984dd9e7df061c87e293213522f7e387b0a6a0..fb26a70f861589c8743cc620c0afa8a3a76361b6 100644 (file)
@@ -11,7 +11,7 @@ abstract class BaseClass {
         private static $tidyconfig;
 
         public function __construct() {
-                $this->tidyconfig = array(
+                self::$tidyconfig = array(
                         'indent'                        => false,
                         'clean'                         => true,
                         'merge-divs'            => false,
@@ -29,7 +29,7 @@ abstract class BaseClass {
                 $data = "awerawer"; // in my code, $data is downloaded from a site
 
                 $tidy = new tidy;
-                $tidy->parseString($data, $this->tidyconfig, 'utf8');
+                $tidy->parseString($data, self::$tidyconfig, 'utf8');
                 $tidy->cleanRepair();
 
                 return $tidy;