From c96894ecd433bde61ce51760c315ab3b515af38e Mon Sep 17 00:00:00 2001 From: Jakub Vrana Date: Wed, 26 Mar 2025 19:29:50 +0100 Subject: [PATCH] PHPStan: Fix level 5 errors --- adminer/drivers/mysql.inc.php | 14 +++++++------- adminer/include/editing.inc.php | 9 +++++---- adminer/include/functions.inc.php | 12 ++++++------ adminer/include/html.inc.php | 4 ++-- adminer/include/lang.inc.php | 2 +- adminer/include/plugins.inc.php | 2 +- adminer/select.inc.php | 4 ++-- compile.php | 2 +- phpstan.neon | 11 +++++++++-- 9 files changed, 34 insertions(+), 26 deletions(-) diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 9985df17..313cf7bd 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -24,11 +24,11 @@ if (!defined('Adminer\DRIVER')) { $this->ssl_set($ssl['key'], $ssl['cert'], $ssl['ca'], '', ''); } $return = @$this->real_connect( - ($server != "" ? $host : ini_get("mysqli.default_host")), - ($server . $username != "" ? $username : ini_get("mysqli.default_user")), - ($server . $username . $password != "" ? $password : ini_get("mysqli.default_pw")), + ($server != "" ? $host : null), + ($server . $username != "" ? $username : null), + ($server . $username . $password != "" ? $password : null), $database, - (is_numeric($port) ? $port : ini_get("mysqli.default_port")), + (is_numeric($port) ? intval($port) : null), (!is_numeric($port) ? $port : $socket), ($ssl ? ($ssl['verify'] !== false ? 2048 : 64) : 0) // 2048 - MYSQLI_CLIENT_SSL, 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16) ); @@ -649,7 +649,7 @@ if (!defined('Adminer\DRIVER')) { /** Get table indexes * @param string - * @param string Db to use + * @param ?Db * @return Index[] */ function indexes($table, $connection2 = null) { @@ -807,7 +807,7 @@ if (!defined('Adminer\DRIVER')) { * @param string "" to create * @param string new name * @param list, string}> of [$orig, $process_field, $after] - * @param list + * @param string[] * @param string * @param string * @param string @@ -1186,7 +1186,7 @@ if (!defined('Adminer\DRIVER')) { } /** Kill a process - * @param int + * @param numeric-string * @return Result|bool */ function kill_process($val) { diff --git a/adminer/include/editing.inc.php b/adminer/include/editing.inc.php index 97a492bc..c0ad3ab3 100644 --- a/adminer/include/editing.inc.php +++ b/adminer/include/editing.inc.php @@ -159,7 +159,7 @@ function select_input($attrs, $options, $value = "", $onchange = "", $placeholde /** Print one row in JSON object * @param string or "" to close the object -* @param string +* @param string|int * @return void */ function json_row($key, $val = null) { @@ -318,7 +318,7 @@ function type_class($type) { /** Print table interior for fields editing * @param Field[] -* @param list[] +* @param list * @param string TABLE or PROCEDURE * @param Field[] returned by referencable_primary() * @return void @@ -423,11 +423,12 @@ function process_fields(&$fields) { } /** Callback used in routine() -* @param list +* @param list * @return string */ function normalize_enum($match) { - return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($match[0][0] . $match[0][0], $match[0][0], substr($match[0], 1, -1))), '\\')) . "'"; + $val = $match[0]; + return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($val[0] . $val[0], $val[0], substr($val, 1, -1))), '\\')) . "'"; } /** Issue grant or revoke commands diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index 422027ab..faacd881 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -124,8 +124,8 @@ function bracket_escape($idf, $back = false) { } /** Check if connection has at least the given version -* @param string required version -* @param string required MariaDB version +* @param string|float required version +* @param string|float required MariaDB version * @param Db defaults to $connection * @return bool */ @@ -311,7 +311,7 @@ function where($where, $fields = array()) { global $connection; $return = array(); foreach ((array) $where["where"] as $key => $val) { - $key = bracket_escape($key, 1); // 1 - back + $key = bracket_escape($key, true); // true - back $column = escape_key($key); $field = idx($fields, $key, array()); $field_type = $field["type"]; @@ -694,7 +694,7 @@ function shorten_utf8($string, $length = 80, $suffix = "") { } /** Format decimal number -* @param int +* @param float|numeric-string * @return string */ function format_number($val) { @@ -749,7 +749,7 @@ function fields_from_edit() { // used by Mongo and SimpleDB } } foreach ((array) $_POST["fields"] as $key => $val) { - $name = bracket_escape($key, 1); // 1 - back + $name = bracket_escape($key, true); // true - back $return[$name] = array( "field" => $name, "privileges" => array("insert" => 1, "update" => 1, "where" => 1, "order" => 1), @@ -898,7 +898,7 @@ function password_file($create) { * @return string 32 hexadecimal characters */ function rand_string() { - return md5(uniqid(mt_rand(), true)); + return md5(uniqid(strval(mt_rand()), true)); } /** Format value to use in select diff --git a/adminer/include/html.inc.php b/adminer/include/html.inc.php index 9ef717c0..487190ec 100644 --- a/adminer/include/html.inc.php +++ b/adminer/include/html.inc.php @@ -27,7 +27,7 @@ function nonce() { /** Get * @param string -* @param string +* @param string|int * @return string HTML */ function input_hidden($name, $value = "") { @@ -68,7 +68,7 @@ function nl_br($string) { /** Generate HTML checkbox * @param string -* @param string +* @param string|int * @param bool * @param string * @param string diff --git a/adminer/include/lang.inc.php b/adminer/include/lang.inc.php index 9b4b27cb..b8f1f7bb 100644 --- a/adminer/include/lang.inc.php +++ b/adminer/include/lang.inc.php @@ -61,7 +61,7 @@ function get_lang() { /** Translate string * @param literal-string -* @param int +* @param float|string * @return string */ // this is matched by compile.php diff --git a/adminer/include/plugins.inc.php b/adminer/include/plugins.inc.php index 294c6135..98a24f2d 100644 --- a/adminer/include/plugins.inc.php +++ b/adminer/include/plugins.inc.php @@ -5,7 +5,7 @@ class Plugins extends Adminer { public $plugins; ///< @var list @visibility protected(set) /** Register plugins - * @param list object instances or null to autoload plugins from adminer-plugins/ + * @param ?list object instances or null to autoload plugins from adminer-plugins/ */ function __construct($plugins) { if ($plugins === null) { diff --git a/adminer/select.inc.php b/adminer/select.inc.php index cd305aeb..0a56766f 100644 --- a/adminer/select.inc.php +++ b/adminer/select.inc.php @@ -48,7 +48,7 @@ if ($_GET["val"] && is_ajax()) { $where[] = where_check($unique_idf, $fields); $return = $driver->select($TABLE, $select, $where, $select); if ($return) { - echo reset($return->fetch_row()); + echo first($return->fetch_row()); } } exit; @@ -170,7 +170,7 @@ if ($_POST && !$error) { foreach ($_POST["val"] as $unique_idf => $row) { $set = array(); foreach ($row as $key => $val) { - $key = bracket_escape($key, 1); // 1 - back + $key = bracket_escape($key, true); // true - back $set[idf_escape($key)] = (preg_match('~char|text~', $fields[$key]["type"]) || $val != "" ? $adminer->processInput($fields[$key], $val) : "NULL"); } $result = $driver->update( diff --git a/compile.php b/compile.php index 24f98f5e..516d050b 100755 --- a/compile.php +++ b/compile.php @@ -219,7 +219,7 @@ function minify_js($file) { return lzw_compress($file); } -function compile_file($match, $callback) { // $callback only to match signature +function compile_file($match, $callback = '') { // $callback only to match signature global $project; $file = ""; list(, $filenames, $callback) = $match; diff --git a/phpstan.neon b/phpstan.neon index 5902005e..89b7f93b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,9 +1,10 @@ parameters: - level: 4 + level: 5 ignoreErrors: # need to fix - "~^Function Adminer\\\\fields_from_edit\\(\\) should return~" # Mongo and SimpleDB - "~^Function Adminer\\\\explain\\(\\) should return Adminer\\\\Result~" # mysqli_result + - "~expects array~" # different shape of array # not real problems - identifier: include.fileNotFound # relative includes @@ -14,6 +15,11 @@ parameters: - "~^Method Adminer\\\\Plugins::\\w+\\(\\) with return type void~" # we use the same pattern for all methods - "~Call to function is_object\\(\\) with Adminer\\\\Db\\|string will always evaluate to false~" # is_object(Db) is true - "~^Comparison operation \"==\" between \\(array\\|float\\|int\\) and 1~" # it thinks that $affected could be an array + - "~^Parameter #2 \\$newvalue of function ini_set expects string~" # it expects string|int|float|bool|null + - "~expects int, float given~" # this will work + - "~expects bool~" # truthy values + - "~fread expects int<1, max>, 100000~" # 1e6 + - "~'strlen' given~" # used as a bool callback # it probably doesn't like $ar[$key] instead of isset($ar[$key]) and thinks that $ar[$key] is always set - identifier: identical.alwaysFalse @@ -54,5 +60,6 @@ parameters: Index: "array{type:string, columns:list, lengths:list, descs:list}" ForeignKey: "array{db:string, ns?:string, table:string, source:list, target:list, on_delete:string, on_update:string}" Trigger: "array{Trigger?:string, Timing?:string, Event?:string, Of?:string, Type?:string, Statement?:string}" - Routine: "array{name?:string, fields:list, comment:string, returns?:array, definition:string, language?:string}" + RoutineField: "array{field:string, type:string, length:?string, unsigned:string, null:bool, full_type:string, inout:string, collation:string}" + Routine: "array{name?:string, fields:list, comment:string, returns?:array, definition:string, language?:string}" BackwardKey: "array{name:string, keys:string[][]}"