]> granicus.if.org Git - php/commitdiff
- Fixed bug #49472 (Constants defined in Interfaces can be overridden)
authorFelipe Pena <felipe@php.net>
Thu, 3 Dec 2009 12:34:50 +0000 (12:34 +0000)
committerFelipe Pena <felipe@php.net>
Thu, 3 Dec 2009 12:34:50 +0000 (12:34 +0000)
NEWS
Zend/tests/bug49472.phpt [new file with mode: 0644]
Zend/tests/errmsg_025.phpt
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 536a38855eb70a25936d5a0a28177e0a48e3ee21..0c5153ce291dfaa4b0dbf4ca1e2d983f77aa4e88 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,8 @@ PHP                                                                        NEWS
 - Fixed bug #50168 (FastCGI fails with wrong error on HEAD request to
   non-existent file). (Dmitry)
 - Fixed bug #49660 (libxml 2.7.3+ limits text nodes to 10MB). (Felipe)
+- Fixed bug #49472 (Constants defined in Interfaces can be overridden).
+  (Felipe)
 
 
 27 Nov 2009, PHP 5.2.12RC3
diff --git a/Zend/tests/bug49472.phpt b/Zend/tests/bug49472.phpt
new file mode 100644 (file)
index 0000000..1803d18
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #49472 (Constants defined in Interfaces can be overridden)
+--FILE--
+<?php
+
+interface ia {
+    const c = 'Sea';
+    const y = 2;
+}
+
+class Foo implements ia {
+}
+
+class FooBar extends Foo implements ia {
+       const x = 1;
+       const c = 'Ocean';
+       
+       public function show() {
+               return ia::c;
+       }
+}
+
+new FooBar;
+
+?>
+--EXPECTF--
+Fatal error: Cannot inherit previously-inherited or override constant c from interface ia in %s on line %d
index d853f734285f6b4da37a49372cde25720b1be8eb..014b409479552dda1a4d229d7a2a08c8cfaeacde 100644 (file)
@@ -16,5 +16,5 @@ class test implements test1, test2 {
 
 echo "Done\n";
 ?>
---EXPECTF--    
-Fatal error: Cannot inherit previously-inherited constant FOO from interface test2 in %s on line %d
+--EXPECTF--
+Fatal error: Cannot inherit previously-inherited or override constant FOO from interface test2 in %s on line %d
index 3c34743619fa2a21568566d85cd1ab5028310c93..439b849e72cd5d44e58413365cd946c2e80d18b8 100644 (file)
@@ -2333,20 +2333,28 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
        }
 }
 
-
 static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zval **parent_constant, zend_hash_key *hash_key, zend_class_entry *iface)
 {
        zval **old_constant;
 
        if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) {
-         if (*old_constant != *parent_constant) {
-                       zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited constant %s from interface %s", hash_key->arKey, iface->name);
+               if (*old_constant != *parent_constant) {
+                       zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name);
                }
                return 0;
        }
        return 1;
 }
 
+static int do_interface_constant_check(zval **val, int num_args, va_list args, zend_hash_key *key) /* {{{ */
+{
+       zend_class_entry **iface = va_arg(args, zend_class_entry**);
+
+       do_inherit_constant_check(&(*iface)->constants_table, val, key, *iface);
+
+       return ZEND_HASH_APPLY_KEEP;
+}
+/* }}} */
 
 ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC)
 {
@@ -2366,7 +2374,10 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
                        }
                }
        }
-       if (!ignore) {
+       if (ignore) {
+               /* Check for attempt to redeclare interface constants */
+               zend_hash_apply_with_arguments(&ce->constants_table, (apply_func_args_t) do_interface_constant_check, 1, &iface);
+       } else {
                if (ce->num_interfaces >= current_iface_num) {
                        if (ce->type == ZEND_INTERNAL_CLASS) {
                                ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));