]> granicus.if.org Git - php/commitdiff
- Enforce protocol on magic methods/functions
authorMarcus Boerger <helly@php.net>
Sun, 1 Aug 2004 21:55:39 +0000 (21:55 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 1 Aug 2004 21:55:39 +0000 (21:55 +0000)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c

index 91310655d385041d591f3431c35b37b74a293c63..0bbf464cf7f2d0686d0cfda16e761736a243b129 100644 (file)
@@ -1087,16 +1087,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);
@@ -1114,10 +1135,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;
index 69fc099b708ec78e3d95dc575e67933e417557f7..937b17043fb95c2a4d5d77cdbdf85f445a32ba03 100644 (file)
@@ -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 */
 
index 0cee71deb1d9da7d43c9efa4202258e1aa67685f..d0670314cc5093e149dc3dd129a99758a659e65f 100644 (file)
@@ -911,7 +911,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);
@@ -932,7 +932,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;