From: Zeev Suraski Date: Mon, 26 Jul 1999 21:18:35 +0000 (+0000) Subject: Fix a bug in inheritence from classes defined in include files, that are X-Git-Tag: php-4.0b2~111 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41308d4b437387c3ca981703eb4dee07697be10c;p=php Fix a bug in inheritence from classes defined in include files, that are inherited from require()'d files --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 99411f8b10..0ff6c70e2b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b71c9ad018..903aeb4527 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9da48357e4..a6663fee59 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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: