]> 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:10 +0000 (16:48 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 13 Jun 2007 16:48:10 +0000 (16:48 +0000)
NEWS
Zend/tests/bug41633_3.phpt [new file with mode: 0755]
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index 917d5ec6ac1ec1af278b028841c592c1b1c1b23b..910ff2479658354676c6f34d08f1066aba186ba1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ PHP                                                                        NEWS
 - Fixed bug #41655 (open_basedir bypass via glob()). (Ilia)
 - Fixed bug #41640 (get_class_vars produces error on class constants).
   (Johannes)
+- Fixed bug #41633 (Crash instantiating classes with self-referencing
+  constants). (Dmitry)
 - Fixed bug #41630 (segfault when an invalid color index is present in
   the image data). (Reported by Elliot <wccoder@gmail dot com>) (Pierre)
 - Fixed bug #41608 (segfault on a weird code with objects and switch()). 
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 f3a123e390c557b9ff7379ee72444416d3a85583..b57834f39528e9c71bf1f7814911e4adf76b3afd 100644 (file)
@@ -448,6 +448,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;
@@ -455,13 +459,17 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
        zval const_value;
        char *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;