From 7b003c04a83a251da4f0beeb287fee2e68f2b23a Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Tue, 16 Feb 2021 22:52:52 +0100 Subject: [PATCH 1/2] MDL-70920 backup: call_user_func_array can accept named arguments Because arguments names do not match in associative array, we change it to regular array or arguments --- backup/util/ui/base_moodleform.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backup/util/ui/base_moodleform.class.php b/backup/util/ui/base_moodleform.class.php index 391551622d5..4d2aefb2892 100644 --- a/backup/util/ui/base_moodleform.class.php +++ b/backup/util/ui/base_moodleform.class.php @@ -207,7 +207,8 @@ abstract class base_moodleform extends moodleform { $this->add_html_formatting($setting); // Then call the add method with the get_element_properties array. - call_user_func_array(array($this->_form, 'addElement'), $setting->get_ui()->get_element_properties($task, $OUTPUT)); + call_user_func_array(array($this->_form, 'addElement'), + array_values($setting->get_ui()->get_element_properties($task, $OUTPUT))); $this->_form->setType($setting->get_ui_name(), $setting->get_param_validation()); $defaults[$setting->get_ui_name()] = $setting->get_value(); if ($setting->has_help()) { @@ -335,7 +336,7 @@ abstract class base_moodleform extends moodleform { $mform = $this->_form; // Apply all dependencies for backup. foreach ($setting->get_my_dependency_properties() as $key => $dependency) { - call_user_func_array(array($this->_form, 'disabledIf'), $dependency); + call_user_func_array(array($this->_form, 'disabledIf'), array_values($dependency)); } } From f4fb91aecb73a3a4fdcb044dae3692c7da20b904 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Thu, 18 Feb 2021 11:49:43 +0100 Subject: [PATCH 2/2] MDL-70920 core: prevent calls to call_user_fun_array() with assoc array --- lib/classes/shutdown_manager.php | 2 +- lib/ddl/sql_generator.php | 2 +- lib/dml/sqlsrv_native_moodle_database.php | 2 +- lib/moodlelib.php | 10 ++++++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/classes/shutdown_manager.php b/lib/classes/shutdown_manager.php index 101b4a1417b..ffd0da99485 100644 --- a/lib/classes/shutdown_manager.php +++ b/lib/classes/shutdown_manager.php @@ -144,7 +144,7 @@ class core_shutdown_manager { error_log('Invalid custom shutdown function detected '.var_export($callback, true)); // @codingStandardsIgnoreEnd } - self::$callbacks[] = [$callback, $params ?? []]; + self::$callbacks[] = [$callback, $params ? array_values($params) : []]; } /** diff --git a/lib/ddl/sql_generator.php b/lib/ddl/sql_generator.php index 99fd21f1390..6215eb1e2c0 100644 --- a/lib/ddl/sql_generator.php +++ b/lib/ddl/sql_generator.php @@ -1237,7 +1237,7 @@ abstract class sql_generator { } // Now call the standard $DB->sql_concat() DML function - return call_user_func_array(array($this->mdb, 'sql_concat'), $elements); + return call_user_func_array(array($this->mdb, 'sql_concat'), array_values($elements)); } /** diff --git a/lib/dml/sqlsrv_native_moodle_database.php b/lib/dml/sqlsrv_native_moodle_database.php index 799438b6591..a359c8999e8 100644 --- a/lib/dml/sqlsrv_native_moodle_database.php +++ b/lib/dml/sqlsrv_native_moodle_database.php @@ -1426,7 +1426,7 @@ class sqlsrv_native_moodle_database extends moodle_database { for ($n = count($elements) - 1; $n > 0; $n--) { array_splice($elements, $n, 0, $separator); } - return call_user_func_array(array($this, 'sql_concat'), $elements); + return call_user_func_array(array($this, 'sql_concat'), array_values($elements)); } public function sql_isempty($tablename, $fieldname, $nullablefield, $textfield) { diff --git a/lib/moodlelib.php b/lib/moodlelib.php index e9947ad1bad..75ac71f4bde 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8062,6 +8062,16 @@ function component_callback($component, $function, array $params = array(), $def $functionname = component_callback_exists($component, $function); + if ($params && (array_keys($params) !== range(0, count($params) - 1))) { + // PHP 8 allows to have associative arrays in the call_user_func_array() parameters but + // PHP 7 does not. Using associative arrays can result in different behavior in different PHP versions. + // See https://php.watch/versions/8.0/named-parameters#named-params-call_user_func_array + // This check can be removed when minimum PHP version for Moodle is raised to 8. + debugging('Parameters array can not be an associative array while Moodle supports both PHP 7 and PHP 8.', + DEBUG_DEVELOPER); + $params = array_values($params); + } + if ($functionname) { // Function exists, so just return function result. $ret = call_user_func_array($functionname, $params);