Skip to content

Commit

Permalink
MFB: Enforce protocol on magic methods/functions
Browse files Browse the repository at this point in the history
  • Loading branch information
helly25 committed Aug 2, 2004
1 parent 5890197 commit 5f0433d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 17 deletions.
33 changes: 25 additions & 8 deletions Zend/zend_compile.c
Expand Up @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_compile.h
Expand Up @@ -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 */

Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_execute_API.c
Expand Up @@ -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);
Expand All @@ -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;
Expand Down
15 changes: 9 additions & 6 deletions ext/mbstring/tests/htmlent.phpt
Expand Up @@ -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--
<?php
// enable output encoding through output handler
ob_start("mb_output_handler");
//ob_start("mb_output_handler");
// &#64... are must be decoded on input these are not reencoded on output.
// If you see &#64;&#65;&#66; on output this means input encoding fails.
// If you do not see &auml;... on output this means output encoding fails.
Expand All @@ -27,9 +28,11 @@ ob_start("mb_output_handler");
?>
<?php echo mb_http_input('l').'>'.mb_internal_encoding().'>'.mb_http_output();?>

<?php mb_parse_str("test=&&;&&#64;&#65;&#66;&#128;&#129;&#130;&auml;&ouml;&uuml;&euro;&lang;&rang;");
echo "test='$test'";
<?php mb_parse_str("test=&#64;&#65;&#66;&#128;&#129;&#130;&auml;&ouml;&uuml;&euro;&lang;&rang;", $test);
print_r($test['test']);
?>
===DONE===
--EXPECT--
HTML-ENTITIES>UTF-8>HTML-ENTITIES
test='&&;&@AB&#128;&#129;&#130;&auml;&ouml;&uuml;&euro;&lang;&rang;'
test='&&;&@AB&#128;&#129;&#130;&auml;&ouml;&uuml;&euro;&lang;&rang;'
===DONE===
2 changes: 1 addition & 1 deletion 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--
<?php

Expand Down

0 comments on commit 5f0433d

Please sign in to comment.