From 594a8c5ab7c4e24a19723c96f4ae8428d8294f82 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Thu, 17 Nov 2022 15:44:35 +0100 Subject: [PATCH 1/2] MDL-76356 various: avoid implicit conversion to arrays PHP before version 8.1 automatically converted stdClass or 'false' to arrays if function parameter expects array (for example, "reset"). PHP 8.1 shows notices in these situations --- admin/roles/tests/privacy/provider_test.php | 2 +- admin/tool/policy/classes/output/page_agreedocs.php | 2 +- analytics/classes/calculation_info.php | 2 +- h5p/tests/helper_test.php | 2 ++ lib/completionlib.php | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/admin/roles/tests/privacy/provider_test.php b/admin/roles/tests/privacy/provider_test.php index fab062222a3..2504be7f822 100644 --- a/admin/roles/tests/privacy/provider_test.php +++ b/admin/roles/tests/privacy/provider_test.php @@ -187,7 +187,7 @@ class provider_test extends provider_testcase { $writer = writer::with_context($context); $this->assertTrue($writer->has_any_data()); if ($context->contextlevel == CONTEXT_MODULE) { - if ($data = $writer->get_data($subcontextstudent)) { + if ($data = (array)$writer->get_data($subcontextstudent)) { $this->assertEquals($user->id, reset($data)->userid); } if ($data = (array)$writer->get_data($subcontextrc)) { diff --git a/admin/tool/policy/classes/output/page_agreedocs.php b/admin/tool/policy/classes/output/page_agreedocs.php index 8681715f945..d744f2729bb 100644 --- a/admin/tool/policy/classes/output/page_agreedocs.php +++ b/admin/tool/policy/classes/output/page_agreedocs.php @@ -278,7 +278,7 @@ class page_agreedocs implements renderable, templatable { $cache = \cache::make('core', 'presignup'); $cachekey = 'tool_policy_viewedpolicies'; - $viewedpolicies = $cache->get($cachekey); + $viewedpolicies = $cache->get($cachekey) ?: []; if (!empty($viewedpolicies)) { // Get the list of the policies docs which the user haven't viewed during this session. $pendingpolicies = array_diff($currentpolicyversionids, $viewedpolicies); diff --git a/analytics/classes/calculation_info.php b/analytics/classes/calculation_info.php index 2be73d21d5d..0d69d275f34 100644 --- a/analytics/classes/calculation_info.php +++ b/analytics/classes/calculation_info.php @@ -99,7 +99,7 @@ class calculation_info { $samplekey = self::get_sample_key($uniquesampleid); // Update the cached data adding the new indicator data. - $cacheddata = $cache->get($samplekey); + $cacheddata = $cache->get($samplekey) ?: []; $cacheddata[$calculableclass] = $infokeys; $cache->set($samplekey, $cacheddata); } diff --git a/h5p/tests/helper_test.php b/h5p/tests/helper_test.php index fedede87593..5e8622015d5 100644 --- a/h5p/tests/helper_test.php +++ b/h5p/tests/helper_test.php @@ -305,7 +305,9 @@ class helper_test extends \advanced_testcase { $this->assertTrue(empty($messages->info)); // Add an some messages manually and check they are still there. + $messages->error = []; $messages->error['error1'] = 'Testing ERROR message'; + $messages->info = []; $messages->info['info1'] = 'Testing INFO message'; $messages->info['info2'] = 'Testing INFO message'; helper::get_messages($messages, $factory); diff --git a/lib/completionlib.php b/lib/completionlib.php index 46bad39d87a..aae0552e349 100644 --- a/lib/completionlib.php +++ b/lib/completionlib.php @@ -1055,7 +1055,7 @@ class completion_info { if (!isset($this->course->cacherev)) { $this->course = get_course($this->course_id); } - if ($cacheddata = $completioncache->get($key)) { + if ($cacheddata = ($completioncache->get($key) ?: [])) { if ($cacheddata['cacherev'] != $this->course->cacherev) { // Course structure has been changed since the last caching, forget the cache. $cacheddata = array(); From b1c97381b4a9e409f5d2a23f134817f569623aa7 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Thu, 17 Nov 2022 15:49:48 +0100 Subject: [PATCH 2/2] MDL-76356 various: avoid implicit conversion to int PHP before version 8.1 automatically converted to int if the function parameter (or array key) is expected to be int. PHP 8.1 shows notice in this case --- admin/tool/behat/cli/run.php | 2 +- lib/behat/classes/behat_config_util.php | 2 +- lib/classes/message/inbound/address_manager.php | 6 ++---- lib/classes/plugininfo/base.php | 3 ++- lib/classes/session/redis.php | 2 +- lib/gdlib.php | 4 ++-- .../classes/completion/custom_completion.php | 2 +- mod/h5pactivity/classes/local/attempt.php | 2 +- question/classes/statistics/questions/calculator.php | 5 +++-- question/engine/lib.php | 4 ++-- question/type/multianswer/renderer.php | 2 +- search/classes/engine.php | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/admin/tool/behat/cli/run.php b/admin/tool/behat/cli/run.php index a5dfa1d8b11..afaddd8b88d 100644 --- a/admin/tool/behat/cli/run.php +++ b/admin/tool/behat/cli/run.php @@ -278,7 +278,7 @@ if (empty($parallelrun)) { // Print combined run o/p from processes. $exitcodes = print_combined_run_output($processes, $stoponfail); // Time to finish run. - $time = round(microtime(true) - $time, 1); + $time = round(microtime(true) - $time, 0); echo "Finished in " . gmdate("G\h i\m s\s", $time) . PHP_EOL . PHP_EOL; ksort($exitcodes); diff --git a/lib/behat/classes/behat_config_util.php b/lib/behat/classes/behat_config_util.php index cde958e2456..804d0a223ad 100644 --- a/lib/behat/classes/behat_config_util.php +++ b/lib/behat/classes/behat_config_util.php @@ -893,7 +893,7 @@ class behat_config_util { && (!defined('PHPUNIT_TEST') || !PHPUNIT_TEST)) { echo "Bucket weightings:\n"; foreach ($weights as $k => $weight) { - echo $k + 1 . ": " . str_repeat('*', 70 * $nbuckets * $weight / $totalweight) . PHP_EOL; + echo $k + 1 . ": " . str_repeat('*', (int)(70 * $nbuckets * $weight / $totalweight)) . PHP_EOL; } } diff --git a/lib/classes/message/inbound/address_manager.php b/lib/classes/message/inbound/address_manager.php index dbe7f26d94b..0d07227bb01 100644 --- a/lib/classes/message/inbound/address_manager.php +++ b/lib/classes/message/inbound/address_manager.php @@ -459,10 +459,8 @@ class address_manager { */ protected function pack_int($int) { if (PHP_INT_SIZE === 8) { - $left = 0xffffffff00000000; - $right = 0x00000000ffffffff; - $l = ($int & $left) >>32; - $r = $int & $right; + $l = intdiv($int, pow(2, 32)); // 32-bit integer quotient. + $r = $int % pow(2, 32); // 32-bit integer remaining. return pack('NN', $l, $r); } else { diff --git a/lib/classes/plugininfo/base.php b/lib/classes/plugininfo/base.php index e7aed5c794b..40e20de4686 100644 --- a/lib/classes/plugininfo/base.php +++ b/lib/classes/plugininfo/base.php @@ -285,7 +285,8 @@ abstract class base { } if (isset($plugin->incompatible) && $plugin->incompatible !== null) { - if ((ctype_digit($plugin->incompatible) || is_int($plugin->incompatible)) && (int) $plugin->incompatible > 0) { + if (((is_string($plugin->incompatible) && ctype_digit($plugin->incompatible)) || is_int($plugin->incompatible)) + && (int) $plugin->incompatible > 0) { $this->pluginincompatible = intval($plugin->incompatible); } else { throw new coding_exception('Incorrect syntax in plugin incompatible declaration in '."$this->name"); diff --git a/lib/classes/session/redis.php b/lib/classes/session/redis.php index c7e6d407772..157effda5e8 100644 --- a/lib/classes/session/redis.php +++ b/lib/classes/session/redis.php @@ -511,7 +511,7 @@ class redis extends handler { // time. If it is too small we will poll too much and if it is // too large we will waste time waiting for no reason. 100ms is // the default starting point. - $delay = rand($this->lockretry, $this->lockretry * 1.1); + $delay = rand($this->lockretry, (int)($this->lockretry * 1.1)); } else { // If we don't get a lock within 5 seconds then there must be a // very long lived process holding the lock so throttle back to diff --git a/lib/gdlib.php b/lib/gdlib.php index c384d79f2aa..9c7e50aae8d 100644 --- a/lib/gdlib.php +++ b/lib/gdlib.php @@ -216,8 +216,8 @@ function process_new_icon($context, $component, $filearea, $itemid, $originalfil $im3 = imagecreate(512, 512); } - $cx = $image->width / 2; - $cy = $image->height / 2; + $cx = floor($image->width / 2); + $cy = floor($image->height / 2); if ($image->width < $image->height) { $half = floor($image->width / 2.0); diff --git a/mod/bigbluebuttonbn/classes/completion/custom_completion.php b/mod/bigbluebuttonbn/classes/completion/custom_completion.php index 6f2518eb1be..3de9569e87d 100644 --- a/mod/bigbluebuttonbn/classes/completion/custom_completion.php +++ b/mod/bigbluebuttonbn/classes/completion/custom_completion.php @@ -229,7 +229,7 @@ class custom_completion extends activity_custom_completion { */ protected static function get_completionattendance_value(stdClass $log): int { $summary = json_decode($log->meta); - return empty($summary->data->duration) ? 0 : $summary->data->duration / 60; + return empty($summary->data->duration) ? 0 : (int)($summary->data->duration / 60); } /** diff --git a/mod/h5pactivity/classes/local/attempt.php b/mod/h5pactivity/classes/local/attempt.php index 0333f766f55..a200db2309e 100644 --- a/mod/h5pactivity/classes/local/attempt.php +++ b/mod/h5pactivity/classes/local/attempt.php @@ -493,7 +493,7 @@ class attempt { * @return int|null the scaled value */ public function get_scaled(): ?int { - return $this->record->scaled; + return is_null($this->record->scaled) ? $this->record->scaled : (int)$this->record->scaled; } /** diff --git a/question/classes/statistics/questions/calculator.php b/question/classes/statistics/questions/calculator.php index e9afff3d6a9..64a673e4919 100644 --- a/question/classes/statistics/questions/calculator.php +++ b/question/classes/statistics/questions/calculator.php @@ -228,8 +228,9 @@ class calculator { $this->sumofmarkvariance += $this->stats->for_slot($slot)->markvariance; - if ($this->stats->for_slot($slot)->covariancewithoverallmark >= 0) { - $sumofcovariancewithoverallmark += sqrt($this->stats->for_slot($slot)->covariancewithoverallmark); + $covariancewithoverallmark = $this->stats->for_slot($slot)->covariancewithoverallmark; + if (null !== $covariancewithoverallmark && $covariancewithoverallmark >= 0) { + $sumofcovariancewithoverallmark += sqrt($covariancewithoverallmark); } } $this->progress->end_progress(); diff --git a/question/engine/lib.php b/question/engine/lib.php index ace64193025..0b06d492005 100644 --- a/question/engine/lib.php +++ b/question/engine/lib.php @@ -917,8 +917,8 @@ abstract class question_utils { 'converted to roman numerals.', $number); } - return self::$thousands[$number / 1000 % 10] . self::$hundreds[$number / 100 % 10] . - self::$tens[$number / 10 % 10] . self::$units[$number % 10]; + return self::$thousands[floor($number / 1000) % 10] . self::$hundreds[floor($number / 100) % 10] . + self::$tens[floor($number / 10) % 10] . self::$units[$number % 10]; } /** diff --git a/question/type/multianswer/renderer.php b/question/type/multianswer/renderer.php index 27c31e9a6fd..aa4a444bec3 100644 --- a/question/type/multianswer/renderer.php +++ b/question/type/multianswer/renderer.php @@ -239,7 +239,7 @@ class qtype_multianswer_textfield_renderer extends qtype_multianswer_subq_render foreach ($subq->answers as $ans) { $size = max($size, core_text::strlen(trim($ans->answer))); } - $size = min(60, round($size + rand(0, $size * 0.15))); + $size = min(60, round($size + rand(0, (int)($size * 0.15)))); // The rand bit is to make guessing harder. $inputattributes = array( diff --git a/search/classes/engine.php b/search/classes/engine.php index 367879ecd34..788c27a4f08 100644 --- a/search/classes/engine.php +++ b/search/classes/engine.php @@ -307,7 +307,7 @@ abstract class engine { if ($now - $lastprogress >= manager::DISPLAY_INDEXING_PROGRESS_EVERY) { $lastprogress = $now; // The first date format is the same used in cron_trace_time_and_memory(). - $options['progress']->output(date('H:i:s', $now) . ': Done to ' . userdate( + $options['progress']->output(date('H:i:s', (int)$now) . ': Done to ' . userdate( $lastindexeddoc, get_string('strftimedatetimeshort', 'langconfig')), 1); } }