]> granicus.if.org Git - php/commitdiff
Moved IS_CONSTANT_VISITED_MARK, used for protection from recursive self-referencing...
authorDmitry Stogov <dmitry@zend.com>
Thu, 18 Jan 2018 08:36:04 +0000 (11:36 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 18 Jan 2018 08:36:04 +0000 (11:36 +0300)
Zend/zend_constants.c
Zend/zend_types.h

index 7e60f3d1fd3322275a97eb6f08934b019c20eba3..a2e25c89df6c54e6cca8c98f80334ca1389a2055 100644 (file)
 #include "zend_globals.h"
 #include "zend_API.h"
 
+/* Protection from recursive self-referencing class constants */
+#define IS_CONSTANT_VISITED_MARK    0x80
+
+#define IS_CONSTANT_VISITED(zv)     (Z_ACCESS_FLAGS_P(zv) & IS_CONSTANT_VISITED_MARK)
+#define MARK_CONSTANT_VISITED(zv)   Z_ACCESS_FLAGS_P(zv) |= IS_CONSTANT_VISITED_MARK
+#define RESET_CONSTANT_VISITED(zv)  Z_ACCESS_FLAGS_P(zv) &= ~IS_CONSTANT_VISITED_MARK
+
 void free_zend_constant(zval *zv)
 {
        zend_constant *c = Z_PTR_P(zv);
@@ -353,20 +360,22 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
                }
 
                if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
-                       if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
-                               if (IS_CONSTANT_VISITED(ret_constant)) {
-                                       zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
-                                       ret_constant = NULL;
-                                       goto failure;
-                               }
-                               MARK_CONSTANT_VISITED(ret_constant);
-                       }
-                       if (UNEXPECTED(zval_update_constant_ex(ret_constant, c->ce) != SUCCESS)) {
-                               RESET_CONSTANT_VISITED(ret_constant);
+                       int ret;
+
+                       if (IS_CONSTANT_VISITED(ret_constant)) {
+                               zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
                                ret_constant = NULL;
                                goto failure;
                        }
+
+                       MARK_CONSTANT_VISITED(ret_constant);
+                       ret = zval_update_constant_ex(ret_constant, c->ce);
                        RESET_CONSTANT_VISITED(ret_constant);
+
+                       if (UNEXPECTED(ret != SUCCESS)) {
+                               ret_constant = NULL;
+                               goto failure;
+                       }
                }
 failure:
                zend_string_release(class_name);
index e98e68b6cb58b237980587c0359af3b42c9418a4..94650c59e2221a29e22ed04c83260daced81bf85 100644 (file)
@@ -470,7 +470,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define GC_OBJECT                                      (IS_OBJECT         | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
 
 /* zval.u1.v.type_flags */
-#define IS_CONSTANT_VISITED_MARK    (1<<0)
 #define IS_TYPE_COPYABLE                       (1<<1)
 #define IS_TYPE_REFCOUNTED                     (1<<2) /* equal to ZEND_CALL_FREE_EXTRA_ARGS */
 
@@ -485,10 +484,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 
 #define IS_CONSTANT_AST_EX                     (IS_CONSTANT_AST   | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
 
-#define IS_CONSTANT_VISITED(p)         (Z_TYPE_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
-#define MARK_CONSTANT_VISITED(p)       Z_TYPE_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
-#define RESET_CONSTANT_VISITED(p)      Z_TYPE_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
-
 /* string flags (zval.value->gc.u.flags) */
 #define IS_STR_INTERNED                                GC_IMMUTABLE  /* interned string */
 #define IS_STR_PERSISTENT                      GC_PERSISTENT /* allocated using malloc */