]> granicus.if.org Git - php/commitdiff
Fixed bug #41633 (Crash instantiating classes with self-referencing constants)
authorDmitry Stogov <dmitry@php.net>
Wed, 13 Jun 2007 16:48:29 +0000 (16:48 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 13 Jun 2007 16:48:29 +0000 (16:48 +0000)
Zend/tests/bug41633_3.phpt [new file with mode: 0755]
Zend/zend_execute_API.c

diff --git a/Zend/tests/bug41633_3.phpt b/Zend/tests/bug41633_3.phpt
new file mode 100755 (executable)
index 0000000..7b9452d
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+Bug #41633.3 (Crash instantiating classes with self-referencing constants)
+--FILE--
+<?php
+class Foo {
+       const A = Foo::B;
+       const B = Foo::A;
+}
+echo Foo::A;
+?>
+--EXPECTF--
+Fatal error: Cannot declare self-referencing constant 'Foo::B' in %sbug41633_3.php on line %d
index 2041a3d42fc188f567b0bb7eeed98351f7ff7e2b..5e53e39d628008360c8f68ee60779dd7783f9573 100644 (file)
@@ -469,6 +469,10 @@ ZEND_API int zend_is_true(zval *op)
 
 #include "../TSRM/tsrm_strtok_r.h"
 
+#define IS_VISITED_CONSTANT       IS_CONSTANT_INDEX
+#define IS_CONSTANT_VISITED(p)    (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
+#define MARK_CONSTANT_VISITED(p)  Z_TYPE_P(p) |= IS_VISITED_CONSTANT
+
 ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC)
 {
        zval *p = *pp;
@@ -476,13 +480,17 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
        zval const_value;
        zstr colon;
 
-       if (Z_TYPE_P(p) == IS_CONSTANT) {
+       if (IS_CONSTANT_VISITED(p)) {
+               zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
+       } else if (Z_TYPE_P(p) == IS_CONSTANT) {
                int refcount;
                zend_uchar is_ref;
 
                SEPARATE_ZVAL_IF_NOT_REF(pp);
                p = *pp;
 
+               MARK_CONSTANT_VISITED(p);
+
                refcount = p->refcount;
                is_ref = p->is_ref;