From 5f0433db83663968d20c8ab02b875aad309c544d Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Mon, 2 Aug 2004 08:27:57 +0000 Subject: [PATCH] MFB: Enforce protocol on magic methods/functions --- Zend/zend_compile.c | 33 +++++++++++++++++++++++++-------- Zend/zend_compile.h | 1 + Zend/zend_execute_API.c | 4 ++-- ext/mbstring/tests/htmlent.phpt | 15 +++++++++------ tests/classes/ctor_failure.phpt | 2 +- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 809c2b4765..b05c88c72f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1089,16 +1089,37 @@ void zend_do_handle_exception(TSRMLS_D) void zend_do_end_function_declaration(znode *function_token TSRMLS_DC) { + char lcname[16]; + int name_len; + zend_do_extended_info(TSRMLS_C); zend_do_return(NULL, 0 TSRMLS_CC); zend_do_handle_exception(TSRMLS_C); pass_two(CG(active_op_array) TSRMLS_CC); - if (CG(active_class_entry) - && !strcmp(CG(active_op_array)->function_name, ZEND_CLONE_FUNC_NAME) - && CG(active_op_array)->num_args != 0) { - zend_error(E_COMPILE_ERROR, "The clone method cannot accept any arguments"); + /* we don't care if the function name is longer, in fact lowercasing only + * the beginning of the name speeds up th echeck process */ + name_len = strlen(CG(active_op_array)->function_name); + zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1)); + lcname[sizeof(lcname)-1] = '\0'; // zend_str_tolower_copy won't necessarily set the zero byte + + if (CG(active_class_entry)) { + if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME) && CG(active_op_array)->num_args != 0) { + zend_error(E_COMPILE_ERROR, "Destuctor %s::%s() cannot take arguments", CG(active_class_entry)->name, ZEND_DESTRUCTOR_FUNC_NAME); + } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_CLONE_FUNC_NAME) && CG(active_op_array)->num_args != 0) { + zend_error(E_COMPILE_ERROR, "Method %s::%s() cannot accept any arguments", CG(active_class_entry)->name, ZEND_CLONE_FUNC_NAME); + } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_GET_FUNC_NAME) && CG(active_op_array)->num_args != 1) { + zend_error(E_COMPILE_ERROR, "Method %s::%s() must take exactly 1 argument", CG(active_class_entry)->name, ZEND_GET_FUNC_NAME); + } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_SET_FUNC_NAME) && CG(active_op_array)->num_args != 2) { + zend_error(E_COMPILE_ERROR, "Method %s::%s() must take exactly 2 arguments", CG(active_class_entry)->name, ZEND_SET_FUNC_NAME); + } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_CALL_FUNC_NAME) && CG(active_op_array)->num_args != 2) { + zend_error(E_COMPILE_ERROR, "Method %s::%s() must take exactly 2 arguments", CG(active_class_entry)->name, ZEND_CALL_FUNC_NAME); + } + } else { + if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !strcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME) && CG(active_op_array)->num_args != 1) { + zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); + } } CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C); @@ -1116,10 +1137,6 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zend_arg_info *cur_arg_info; - if (CG(active_class_entry) && CG(active_class_entry)->destructor == (zend_function *) CG(active_op_array)) - { - zend_error(E_COMPILE_ERROR, "Destuctor %s::%s() cannot take arguments", CG(active_class_entry)->name, CG(active_op_array)->function_name); - } CG(active_op_array)->num_args++; opline->opcode = op; opline->result = *var; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 69fc099b70..937b17043f 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -840,6 +840,7 @@ END_EXTERN_C() #define ZEND_GET_FUNC_NAME "__get" #define ZEND_SET_FUNC_NAME "__set" #define ZEND_CALL_FUNC_NAME "__call" +#define ZEND_AUTOLOAD_FUNC_NAME "__autoload" #endif /* ZEND_COMPILE_H */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index ff540a0965..47c5365e90 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -923,7 +923,7 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry *** return FAILURE; } - ZVAL_STRINGL(&autoload_function, "__autoload", sizeof("__autoload")-1, 0); + ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1, 0); INIT_PZVAL(class_name_ptr); ZVAL_STRINGL(class_name_ptr, name, name_length, 0); @@ -944,7 +944,7 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry *** if (EG(exception)) { free_alloca(lc_name); - zend_error(E_ERROR, "__autoload(%s) threw an exception of type '%s'", name, Z_OBJCE_P(EG(exception))->name); + zend_error(E_ERROR, "Function %s(%s) threw an exception of type '%s'", ZEND_AUTOLOAD_FUNC_NAME, name, Z_OBJCE_P(EG(exception))->name); return FAILURE; } EG(exception) = exception; diff --git a/ext/mbstring/tests/htmlent.phpt b/ext/mbstring/tests/htmlent.phpt index ca7d64ba41..e625578e04 100644 --- a/ext/mbstring/tests/htmlent.phpt +++ b/ext/mbstring/tests/htmlent.phpt @@ -6,18 +6,19 @@ HTML input/output extension_loaded('mbstring') or die('skip mbstring not available'); ?> --INI-- +output_buffering=4096 output_handler=mb_output_handler zlib.output_compression= -arg_separator.input="x" +arg_separator.input=x error_reporting=0 mbstring.http_input=HTML-ENTITIES -mbstring.internal_encoding=UTF8 +mbstring.internal_encoding=UTF-8 mbstring.http_output=HTML-ENTITIES mbstring.encoding_translation=1 --FILE-- '.mb_internal_encoding().'>'.mb_http_output();?> - +===DONE=== --EXPECT-- HTML-ENTITIES>UTF-8>HTML-ENTITIES -test='&&;&@AB€‚äöü€⟨⟩' \ No newline at end of file +test='&&;&@AB€‚äöü€⟨⟩' +===DONE=== diff --git a/tests/classes/ctor_failure.phpt b/tests/classes/ctor_failure.phpt index bbebca2af8..b7d3b64dda 100755 --- a/tests/classes/ctor_failure.phpt +++ b/tests/classes/ctor_failure.phpt @@ -1,5 +1,5 @@ --TEST-- -Do not call destructors if constructor fails +ZE2 Do not call destructors if constructor fails --FILE--