cvs: ZendEngine2 / zend_API.c zend_API.h zend_execute_API.c zend_vm_def.h

[email protected] ("Marcus Boerger")
Newsgroups php.zend-engine.cvs
Message-ID <cvshelly1201965802@cvsserver>
helly		Sat Feb  2 15:23:22 2008 UTC

  Modified files:              
    /ZendEngine2	zend_API.c zend_API.h zend_execute_API.c zend_vm_def.h 
  Log:
  - MFB static callable message mess
helly-20080202152322.txt (text/plain, 17.8 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.c?r1=1.453&r2=1.454&diff_format=u
Index: ZendEngine2/zend_API.c
diff -u ZendEngine2/zend_API.c:1.453 ZendEngine2/zend_API.c:1.454
--- ZendEngine2/zend_API.c:1.453	Thu Jan 24 10:49:44 2008
+++ ZendEngine2/zend_API.c	Sat Feb  2 15:23:22 2008
@@ -18,13 +18,14 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.c,v 1.453 2008/01/24 10:49:44 dmitry Exp $ */
+/* $Id: zend_API.c,v 1.454 2008/02/02 15:23:22 helly Exp $ */
 
 #include "zend.h"
 #include "zend_execute.h"
 #include "zend_API.h"
 #include "zend_modules.h"
 #include "zend_constants.h"
+#include "zend_exceptions.h"
 
 #ifdef HAVE_STDARG_H
 #include <stdarg.h>
@@ -313,7 +314,7 @@
 }
 /* }}} */
 
-static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec, char T_arg_type, int* ret_type TSRMLS_DC) /* {{{ */
+static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec, char T_arg_type, int* ret_type, char **error, int *severity TSRMLS_DC) /* {{{ */
 {
 	char *spec_walk = *spec;
 	char c = *spec_walk++;
@@ -770,21 +771,15 @@
 				}
 				if (ce_base) {
 					if ((!*pce || !instanceof_function(*pce, ce_base TSRMLS_CC))) {
-						char *space;
-						zstr class_name = get_active_class_name(&space TSRMLS_CC);
-						zend_error(E_WARNING, "%v%s%v() expects parameter %d to be a class name derived from %v, '%v' given",
-							class_name, space, get_active_function_name(TSRMLS_C),
-							arg_num, ce_base->name, Z_STRVAL_PP(arg));
+						zend_spprintf(error, 0, "to be a class name derived from %s, '%s' given",
+							ce_base->name, Z_STRVAL_PP(arg));
 						*pce = NULL;
 						return "";
 					}
 				}
 				if (!*pce) {
-					char *space;
-					zstr class_name = get_active_class_name(&space TSRMLS_CC);
-					zend_error(E_WARNING, "%v%s%v() expects parameter %d to be a valid class name, '%v' given",
-						class_name, space, get_active_function_name(TSRMLS_C),
-						arg_num, Z_STRVAL_PP(arg));
+					zend_spprintf(error, 0, "to be a valid class name, '%s' given",
+						Z_STRVAL_PP(arg));
 					return "";
 				}
 				break;
@@ -796,6 +791,7 @@
 			{
 				zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
 				zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
+				char *is_callable_error = NULL;
 
 				if (return_null) {
 					fci->size = 0;
@@ -803,10 +799,24 @@
 					break;
 				}
 
-				if (zend_fcall_info_init(*arg, fci, fcc, NULL TSRMLS_CC) == SUCCESS) {
+				if (zend_fcall_info_init(*arg, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == SUCCESS) {
+					if (is_callable_error) {
+						*severity = E_STRICT;
+						zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
+						efree(is_callable_error);
+						*spec = spec_walk;
+						return "";
+					}
 					break;
 				} else {
-					return "valid callback";
+					if (is_callable_error) {
+						*severity = E_WARNING;
+						zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error);
+						efree(is_callable_error);
+						return "";
+					} else {
+						return "valid callback";
+					}
 				}
 			}
 
@@ -844,20 +854,29 @@
 
 static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int quiet, char T_arg_type TSRMLS_DC) /* {{{ */
 {
-	char *expected_type = NULL;
+	char *expected_type = NULL, *error = NULL;
 	int ret_type = IS_STRING;
+	int severity = E_WARNING;
 
-	expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, T_arg_type, &ret_type TSRMLS_CC);
+	expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, T_arg_type, &ret_type, &error, &severity TSRMLS_CC);
 	if (expected_type) {
-		if (!quiet && *expected_type) {
+		if (!quiet && (*expected_type || error)) {
 			char *space;
 			zstr class_name = get_active_class_name(&space TSRMLS_CC);
 
-			zend_error(E_WARNING, "%v%s%v() expects parameter %d to be %R, %s given",
-					class_name, space, get_active_function_name(TSRMLS_C), arg_num, ret_type, expected_type,
-					zend_zval_type_name(*arg));
+			if (error) {
+				zend_error(severity, "%v%s%v() expects parameter %d %s",
+						class_name, space, get_active_function_name(TSRMLS_C), arg_num, error);
+				efree(error);
+			} else {
+				zend_error(severity, "%v%s%v() expects parameter %d to be %R, %s given",
+						class_name, space, get_active_function_name(TSRMLS_C), arg_num, ret_type, expected_type,
+						zend_zval_type_name(*arg));
+			}
+		}
+		if (severity != E_STRICT) {
+			return FAILURE;
 		}
-		return FAILURE;
 	}
 
 	return SUCCESS;
@@ -2625,7 +2644,7 @@
 }
 /* }}} */
 
-static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, zend_class_entry *ce_org, zval *callable, zend_class_entry **ce_ptr, zend_function **fptr_ptr TSRMLS_DC) /* {{{ */
+static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, zend_class_entry *ce_org, zval *callable, zend_class_entry **ce_ptr, zend_function **fptr_ptr, char **error TSRMLS_DC) /* {{{ */
 {
 	int retval;
 	zstr lmname, mname, colon = NULL_ZSTR;
@@ -2686,6 +2705,7 @@
 			colon.s--;
 			clen = colon.s - Z_STRVAL_P(callable);
 			if (clen == 0) {
+				if (error) zend_spprintf(error, 0, "invalid function name");
 				return 0;
 			}
 			mlen = Z_STRLEN_P(callable) - clen - 2;
@@ -2699,10 +2719,14 @@
 		 * Try to fetch class and then find static method. */
 		*ce_ptr = zend_u_fetch_class(Z_TYPE_P(callable), Z_UNIVAL_P(callable), clen, ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
 		if (!*ce_ptr) {
+			char *cname = estrndup(Z_STRVAL_P(callable), clen);
+			if (error) zend_spprintf(error, 0, "class '%s' not found", cname);
+			efree(cname);
 			return 0;
 		}
 		ftable = &(*ce_ptr)->function_table;
 		if (ce_org && !instanceof_function(ce_org, *ce_ptr TSRMLS_CC)) {
+			if (error) zend_spprintf(error, 0, "class '%s' is not a subclass of '%s'", ce_org->name, (*ce_ptr)->name);
 			return 0;
 		}
 		lmname = zend_u_str_case_fold(Z_TYPE_P(callable), mname, mlen, 1, &mlen);
@@ -2713,6 +2737,7 @@
 		*ce_ptr = ce_org;
 	} else {
 		/* We already checked for plain function before. */
+		if (error) zend_spprintf(error, 0, "function '%s' not found or invalid function name", Z_STRVAL_P(callable));
 		return 0;
 	}
 
@@ -2725,24 +2750,53 @@
 		} else if (!*zobj_ptr_ptr && *ce_ptr && (*ce_ptr)->__callstatic) {
 			retval = 1;
 			*fptr_ptr = (*ce_ptr)->__callstatic;
+		} else {
+			if (*ce_ptr) {
+				if (error) zend_spprintf(error, 0, "class '%s' does not have a method '%s'", (*ce_ptr)->name, lmname);
+			} else {
+				if (error) zend_spprintf(error, 0, "function '%s' does not exist", lmname);
+			}
 		}
 	} else {
 		*fptr_ptr = fptr;
 		if (*ce_ptr) {
 			if (!*zobj_ptr_ptr && !(fptr->common.fn_flags & ZEND_ACC_STATIC)) {
+				int severity;
+				char *verb;
+				if (fptr->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+					severity = E_STRICT;
+					verb = "should not";
+				} else {
+					severity = E_ERROR;
+					verb = "cannot";
+				}
 				if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
 					retval = 0;
+				}
+				if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), *ce_ptr TSRMLS_CC)) {
+					*zobj_ptr_ptr = &EG(This);
+					if (error) {
+						zend_spprintf(error, 0, "non-static method %s::%s() %s be called statically, assuming $this from compatible context %s", (*ce_ptr)->name, fptr->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
+					} else if (retval) {
+						zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from compatible context %s", (*ce_ptr)->name, fptr->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
+					}
 				} else {
-					zend_error(E_STRICT, "Non-static method %v::%v() cannot be called statically", (*ce_ptr)->name, fptr->common.function_name);
+					if (error) {
+						zend_spprintf(error, 0, "non-static method %s::%s() %s be called statically", (*ce_ptr)->name, fptr->common.function_name, verb);
+					} else if (retval) {
+						zend_error(severity, "Non-static method %s::%s() %s be called statically", (*ce_ptr)->name, fptr->common.function_name, verb);
+					}
 				}
 			}
 			if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
 				if (fptr->op_array.fn_flags & ZEND_ACC_PRIVATE) {
 					if (!zend_check_private(fptr, *zobj_ptr_ptr ? Z_OBJCE_PP(*zobj_ptr_ptr) : EG(scope), lmname, mlen TSRMLS_CC)) {
+						if (error) zend_spprintf(error, 0, "cannot access private method %s::%s()", (*ce_ptr)->name, fptr->common.function_name);
 						retval = 0;
 					}
 				} else if ((fptr->common.fn_flags & ZEND_ACC_PROTECTED)) {
 					if (!zend_check_protected(fptr->common.scope, EG(scope))) {
+						if (error) zend_spprintf(error, 0, "cannot access protected method %s::%s()", (*ce_ptr)->name, fptr->common.function_name);
 						retval = 0;
 					}
 				}
@@ -2754,7 +2808,7 @@
 }
 /* }}} */
 
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr TSRMLS_DC) /* {{{ */
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr, char **error TSRMLS_DC) /* {{{ */
 {
 	zstr lcname;
 	unsigned int lcname_len;
@@ -2774,6 +2828,9 @@
 	if (zobj_ptr_ptr == NULL) {
 		zobj_ptr_ptr = &zobj_ptr_local;
 	}
+	if (error) {
+		*error = NULL;
+	}
 	*ce_ptr = NULL;
 	*fptr_ptr = NULL;
 	*zobj_ptr_ptr = NULL;
@@ -2790,7 +2847,7 @@
 				return 1;
 			}
 
-			return zend_is_callable_check_func(check_flags|IS_CALLABLE_CHECK_IS_STATIC, zobj_ptr_ptr, NULL, callable, ce_ptr, fptr_ptr TSRMLS_CC);
+			return zend_is_callable_check_func(check_flags, zobj_ptr_ptr, NULL, callable, ce_ptr, fptr_ptr, error TSRMLS_CC);
 
 		case IS_ARRAY:
 			{
@@ -2935,10 +2992,23 @@
 					}
 
 					if (ce) {
-						return zend_is_callable_check_func(check_flags, zobj_ptr_ptr, ce, *method, ce_ptr, fptr_ptr TSRMLS_CC);
+						return zend_is_callable_check_func(check_flags, zobj_ptr_ptr, ce, *method, ce_ptr, fptr_ptr, error TSRMLS_CC);
+					} else {
+						if (error) zend_spprintf(error, 0, "first array member is not a valid %s", Z_TYPE_PP(obj) == IS_STRING ? "class name" : "object");
+					}
+				} else {
+					if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
+						if (!obj) {
+							if (error) zend_spprintf(error, 0, "first array member is not a valid class name or object");
+						} else {
+							if (error) zend_spprintf(error, 0, "second array member is not a valid method");
+						}
+					} else {
+						if (error) zend_spprintf(error, 0, "array must have exactly two members");
+					}
+					if (callable_name) {
+						ZVAL_ASCII_STRINGL(callable_name, "Array", sizeof("Array")-1, 1);
 					}
-				} else if (callable_name) {
-					ZVAL_ASCII_STRINGL(callable_name, "Array", sizeof("Array")-1, 1);
 				}
 				*ce_ptr = ce;
 			}
@@ -2950,6 +3020,7 @@
 				zval_copy_ctor(callable_name);
 				convert_to_text(callable_name);
 			}
+			if (error) zend_spprintf(error, 0, "no array or string given");
 			return 0;
 	}
 }
@@ -2959,52 +3030,36 @@
 {
 	TSRMLS_FETCH();
 
-	return zend_is_callable_ex(callable, check_flags, callable_name, NULL, NULL, NULL TSRMLS_CC);
+	return zend_is_callable_ex(callable, check_flags, callable_name, NULL, NULL, NULL, NULL TSRMLS_CC);
 }
 /* }}} */
 
 ZEND_API zend_bool zend_make_callable(zval *callable, zval *callable_name TSRMLS_DC) /* {{{ */
 {
-	char *lcname, *func, *class_name;
-	zend_bool retval = 0;
-	zend_class_entry **pce;
-	int class_name_len;
+	zend_class_entry *ce;
+	zend_function *fptr;
+	zval **zobj_ptr;
 
-	if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, NULL, NULL, NULL TSRMLS_CC)) {
+	if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, &ce, &fptr, &zobj_ptr, NULL TSRMLS_CC)) {
+		if ((Z_TYPE_P(callable) == IS_STRING || Z_TYPE_P(callable) == IS_UNICODE) && ce) {
+			zval_dtor(callable);
+			array_init(callable);
+			add_next_index_text(callable, ce->name, 1);
+			add_next_index_text(callable, fptr->common.function_name, 1);
+		}
 		return 1;
 	}
-	switch (Z_TYPE_P(callable)) {
-		case IS_STRING:
-			lcname = zend_str_tolower_dup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
-
-			if ((func = strstr(lcname, "::")) != NULL) {
-				*func = '\0';
-				class_name_len = func - lcname;
-				class_name = estrndup(Z_STRVAL_P(callable), class_name_len);
-				if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == SUCCESS) {
-					zval_dtor(callable);
-					array_init(callable);
-					add_next_index_stringl(callable, lcname, class_name_len, 1);
-					func += 2;
-					add_next_index_stringl(callable, func, strlen(func), 1);
-					retval = 1;
-				}
-				efree(class_name);
-			}
-			efree(lcname);
-			break;
-	}
-	return retval;
+	return 0;
 }
 /* }}} */
 
-ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *callable_name TSRMLS_DC) /* {{{ */
+ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *callable_name, char **error TSRMLS_DC) /* {{{ */
 {
 	zend_class_entry *ce;
 	zend_function *func;
 	zval **obj;
 
-	if (!zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, &ce, &func, &obj TSRMLS_CC)) {
+	if (!zend_is_callable_ex(callable, check_flags, callable_name, &ce, &func, &obj, error TSRMLS_CC)) {
 		return FAILURE;
 	}
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.h?r1=1.296&r2=1.297&diff_format=u
Index: ZendEngine2/zend_API.h
diff -u ZendEngine2/zend_API.h:1.296 ZendEngine2/zend_API.h:1.297
--- ZendEngine2/zend_API.h:1.296	Thu Jan 24 18:08:06 2008
+++ ZendEngine2/zend_API.h	Sat Feb  2 15:23:22 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.h,v 1.296 2008/01/24 18:08:06 dmitry Exp $ */
+/* $Id: zend_API.h,v 1.297 2008/02/02 15:23:22 helly Exp $ */
 
 #ifndef ZEND_API_H
 #define ZEND_API_H
@@ -233,7 +233,7 @@
 
 #define IS_CALLABLE_STRICT  (IS_CALLABLE_CHECK_IS_STATIC)
 
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr TSRMLS_DC);
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, zval *callable_name, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr, char **error TSRMLS_DC);
 ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, zval *callable_name);
 ZEND_API zend_bool zend_make_callable(zval *callable, zval *callable_name TSRMLS_DC);
 ZEND_API const char *zend_get_module_version(const char *module_name);
@@ -1534,8 +1534,9 @@
  * fci->param_count = 0;
  * fci->params = NULL;
  * The callable_name argument may be NULL.
+ * Set check_flags to IS_CALLABLE_STRICT for every new usage!
  */
-ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *callable_name TSRMLS_DC);
+ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *callable_name, char **error TSRMLS_DC);
 
 /** Clear argumens connected with zend_fcall_info *fci
  * If free_mem is not zero then the params array gets free'd as well
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute_API.c?r1=1.435&r2=1.436&diff_format=u
Index: ZendEngine2/zend_execute_API.c
diff -u ZendEngine2/zend_execute_API.c:1.435 ZendEngine2/zend_execute_API.c:1.436
--- ZendEngine2/zend_execute_API.c:1.435	Wed Jan 30 12:30:57 2008
+++ ZendEngine2/zend_execute_API.c	Sat Feb  2 15:23:22 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_execute_API.c,v 1.435 2008/01/30 12:30:57 tony2001 Exp $ */
+/* $Id: zend_execute_API.c,v 1.436 2008/02/02 15:23:22 helly Exp $ */
 
 #include <stdio.h>
 #include <signal.h>
@@ -1145,12 +1145,15 @@
 		EG(This) = NULL;
 		if (calling_scope && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
 			int severity;
+			char *verb;
 			if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
 				severity = E_STRICT;
+				verb = "should not";
 			} else {
 				severity = E_ERROR;
+				verb = "cannot";
 			}
-			zend_error(severity, "Non-static method %v::%v() cannot be called statically", calling_scope->name, EX(function_state).function->common.function_name);
+			zend_error(severity, "Non-static method %v::%v() %s be called statically", calling_scope->name, EX(function_state).function->common.function_name, verb);
 		}
 	}
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.210&r2=1.211&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.210 ZendEngine2/zend_vm_def.h:1.211
--- ZendEngine2/zend_vm_def.h:1.210	Thu Jan 24 18:08:06 2008
+++ ZendEngine2/zend_vm_def.h	Sat Feb  2 15:23:22 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.210 2008/01/24 18:08:06 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.211 2008/02/02 15:23:22 helly Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -2026,7 +2026,16 @@
 		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
 		    /* We are calling method of the other (incompatible) class,
 		       but passing $this. This is done for compatibility with php-4. */
-			zend_error(E_STRICT, "Non-static method %v::%v() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+			int severity;
+			char *verb;
+			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+				severity = E_STRICT;
+				verb = "should not";
+			} else {
+				severity = E_ERROR;
+				verb = "cannot";
+			}
+			zend_error(severity, "Non-static method %v::%v() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);
 
 		}
 		if ((EX(object) = EG(This))) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.