]> granicus.if.org Git - php/commitdiff
Clean up zend_check_magic_method_implementation
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 20 Jul 2020 08:11:52 +0000 (10:11 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 20 Jul 2020 08:17:40 +0000 (10:17 +0200)
Let everything go through a common function, which fixes some
consistency issues.

Zend/tests/errmsg_015.phpt
Zend/tests/errmsg_019.phpt
Zend/zend_API.c

index ceac72c5d20453c9985df1820014740c70136ae6..429a852cdf1fc03f5b83c3d1e64e4a0a15b8635b 100644 (file)
@@ -11,4 +11,4 @@ class test {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Method test::__clone() cannot accept any arguments in %s on line %d
+Fatal error: Method test::__clone() cannot take arguments in %s on line %d
index 5f6ab0f08f9d6464ea01b72f0d09d65bcfca29a8..6f7780da0d7b32c4fd68931dd4a08625284676d3 100644 (file)
@@ -11,4 +11,4 @@ class test {
 echo "Done\n";
 ?>
 --EXPECTF--
-Fatal error: Destructor test::__destruct() cannot take arguments in %s on line %d
+Fatal error: Method test::__destruct() cannot take arguments in %s on line %d
index 6e200a15c3d54e9a1e93ce7bbd9547ebf348ba28..41d09a22d8389197b46226fed28761ccbd5b817f 100644 (file)
@@ -2007,6 +2007,32 @@ ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *mod
 }
 /* }}} */
 
+static void zend_check_magic_method_args(
+               uint32_t num_args, const char *name,
+               const zend_class_entry *ce, const zend_function *fptr, int error_type)
+{
+       if (fptr->common.num_args != num_args) {
+               if (num_args == 0) {
+                       zend_error(error_type, "Method %s::%s() cannot take arguments",
+                               ZSTR_VAL(ce->name), name);
+               } else if (num_args == 1) {
+                       zend_error(error_type, "Method %s::%s() must take exactly 1 argument",
+                               ZSTR_VAL(ce->name), name);
+               } else {
+                       zend_error(error_type, "Method %s::%s() must take exactly %" PRIu32 " arguments",
+                               ZSTR_VAL(ce->name), name, num_args);
+               }
+               return;
+       }
+       for (uint32_t i = 0; i < num_args; i++) {
+               if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, i + 1)) {
+                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference",
+                               ZSTR_VAL(ce->name), name);
+                       return;
+               }
+       }
+}
+
 ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */
 {
        if (ZSTR_VAL(fptr->common.function_name)[0] != '_'
@@ -2014,54 +2040,30 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce,
                return;
        }
 
-       if (zend_string_equals_literal(lcname, ZEND_DESTRUCTOR_FUNC_NAME) && fptr->common.num_args != 0) {
-               zend_error(error_type, "Destructor %s::%s() cannot take arguments", ZSTR_VAL(ce->name), ZEND_DESTRUCTOR_FUNC_NAME);
-       } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME) && fptr->common.num_args != 0) {
-               zend_error(error_type, "Method %s::%s() cannot accept any arguments", ZSTR_VAL(ce->name), ZEND_CLONE_FUNC_NAME);
+       if (zend_string_equals_literal(lcname, ZEND_DESTRUCTOR_FUNC_NAME)) {
+               zend_check_magic_method_args(0, "__destruct", ce, fptr, error_type);
+       } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) {
+               zend_check_magic_method_args(0, "__clone", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) {
-               if (fptr->common.num_args != 1) {
-                       zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_GET_FUNC_NAME);
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
-                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_GET_FUNC_NAME);
-               }
+               zend_check_magic_method_args(1, "__get", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) {
-               if (fptr->common.num_args != 2) {
-                       zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_SET_FUNC_NAME);
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
-                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_SET_FUNC_NAME);
-               }
+               zend_check_magic_method_args(2, "__set", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) {
-               if (fptr->common.num_args != 1) {
-                       zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_UNSET_FUNC_NAME);
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
-                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_UNSET_FUNC_NAME);
-               }
+               zend_check_magic_method_args(1, "__unset", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) {
-               if (fptr->common.num_args != 1) {
-                       zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ZSTR_VAL(ce->name), ZEND_ISSET_FUNC_NAME);
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) {
-                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_ISSET_FUNC_NAME);
-               }
+               zend_check_magic_method_args(1, "__isset", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) {
-               if (fptr->common.num_args != 2) {
-                       zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_CALL_FUNC_NAME);
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
-                       zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_CALL_FUNC_NAME);
-               }
+               zend_check_magic_method_args(2, "__call", ce, fptr, error_type);
        } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) {
-               if (fptr->common.num_args != 2) {
-                       zend_error(error_type, "Method %s::__callStatic() must take exactly 2 arguments", ZSTR_VAL(ce->name));
-               } else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
-                       zend_error(error_type, "Method %s::__callStatic() cannot take arguments by reference", ZSTR_VAL(ce->name));
-               }
-       } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME) && fptr->common.num_args != 0) {
-               zend_error(error_type, "Method %s::__toString() cannot take arguments", ZSTR_VAL(ce->name));
-       } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME) && fptr->common.num_args != 0) {
-               zend_error(error_type, "Method %s::__debugInfo() cannot take arguments", ZSTR_VAL(ce->name));
-       } else if (zend_string_equals_literal(lcname, "__serialize") && fptr->common.num_args != 0) {
-               zend_error(error_type, "Method %s::__serialize() cannot take arguments", ZSTR_VAL(ce->name));
-       } else if (zend_string_equals_literal(lcname, "__unserialize") && fptr->common.num_args != 1) {
-               zend_error(error_type, "Method %s::__unserialize() must take exactly 1 argument", ZSTR_VAL(ce->name));
+               zend_check_magic_method_args(2, "__callStatic", ce, fptr, error_type);
+       } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
+               zend_check_magic_method_args(0, "__toString", ce, fptr, error_type);
+       } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
+               zend_check_magic_method_args(0, "__debugInfo", ce, fptr, error_type);
+       } else if (zend_string_equals_literal(lcname, "__serialize")) {
+               zend_check_magic_method_args(0, "__serialize", ce, fptr, error_type);
+       } else if (zend_string_equals_literal(lcname, "__unserialize")) {
+               zend_check_magic_method_args(1, "__unserialize", ce, fptr, error_type);
        }
 }
 /* }}} */