]> git.joonet.de Git - adminer.git/commitdiff
PHPStan: Fix level 6 errors
authorJakub Vrana <jakub@vrana.cz>
Wed, 26 Mar 2025 20:06:01 +0000 (21:06 +0100)
committerJakub Vrana <jakub@vrana.cz>
Wed, 26 Mar 2025 20:54:00 +0000 (21:54 +0100)
14 files changed:
adminer/call.inc.php
adminer/drivers/mysql.inc.php
adminer/include/adminer.inc.php
adminer/include/auth.inc.php
adminer/include/coverage.inc.php
adminer/include/driver.inc.php
adminer/include/functions.inc.php
adminer/include/html.inc.php
adminer/include/lang.inc.php
adminer/include/plugins.inc.php
adminer/include/tmpfile.inc.php
adminer/include/xxtea.inc.php
compile.php
phpstan.neon

index 236ae3b4253abafceee3eaf82aa92e32ded812d1..e43241de126e468c298bda78bf1b616343d747e3 100644 (file)
@@ -91,9 +91,14 @@ if ($in) {
 
 <pre>
 <?php
+/** Format string as table row
+* @param string
+* @return string HTML
+*/
 function pre_tr($s) {
        return preg_replace('~^~m', '<tr>', preg_replace('~\|~', '<td>', preg_replace('~\|$~m', "", rtrim($s))));
 }
+
 $table = '(\+--[-+]+\+\n)';
 $row = '(\| .* \|\n)';
 echo preg_replace_callback(
index 313cf7bd3505206f4c116f4189e03f366d1cea6d..d8e558072ce818d0a573b81bd5e842ed4d16290e 100644 (file)
@@ -61,16 +61,16 @@ if (!defined('Adminer\DRIVER')) {
 
        } elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) {
                class Db {
-                       public
-                               $extension = "MySQL", ///< @var string extension name
-                               $flavor = '', ///< @var string different vendor with the same API, e.g. MariaDB, usually stays empty
-                               $server_info, ///< @var string server version
-                               $affected_rows, ///< @var int number of affected rows
-                               $info, ///< @var string see https://php.net/mysql_info
-                               $errno, ///< @var int last error code
-                               $error ///< @var string last error message
-                       ;
-                       private $link, $result;
+                       /** @var string */ public $extension = "MySQL"; // extension name
+                       /** @var string */ public $flavor = ''; // different vendor with the same API; e.g. MariaDB; usually stays empty
+                       /** @var string */ public $server_info; // server version
+                       /** @var int */ public $affected_rows; // number of affected rows
+                       /** @var string */ public $info; // see https://php.net/mysql_info
+                       /** @var int */ public $errno; // last error code
+                       /** @var string */ public $error; // last error message
+
+                       /** @var \mysqli */ private $link;
+                       /** @var Result */ private $result;
 
                        /** Connect to server
                        * @param string
@@ -132,7 +132,7 @@ if (!defined('Adminer\DRIVER')) {
                        /** Send query
                        * @param string
                        * @param bool
-                       * @return mixed bool or Result
+                       * @return Result|bool
                        */
                        function query($query, $unbuffered = false) {
                                $result = @($unbuffered ? mysql_unbuffered_query($query, $this->link) : mysql_query($query, $this->link)); // @ - mute mysql.trace_mode
@@ -152,7 +152,7 @@ if (!defined('Adminer\DRIVER')) {
 
                        /** Send query with more resultsets
                        * @param string
-                       * @return bool
+                       * @return Result|bool
                        */
                        function multi_query($query) {
                                return $this->result = $this->query($query);
@@ -185,8 +185,9 @@ if (!defined('Adminer\DRIVER')) {
                }
 
                class Result {
-                       public $num_rows; ///< @var int number of rows in the result
-                       private $result, $offset = 0;
+                       /** @var int */ public $num_rows; // number of rows in the result
+                       /** @var resource */ private $result;
+                       /** @var int */ private $offset = 0;
 
                        /** Constructor
                        * @param resource
@@ -286,13 +287,13 @@ if (!defined('Adminer\DRIVER')) {
 
 
        class Driver extends SqlDriver {
-               static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL");
-               static $jush = "sql"; ///< @var string JUSH identifier
+               /** @var list<string> */ static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL");
+               /** @var string */ static $jush = "sql"; // JUSH identifier
 
-               public $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
-               public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
-               public $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
-               public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
+               /** @var list<string> */ public $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
+               /** @var list<string> */ public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
+               /** @var list<string> */ public $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
+               /** @var list<string> */ public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
 
                function __construct($connection) {
                        parent::__construct($connection);
index 869533e7fb722e6a891f8ddaae5de21cbd364e45..e91d8b229d01500c7725f95902fcfb6370c3c5ee 100644 (file)
@@ -4,8 +4,8 @@ namespace Adminer;
 // any method change in this file should be transferred to editor/include/adminer.inc.php and plugins.inc.php
 
 class Adminer {
-       public $operators; ///< @var list<string> operators used in select, null for all operators
-       public $error = ''; ///< @var string @visibility protected(set) string HTML
+       /** @var list<string> */ public $operators; // operators used in select, null for all operators
+       /** @var string @visibility protected(set) */ public $error = ''; // HTML
 
        /** Name in title and navigation
        * @return string HTML code
@@ -264,6 +264,7 @@ class Adminer {
        }
 
        /** Print HTML code just before the Execute button in SQL command
+       * @return void
        */
        function sqlPrintAfter() {
        }
@@ -689,7 +690,7 @@ class Adminer {
 
        /** Print before edit form
        * @param string
-       * @param array[]
+       * @param Field[]
        * @param mixed
        * @param bool
        * @return void
@@ -1052,6 +1053,7 @@ class Adminer {
 
        /** Set up syntax highlight for code and <textarea>
        * @param TableStatus[] result of table_status('', true)
+       * @return void
        */
        function syntaxHighlighting($tables) {
                global $connection;
index 9a0ff67dfcfb977ee73211e5f480ee7036ee03f7..43407d131f4419f0d2696b820b2afe59b9fa387a 100644 (file)
@@ -17,6 +17,7 @@ if ($_COOKIE["adminer_permanent"]) {
        }
 }
 
+/** @return void */
 function add_invalid_login() {
        global $adminer;
        $base = get_temp_dir() . "/adminer.invalid";
@@ -50,6 +51,7 @@ function add_invalid_login() {
        file_write_unlock($fp, serialize($invalids));
 }
 
+/** @return void */
 function check_invalid_login() {
        global $adminer;
        $invalids = array();
@@ -113,6 +115,7 @@ if ($auth) {
        }
 }
 
+/** @return void */
 function unset_permanent() {
        global $permanent;
        foreach ($permanent as $key => $val) {
index 04db84b7c5ec9e29da7a3af75f94c8817b4f2898..990a2c4f3e496a77eb0fff4aff62d5a15679e488 100644 (file)
@@ -3,6 +3,7 @@ namespace Adminer;
 
 // coverage is used in tests and removed in compilation
 if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.coverage")) {
+       /** @return void */
        function save_coverage() {
                $coverage_filename = sys_get_temp_dir() . "/adminer.coverage";
                $coverage = unserialize(file_get_contents($coverage_filename));
index fc3397befc9a97794ec6c0828357d473f271853c..dfc33352abcc00ef28ca18e7642f3061dba4da33 100644 (file)
@@ -23,20 +23,20 @@ function get_driver($id) {
 }
 
 abstract class SqlDriver {
-       static $possibleDrivers = array(); ///< @var list<string>
-       static $jush; ///< @var string JUSH identifier
+       /** @var list<string> */ static $possibleDrivers = array();
+       /** @var string */ static $jush; // JUSH identifier
 
-       protected $conn; ///< @var Db
-       protected $types = array(); ///< @var int[][] [$group => [$type => $maximum_unsigned_length, ...], ...]
-       public $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
-       public $unsigned = array(); ///< @var list<string> number variants
-       public $operators = array(); ///< @var list<string> operators used in select
-       public $functions = array(); ///< @var list<string> functions used in select
-       public $grouping = array(); ///< @var list<string> grouping functions used in select
-       public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()
-       public $inout = "IN|OUT|INOUT"; ///< @var string used in routines
-       public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; ///< @var string regular expression for parsing enum lengths
-       public $generated = array(); ///< @var list<string> allowed types of generated columns
+       /** @var Db */ protected $conn;
+       /** @var int[][] */ protected $types = array(); // [$group => [$type => $maximum_unsigned_length, ...], ...]
+       /** @var array{0?:string[], 1?:string[]} */ public $editFunctions = array(); // of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
+       /** @var list<string> */ public $unsigned = array(); // number variants
+       /** @var list<string> */ public $operators = array(); // operators used in select
+       /** @var list<string> */ public $functions = array(); // functions used in select
+       /** @var list<string> */ public $grouping = array(); // grouping functions used in select
+       /** @var string */ public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; // used in foreign_keys()
+       /** @var string */ public $inout = "IN|OUT|INOUT"; // used in routines
+       /** @var string */ public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths
+       /** @var list<string> */ public $generated = array(); // allowed types of generated columns
 
        /** Create object for performing database operations
        * @param Db
index faacd881c5bbf5c6be7df940dfd9518a403567ca..1890290b806d30aa05e707bb0e39663b74928687 100644 (file)
@@ -67,7 +67,7 @@ function escape_string($val) {
 
 /** Get a possibly missing item from a possibly missing array
 * idx($row, $key) is better than $row[$key] ?? null because PHP will report error for undefined $row
-* @param ?array
+* @param ?mixed[]
 * @param string|int
 * @param mixed
 * @return mixed
@@ -543,8 +543,8 @@ function query_redirect($query, $location, $message, $redirect = true, $execute
 }
 
 class Queries {
-       static $queries = array();
-       static $start;
+       /** @var string[] */ static $queries = array();
+       /** @var float */ static $start;
 }
 
 /** Execute and remember query
@@ -846,6 +846,7 @@ function file_open_lock($filename) {
 /** Write and unlock a file
 * @param resource
 * @param string
+* @return void
 */
 function file_write_unlock($fp, $data) {
        rewind($fp);
@@ -856,6 +857,7 @@ function file_write_unlock($fp, $data) {
 
 /** Unlock and close a file
 * @param resource
+* @return void
 */
 function file_unlock($fp) {
        flock($fp, LOCK_UN);
@@ -863,8 +865,8 @@ function file_unlock($fp) {
 }
 
 /** Get first element of an array
-* @param array
-* @return mixed or false if not found
+* @param mixed[]
+* @return mixed if not found
 */
 function first($array) {
        // reset(f()) triggers a notice
@@ -1029,6 +1031,10 @@ function verify_token() {
 }
 
 // used in compiled version
+/**
+* @param string
+* @return string
+*/
 function lzw_decompress($binary) {
        // convert binary string to codes
        $dictionary_count = 256;
index 487190ec2bd720d675cf9759c8efd8358eb71280..dcaa345ab27c03e0a46f6b8cd1dd7b08b467bc69 100644 (file)
@@ -197,7 +197,7 @@ function pagination($page, $current) {
 }
 
 /** Print hidden fields
-* @param array
+* @param mixed[]
 * @param list<string>
 * @param string
 * @return bool
index b8f1f7bbb3758f6d6fdd06054dd858c1b45bd2c2..da2436e0c4b8b585271b8ebc6b93fcb7b0a296e4 100644 (file)
@@ -92,6 +92,7 @@ function lang($idf, $number = null) {
        return vsprintf($format, $args);
 }
 
+/** @return void */
 function switch_lang() {
        global $LANG, $langs;
        echo "<form action='' method='post'>\n<div id='lang'>";
index 98a24f2daac8542964012808658eb62dfd222ec7..6dbf6fd49ac8877703fc70b5b2edc29d36a40209 100644 (file)
@@ -2,7 +2,7 @@
 namespace Adminer;
 
 class Plugins extends Adminer {
-       public $plugins; ///< @var list<object> @visibility protected(set)
+       /** @var list<object> @visibility protected(set) */ public $plugins;
 
        /** Register plugins
        * @param ?list<object> object instances or null to autoload plugins from adminer-plugins/
@@ -42,10 +42,20 @@ class Plugins extends Adminer {
                $this->plugins = $plugins;
        }
 
+       /**
+       * @param literal-string
+       * @param mixed[]
+       * @return mixed
+       */
        private function callParent($function, $args) {
                return call_user_func_array(array('parent', $function), $args);
        }
 
+       /**
+       * @param literal-string
+       * @param mixed[]
+       * @return mixed
+       */
        private function applyPlugin($function, $params) {
                $args = array();
                foreach ($params as $key => $val) {
@@ -63,6 +73,11 @@ class Plugins extends Adminer {
                return $this->callParent($function, $args);
        }
 
+       /**
+       * @param literal-string
+       * @param mixed[]
+       * @return mixed
+       */
        private function appendPlugin($function, $args) {
                $return = $this->callParent($function, $args);
                foreach ($this->plugins as $plugin) {
index a9c87d29a9ce39fab207b35bf059a6e6a870aa60..9e634385ddf4965939313972cb19d74e1fe5c585 100644 (file)
@@ -2,18 +2,23 @@
 namespace Adminer;
 
 class TmpFile {
-       private $handler;
-       public $size; ///< @visibility protected(set)
+       /** @var resource */ private $handler;
+       /** @var int @visibility protected(set) */ public $size;
 
        function __construct() {
                $this->handler = tmpfile();
        }
 
+       /**
+       * @param string
+       * @return void
+       */
        function write($contents) {
                $this->size += strlen($contents);
                fwrite($this->handler, $contents);
        }
 
+       /** @return void */
        function send() {
                fseek($this->handler, 0);
                fpassthru($this->handler);
index 4ae13733ee2dec87f1d1faff9b0cb8ea833f53bb..90c1893802c2859f603f377dc9c3e0eec5c453e6 100644 (file)
@@ -6,6 +6,10 @@ namespace Adminer;
 * @link http://www.coolcode.cn/?action=show&id=128
 */
 
+/**
+* @param int
+* @return int
+*/
 function int32($n) {
        while ($n >= 2147483648) {
                $n -= 4294967296;
@@ -16,6 +20,11 @@ function int32($n) {
        return (int) $n;
 }
 
+/**
+* @param int[]
+* @param bool
+* @return string
+*/
 function long2str($v, $w) {
        $s = '';
        foreach ($v as $val) {
@@ -27,6 +36,11 @@ function long2str($v, $w) {
        return $s;
 }
 
+/**
+* @param string
+* @param bool
+* @return int[]
+*/
 function str2long($s, $w) {
        $v = array_values(unpack('V*', str_pad($s, 4 * ceil(strlen($s) / 4), "\0")));
        if ($w) {
@@ -35,6 +49,13 @@ function str2long($s, $w) {
        return $v;
 }
 
+/**
+* @param int
+* @param int
+* @param int
+* @param int
+* @return int
+*/
 function xxtea_mx($z, $y, $sum, $k) {
        return int32((($z >> 5 & 0x7FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k ^ $z));
 }
index 516d050be5f5ebfb0804a168e2b34853093a9f44..24f98f5eca0f34538c9f0c00eeabd529be0856cb 100755 (executable)
@@ -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;
index 89b7f93b5d42b2a0a8794cbec7c7e9a905033fbc..f6527337bff6fafeee2480f487e84b172aee0a39 100644 (file)
@@ -1,9 +1,10 @@
 parameters:
-       level: 5
+       level: 6
+       
        ignoreErrors:
                # need to fix
                - "~^Function Adminer\\\\fields_from_edit\\(\\) should return~" # Mongo and SimpleDB
-               - "~^Function Adminer\\\\explain\\(\\) should return Adminer\\\\Result~" # mysqli_result
+               - "~Adminer\\\\Result.*mysqli_result~" # mysqli_result
                - "~expects array~" # different shape of array
                
                # not real problems
@@ -20,6 +21,7 @@ parameters:
                - "~expects bool~" # truthy values
                - "~fread expects int<1, max>, 100000~" # 1e6
                - "~'strlen' given~" # used as a bool callback
+               - "~Adminer\\\\(Db|PdoDb).* type specified~" # duplicate methods
 
                # it probably doesn't like $ar[$key] instead of isset($ar[$key]) and thinks that $ar[$key] is always set
                - identifier: identical.alwaysFalse
@@ -37,9 +39,10 @@ parameters:
                - identifier: while.alwaysTrue
                - identifier: isset.offset
                - identifier: deadCode.unreachable
-
+               
        paths:
                - adminer/
+       scanFiles:
                - compile.php # compile_file()
        excludePaths:
                - adminer/designs.php
@@ -53,7 +56,7 @@ parameters:
        phpVersion:
                min: 70100
                max: 80499
-       checkMissingCallableSignature: true
+               
        typeAliases:
                TableStatus: "array{Name:string, Engine?:?string, Comment?:string, Oid?:numeric-string, Rows?:?numeric-string, Collation?:string, Auto_increment?:?numeric-string, Data_length?:numeric-string, Index_length?:numeric-string, Data_free?:numeric-string, Create_options?:string, nspname?:string}"
                Field: "array{field:?string, full_type:string, type:string, length:numeric-string, unsigned:string, default:?string, null:bool, auto_increment:bool, collation:string, privileges:int[], comment:string, primary:bool, generated:string, orig?:string, on_update:?string, on_delete?:string, inout?:string}"
@@ -61,5 +64,5 @@ parameters:
                ForeignKey: "array{db:string, ns?:string, table:string, source:list<string>, target:list<string>, on_delete:string, on_update:string}"
                Trigger: "array{Trigger?:string, Timing?:string, Event?:string, Of?:string, Type?:string, Statement?: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<RoutineField>, comment:string, returns?:array, definition:string, language?:string}"
+               Routine: "array{name?:string, fields:list<RoutineField>, comment:string, returns?:array{type:string, length:string, unsigned:string, collation:string}, definition:string, language?:string}"
                BackwardKey: "array{name:string, keys:string[][]}"