]> granicus.if.org Git - php/commitdiff
Fix a bug in inheritence from classes defined in include files, that are
authorZeev Suraski <zeev@php.net>
Mon, 26 Jul 1999 21:18:35 +0000 (21:18 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 26 Jul 1999 21:18:35 +0000 (21:18 +0000)
inherited from require()'d files

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c

index 99411f8b109c9178c34fb47a434f2e9f119a547a..0ff6c70e2b72a544c5dfd681b062e97446f9ef7c 100644 (file)
@@ -874,7 +874,7 @@ static void function_add_ref(zend_function *function)
 }
 
 
-ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table)
+ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int allow_failure)
 {
        switch (opline->extended_value) {
                case ZEND_DECLARE_FUNCTION: {
@@ -883,7 +883,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
                                zend_hash_index_find(function_table, opline->op1.u.constant.value.lval, (void **) &function);
                                (*function->op_array.refcount)++;
                                if (zend_hash_add(function_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, function, sizeof(zend_function), NULL)==FAILURE) {
-                                       zend_error(E_COMPILE_ERROR, "Cannot redeclare %s()", opline->op2.u.constant.value.str.val);
+                                       if (!allow_failure) {
+                                               zend_error(E_COMPILE_ERROR, "Cannot redeclare %s()", opline->op2.u.constant.value.str.val);
+                                       }
+                                       return FAILURE;
+                               } else {
+                                       return SUCCESS;
                                }
                        }
                        break;
@@ -893,7 +898,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
                                zend_hash_index_find(class_table, opline->op1.u.constant.value.lval, (void **) &ce);
                                (*ce->refcount)++;
                                if (zend_hash_add(class_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, ce, sizeof(zend_class_entry), NULL)==FAILURE) {
-                                       zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
+                                       if (!allow_failure) {
+                                               zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
+                                       }
+                                       return FAILURE;
+                               } else {
+                                       return SUCCESS;
                                }
                        }
                        break;
@@ -916,7 +926,12 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
 
                                /* Obtain parent class */
                                if (zend_hash_find(class_table, parent_name, strlen(parent_name)+1, (void **) &parent_ce)==FAILURE) {
-                                       zend_error(E_COMPILE_ERROR, "Class %s:  Cannot inherit from undefined class %s", class_name, parent_name);
+                                       if (!allow_failure) {
+                                               zend_error(E_COMPILE_ERROR, "Class %s:  Cannot inherit from undefined class %s", class_name, parent_name);
+                                       }
+                                       (*ce->refcount)--;
+                                       *(class_name-1) = ':';
+                                       return FAILURE;
                                }
 
                                /* Perform inheritence */
@@ -925,8 +940,15 @@ ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_tab
 
                                /* Register the derived class */
                                if (zend_hash_add(class_table, class_name, strlen(class_name)+1, ce, sizeof(zend_class_entry), NULL)==FAILURE) {
-                                       zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
+                                       if (allow_failure) {
+                                               zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
+                                       }
+                                       (*ce->refcount)--;
+                                       zend_hash_destroy(&ce->function_table);
+                                       zend_hash_destroy(&ce->default_properties);
+                                       return FAILURE;
                                }
+                               return SUCCESS;
                        }
                        break;
        }
@@ -937,7 +959,9 @@ void do_early_binding(CLS_D)
 {
        zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
 
-       do_bind_function_or_class(opline, CG(function_table), CG(class_table));
+       if (do_bind_function_or_class(opline, CG(function_table), CG(class_table), 1)==FAILURE) {
+               return;
+       }
        switch (opline->extended_value) {
                case ZEND_DECLARE_FUNCTION:
                        zend_hash_index_del(CG(function_table), opline->op1.u.constant.value.lval);
index b71c9ad018b43bb8a26a368b3ccbfebd281fbfd7..903aeb452785e1d6138eccb4d2c54a4d7ba4e09a 100644 (file)
@@ -265,7 +265,7 @@ void do_begin_dynamic_function_call(znode *function_name CLS_DC);
 void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
 void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC);
 void do_return(znode *expr CLS_DC);
-ZEND_API void do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table);
+ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int allow_failure);
 void do_early_binding(CLS_D);
 
 void do_pass_param(znode *param, int op, int offset CLS_DC);
index 9da48357e4a335dc75da4e2923a108eebff8d158..a6663fee592eea4158399debc94c3d1751618680 100644 (file)
@@ -2026,7 +2026,7 @@ send_by_ref:
                                }
                                break;
                        case ZEND_DECLARE_FUNCTION_OR_CLASS:
-                               do_bind_function_or_class(opline, EG(function_table), EG(class_table));
+                               do_bind_function_or_class(opline, EG(function_table), EG(class_table), 0);
                                break;
                        case ZEND_EXT_NOP:
                        case ZEND_NOP: