]> granicus.if.org Git - php/commitdiff
Add tests to check mismatching function signatures
authorMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 5 Jun 2020 12:40:40 +0000 (14:40 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Sat, 6 Jun 2020 07:23:34 +0000 (09:23 +0200)
Closes GH-5666

Zend/tests/arginfo_zpp_mismatch.phpt [new file with mode: 0644]
ext/intl/calendar/calendar_methods.cpp
ext/opcache/tests/func_info.phpt [new file with mode: 0644]
ext/session/session.c
ext/standard/basic_functions.c
ext/standard/basic_functions.stub.php
ext/standard/basic_functions_arginfo.h

diff --git a/Zend/tests/arginfo_zpp_mismatch.phpt b/Zend/tests/arginfo_zpp_mismatch.phpt
new file mode 100644 (file)
index 0000000..9762dd5
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+Test that there is no arginfo/zpp mismatch
+--FILE--
+<?php
+
+foreach (get_defined_functions()["internal"] as $function) {
+    try {
+        @$function(null, null, null, null, null, null, null, null);
+    } catch (ArgumentCountError|Error) {
+    }
+}
+
+// var_dump() and debug_zval_dump() print all arguments
+?>
+--EXPECT--
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
index b38a2f19610de8c2d06e6f0e0e383fe3d85d6f19..cc1f78cba25438aaf5b591bef1300a0a33fbff60 100644 (file)
@@ -427,51 +427,34 @@ U_CFUNC PHP_FUNCTION(intlcal_set)
 
 U_CFUNC PHP_FUNCTION(intlcal_roll)
 {
-       zend_long               field,
-                               value;
-       zval            args_a[3]                = {0},
-                               *args                    = args_a;
-       zend_bool       bool_variant_val;
+       zval *zvalue;
+       zend_long field, value;
        CALENDAR_METHOD_INIT_VARS;
 
-       object = getThis();
-
-       if (ZEND_NUM_ARGS() > (object ? 2 :3) ||
-                       zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "intlcal_set: too many arguments", 0);
-               RETURN_FALSE;
-       }
-       if (!object) {
-               args++;
-       }
-       if (!Z_ISUNDEF(args[1]) && (Z_TYPE(args[1]) == IS_TRUE || Z_TYPE(args[1]) == IS_FALSE)) {
-               if (zend_parse_method_parameters(ZEND_NUM_ARGS(), object,
-                               "Olb", &object, Calendar_ce_ptr, &field, &bool_variant_val)
-                               == FAILURE) {
-                       RETURN_THROWS();
-               }
-               /* false corresponds to rolling down, i.e. -1 */
-               value = Z_TYPE(args[1]) == IS_TRUE? 1 : -1;
-       } else if (zend_parse_method_parameters(ZEND_NUM_ARGS(), object,
-                       "Oll", &object, Calendar_ce_ptr, &field, &value) == FAILURE) {
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Olz", &object, Calendar_ce_ptr, &field, &zvalue) == FAILURE) {
                RETURN_THROWS();
        }
 
+       CALENDAR_METHOD_FETCH_OBJECT;
+
        if (field < 0 || field >= UCAL_FIELD_COUNT) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "intlcal_roll: invalid field", 0);
-               RETURN_FALSE;
-       }
-       if (value < INT32_MIN || value > INT32_MAX) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "intlcal_roll: value out of bounds", 0);
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_roll: invalid field", 0);
                RETURN_FALSE;
        }
 
-       CALENDAR_METHOD_FETCH_OBJECT;
+       if (Z_TYPE_P(zvalue) == IS_FALSE || Z_TYPE_P(zvalue) == IS_TRUE) {
+               value = Z_TYPE_P(zvalue) == IS_TRUE ? 1 : -1;
+       } else {
+               value = zval_get_long(zvalue);
+
+               if (value < INT32_MIN || value > INT32_MAX) {
+                       intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_roll: value out of bounds", 0);
+                       RETURN_FALSE;
+               }
+       }
 
        co->ucal->roll((UCalendarDateFields)field, (int32_t)value, CALENDAR_ERROR_CODE(co));
+
        INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll");
 
        RETURN_TRUE;
diff --git a/ext/opcache/tests/func_info.phpt b/ext/opcache/tests/func_info.phpt
new file mode 100644 (file)
index 0000000..71843a8
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+Test that return types in zend_func_info.c match return types in stubs
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$contents = "<?php\n";
+
+$contents .= "function test() {\n";
+foreach (get_defined_functions()["internal"] as $function) {
+    $contents .= "    {$function}();\n";
+}
+$contents .= "}\n";
+
+file_put_contents("func_info_generated.php", $contents);
+
+require_once("func_info_generated.php");
+
+?>
+--CLEAN--
+<?php
+
+unlink("func_info_generated.php");
+
+?>
+--EXPECT--
index 220bfe3638deb9025aeedf667c75f5d51353f142..993f6a063f5d9c2ad370da732691dc8d36c49a9f 100644 (file)
@@ -1917,24 +1917,28 @@ PHP_FUNCTION(session_module_name)
 }
 /* }}} */
 
-/* {{{ proto bool session_set_save_handler(string open, string close, string read, string write, string destroy, string gc, string create_sid)
-   Sets user-level functions */
-PHP_FUNCTION(session_set_save_handler)
-{
-       zval *args = NULL;
-       int i, num_args, argc = ZEND_NUM_ARGS();
-       zend_string *ini_name, *ini_val;
-
+static int save_handler_check_session() {
        if (PS(session_status) == php_session_active) {
                php_error_docref(NULL, E_WARNING, "Cannot change save handler when session is active");
-               RETURN_FALSE;
+               return FAILURE;
        }
 
        if (SG(headers_sent)) {
                php_error_docref(NULL, E_WARNING, "Cannot change save handler when headers already sent");
-               RETURN_FALSE;
+               return FAILURE;
        }
 
+       return SUCCESS;
+}
+
+/* {{{ proto bool session_set_save_handler(string open, string close, string read, string write, string destroy, string gc, string create_sid)
+   Sets user-level functions */
+PHP_FUNCTION(session_set_save_handler)
+{
+       zval *args = NULL;
+       int i, num_args, argc = ZEND_NUM_ARGS();
+       zend_string *ini_name, *ini_val;
+
        if (argc > 0 && argc <= 2) {
                zval *obj = NULL;
                zend_string *func_name;
@@ -1945,6 +1949,10 @@ PHP_FUNCTION(session_set_save_handler)
                        RETURN_THROWS();
                }
 
+               if (save_handler_check_session() == FAILURE) {
+                       RETURN_FALSE;
+               }
+
                /* For compatibility reason, implemented interface is not checked */
                /* Find implemented methods - SessionHandlerInterface */
                i = 0;
@@ -2047,6 +2055,10 @@ PHP_FUNCTION(session_set_save_handler)
                RETURN_THROWS();
        }
 
+       if (save_handler_check_session() == FAILURE) {
+               RETURN_FALSE;
+       }
+
        /* remove shutdown function */
        remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") - 1);
 
index ac407108e01590f70dc1f447e4836b4156885e41..090f11e0abddc08e97f7434829c1d79c415e64f4 100755 (executable)
@@ -2540,14 +2540,14 @@ PHP_FUNCTION(is_uploaded_file)
        char *path;
        size_t path_len;
 
-       if (!SG(rfc1867_uploaded_files)) {
-               RETURN_FALSE;
-       }
-
        ZEND_PARSE_PARAMETERS_START(1, 1)
                Z_PARAM_PATH(path, path_len)
        ZEND_PARSE_PARAMETERS_END();
 
+       if (!SG(rfc1867_uploaded_files)) {
+               RETURN_FALSE;
+       }
+
        if (zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
                RETURN_TRUE;
        } else {
@@ -2568,15 +2568,15 @@ PHP_FUNCTION(move_uploaded_file)
        int oldmask; int ret;
 #endif
 
-       if (!SG(rfc1867_uploaded_files)) {
-               RETURN_FALSE;
-       }
-
        ZEND_PARSE_PARAMETERS_START(2, 2)
                Z_PARAM_STRING(path, path_len)
                Z_PARAM_PATH(new_path, new_path_len)
        ZEND_PARSE_PARAMETERS_END();
 
+       if (!SG(rfc1867_uploaded_files)) {
+               RETURN_FALSE;
+       }
+
        if (!zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
                RETURN_FALSE;
        }
index 963c5b02f4cf2155298775865182fc07959a3b34..babe88f81053af131f76269a5470ae743c66f589 100755 (executable)
@@ -357,7 +357,7 @@ function parse_ini_file(string $filename, bool $process_sections = false, int $s
 function parse_ini_string(string $ini_string, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array|false {}
 
 #if ZEND_DEBUG
-function config_get_hash(string $ini_string, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array {}
+function config_get_hash(): array {}
 #endif
 
 #ifdef HAVE_GETLOADAVG
index e7d77c1e81135c5d2863c353cd3fb1c39278d305..7c12e8d3575f23debf125d5e95eee6bf756c9a31 100755 (executable)
@@ -578,10 +578,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_parse_ini_string, 0, 1, MAY_BE_A
 ZEND_END_ARG_INFO()
 
 #if ZEND_DEBUG
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_config_get_hash, 0, 1, IS_ARRAY, 0)
-       ZEND_ARG_TYPE_INFO(0, ini_string, IS_STRING, 0)
-       ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, process_sections, _IS_BOOL, 0, "false")
-       ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, scanner_mode, IS_LONG, 0, "INI_SCANNER_NORMAL")
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_config_get_hash, 0, 0, IS_ARRAY, 0)
 ZEND_END_ARG_INFO()
 #endif