From: Andi Gutmans Date: Thu, 13 Dec 2001 16:55:04 +0000 (+0000) Subject: - Fix crash bug in startup code. X-Git-Tag: PRE_FUNC_RETURNS_OBJECT_PATCH~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4b832d277390f1e20e38ed275f26867c7c6537c;p=php - Fix crash bug in startup code. - Start work on being able to reference global and local scope --- diff --git a/Zend/zend.c b/Zend/zend.c index a6314dfd1b..be547ec907 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -246,7 +246,8 @@ static void register_standard_class(void) zend_standard_class_def.name = zend_strndup("stdClass", zend_standard_class_def.name_length); zend_standard_class_def.parent = NULL; zend_hash_init_ex(&zend_standard_class_def.default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); - zend_hash_init_ex(&zend_standard_class_def.static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_standard_class_def.static_members = (HashTable *) malloc(sizeof(HashTable)); + zend_hash_init_ex(zend_standard_class_def.static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0); zend_hash_init_ex(&zend_standard_class_def.constants_table, 0, NULL, ZVAL_PTR_DTOR, 1, 0); zend_hash_init_ex(&zend_standard_class_def.class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0); zend_hash_init_ex(&zend_standard_class_def.function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0); @@ -447,8 +448,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i executor_globals = ts_resource(executor_globals_id); tsrm_ls = ts_resource_ex(0, NULL); compiler_globals_dtor(compiler_globals, tsrm_ls); - compiler_globals->function_table = GLOBAL_FUNCTION_TABLE; - compiler_globals->class_table = GLOBAL_CLASS_TABLE; + *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE; + *compiler_globals->class_table = *GLOBAL_CLASS_TABLE; compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE; zend_startup_constants(tsrm_ls); #else @@ -489,8 +490,10 @@ void zend_shutdown(TSRMLS_D) #endif zend_destroy_rsrc_list_dtors(); zend_hash_destroy(&module_registry); +#ifndef ZTS zend_hash_destroy(GLOBAL_FUNCTION_TABLE); zend_hash_destroy(GLOBAL_CLASS_TABLE); +#endif zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE); free(GLOBAL_AUTO_GLOBALS_TABLE); zend_shutdown_extensions(TSRMLS_C); diff --git a/Zend/zend.h b/Zend/zend.h index c869f7fecf..69d33f3291 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -286,7 +286,7 @@ struct _zend_class_entry { HashTable function_table; HashTable default_properties; HashTable class_table; - HashTable static_members; + HashTable *static_members; HashTable constants_table; zend_function_entry *builtin_functions; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b61e797e01..966f8c1fa8 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -572,7 +572,7 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type if (!class_type->constants_updated) { zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); - zend_hash_apply_with_argument(&class_type->static_members, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); + zend_hash_apply_with_argument(class_type->static_members, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); class_type->constants_updated = 1; } @@ -1216,7 +1216,8 @@ ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_ *class_entry->refcount = 1; class_entry->constants_updated = 0; zend_hash_init(&class_entry->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1); - zend_hash_init(&class_entry->static_members, 0, NULL, ZVAL_PTR_DTOR, 1); + class_entry->static_members = (HashTable *) malloc(sizeof(HashTable)); + zend_hash_init(class_entry->static_members, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&class_entry->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&class_entry->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1); zend_hash_init(&class_entry->class_table, 10, NULL, ZEND_CLASS_DTOR, 1); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 587b4903ff..0b753f23d6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -927,6 +927,11 @@ void do_fetch_class(znode *result, znode *class_entry, znode *class_name TSRMLS_ SET_UNUSED(opline->op2); opline->extended_value = ZEND_FETCH_CLASS_SELF; zval_dtor(&class_name->u.constant); + } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) && + !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) { + SET_UNUSED(opline->op2); + opline->extended_value = ZEND_FETCH_CLASS_MAIN; + zval_dtor(&class_name->u.constant); } else { opline->op2 = *class_name; } @@ -1281,7 +1286,7 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce) /* Perform inheritance */ zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); /* STATIC_MEMBERS_FIXME */ - zend_hash_merge(&ce->static_members, &parent_ce->static_members, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); + zend_hash_merge(ce->static_members, parent_ce->static_members, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); zend_hash_merge(&ce->function_table, &parent_ce->function_table, (void (*)(void *)) function_add_ref, &tmp_zend_function, sizeof(zend_function), 0); ce->parent = parent_ce; @@ -1389,7 +1394,7 @@ ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_tabl (*ce->refcount)--; zend_hash_destroy(&ce->function_table); zend_hash_destroy(&ce->default_properties); - zend_hash_destroy(&ce->static_members); + zend_hash_destroy(ce->static_members); zend_hash_destroy(&ce->constants_table); return FAILURE; } @@ -1722,7 +1727,8 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod zend_hash_init(&new_class_entry.function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0); zend_hash_init(&new_class_entry.class_table, 10, NULL, ZEND_CLASS_DTOR, 0); zend_hash_init(&new_class_entry.default_properties, 10, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_init(&new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0); + new_class_entry.static_members = (HashTable *) emalloc(sizeof(HashTable)); + zend_hash_init(new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&new_class_entry.constants_table, 10, NULL, ZVAL_PTR_DTOR, 0); new_class_entry.constructor = NULL; @@ -1749,7 +1755,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod zend_hash_copy(&new_class_entry.default_properties, &parent_class->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); /* copy static members */ - zend_hash_copy(&new_class_entry.static_members, &parent_class->static_members, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(new_class_entry.static_members, parent_class->static_members, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); /* copy constants */ zend_hash_copy(&new_class_entry.constants_table, &parent_class->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); @@ -1836,7 +1842,7 @@ void zend_do_declare_property(znode *var_name, znode *value, int declaration_typ zend_hash_update(&CG(active_class_entry)->default_properties, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); break; case T_STATIC: - zend_hash_update(&CG(active_class_entry)->static_members, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + zend_hash_update(CG(active_class_entry)->static_members, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); break; case T_CONST: zend_hash_update(&CG(active_class_entry)->constants_table, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index a8dba653c5..cba5488a08 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -554,6 +554,7 @@ int zendlex(znode *zendlval TSRMLS_DC); /* class fetches */ #define ZEND_FETCH_CLASS_DEFAULT 0 #define ZEND_FETCH_CLASS_SELF 1 +#define ZEND_FETCH_CLASS_MAIN 2 /* unset types */ #define ZEND_UNSET_REG 0 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 1f029428c0..e9bc897b88 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -548,7 +548,7 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type target_symbol_table = EG(active_op_array)->static_variables; break; case ZEND_FETCH_STATIC_MEMBER: - target_symbol_table = &Ts[opline->op2.u.var].EA.class_entry->static_members; + target_symbol_table = Ts[opline->op2.u.var].EA.class_entry->static_members; break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -1500,6 +1500,9 @@ binary_assign_op_addr: { } EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(namespace); NEXT_OPCODE(); + } else if (EX(opline)->extended_value == ZEND_FETCH_CLASS_MAIN) { + EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(main_class_ptr); + NEXT_OPCODE(); } class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R); @@ -1621,7 +1624,7 @@ binary_assign_op_addr: { zval_copy_ctor(this_ptr); EX(object).ptr = this_ptr; } - active_function_table = &Z_OBJCE_P(EX(object).ptr)->function_table; + //active_function_table = &Z_OBJCE_P(EX(object).ptr)->function_table; EX(calling_namespace) = Z_OBJCE_P(EX(object).ptr); } if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) { @@ -1657,6 +1660,7 @@ overloaded_function_call_cont: if (zend_hash_find(EG(namespace)?&EG(namespace)->function_table:EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val); } + EX(calling_namespace) = EG(namespace); FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); zend_ptr_stack_push(&EG(arg_types_stack), EX(object).ptr); EX(object).ptr = NULL; @@ -2101,6 +2105,16 @@ send_by_ref: ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry; + if (&ce->constants_table == &EG(main_class_ptr)->constants_table) { + if (!zend_get_constant(EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len, &EX(Ts)[EX(opline)->result.u.var].tmp_var TSRMLS_CC)) { + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + EX(opline)->op2.u.constant.value.str.val, + EX(opline)->op2.u.constant.value.str.val); + EX(Ts)[EX(opline)->result.u.var].tmp_var = EX(opline)->op2.u.constant; + zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var); + } + NEXT_OPCODE(); + } if (zend_hash_find(&ce->constants_table, EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) { zval_update_constant(value, (void *) 1 TSRMLS_CC); EX(Ts)[EX(opline)->result.u.var].tmp_var = **value; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a9ea4469a7..7141391975 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -136,7 +136,7 @@ void init_executor(TSRMLS_D) zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table); - + zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); EG(opline_ptr) = NULL; EG(garbage_ptr) = 0; @@ -160,6 +160,10 @@ void init_executor(TSRMLS_D) EG(exception) = NULL; EG(namespace) = NULL; + + EG(main_class_ptr) = &CG(main_class); + CG(main_class).static_members = &EG(symbol_table); + } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index d6001aac43..38a1a69cbc 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -157,6 +157,7 @@ struct _zend_executor_globals { HashTable *zend_constants; /* constants table */ zend_class_entry *namespace; + zend_class_entry *main_class_ptr; long precision; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index edefcafa02..9bc95b6398 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -117,7 +117,8 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce) efree(ce->refcount); zend_hash_destroy(&ce->function_table); zend_hash_destroy(&ce->default_properties); - zend_hash_destroy(&ce->static_members); + zend_hash_destroy(ce->static_members); + efree(ce->static_members); zend_hash_destroy(&ce->constants_table); zend_hash_destroy(&ce->class_table); break; @@ -126,7 +127,8 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce) free(ce->refcount); zend_hash_destroy(&ce->function_table); zend_hash_destroy(&ce->default_properties); - zend_hash_destroy(&ce->static_members); + zend_hash_destroy(ce->static_members); + free(ce->static_members); zend_hash_destroy(&ce->constants_table); zend_hash_destroy(&ce->class_table); break;