diff --git a/adminer/call.inc.php b/adminer/call.inc.php index a9df194d..90d28596 100644 --- a/adminer/call.inc.php +++ b/adminer/call.inc.php @@ -71,13 +71,13 @@ if ($in) { $field = $routine["fields"][$key]; $name = $field["field"]; echo "" . $adminer->fieldName($field); - $value = $_POST["fields"][$name]; + $value = idx($_POST["fields"], $name); if ($value != "") { if ($field["type"] == "set") { $value = implode(",", $value); } } - input($field, $value, (string) $_POST["function"][$name]); // param name can be empty + input($field, $value, idx($_POST["function"], $name, "")); // param name can be empty echo "\n"; } echo "\n"; diff --git a/adminer/foreign.inc.php b/adminer/foreign.inc.php index 3685d057..3ce59fb9 100644 --- a/adminer/foreign.inc.php +++ b/adminer/foreign.inc.php @@ -95,7 +95,7 @@ $j = 0; foreach ($row["source"] as $key => $val) { echo ""; echo "" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : ""), "label-source"); - echo "" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], "", "label-target"); + echo "" . html_select("target[" . (+$key) . "]", $target, idx($row["target"], $key), "", "label-target"); $j++; } ?> diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index d79a5002..5529b54a 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -667,7 +667,7 @@ class Adminer { global $driver; restart_session(); $history = &get_session("queries"); - if (!$history[$_GET["db"]]) { + if (!idx($history, $_GET["db"])) { $history[$_GET["db"]] = array(); } if (strlen($query) > 1e6) { diff --git a/adminer/include/auth.inc.php b/adminer/include/auth.inc.php index 5cb61621..66abb111 100644 --- a/adminer/include/auth.inc.php +++ b/adminer/include/auth.inc.php @@ -62,7 +62,7 @@ function check_invalid_login() { } } $invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array()); - $next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts + $next_attempt = (idx($invalid, 1) > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts if ($next_attempt > 0) { //! do the same with permanent login auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60))); } diff --git a/adminer/include/coverage.inc.php b/adminer/include/coverage.inc.php index e4eefdba..04db84b7 100644 --- a/adminer/include/coverage.inc.php +++ b/adminer/include/coverage.inc.php @@ -8,7 +8,7 @@ if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.cov $coverage = unserialize(file_get_contents($coverage_filename)); foreach (xdebug_get_code_coverage() as $filename => $lines) { foreach ($lines as $l => $val) { - if (!$coverage[$filename][$l] || $val > 0) { + if (!idx($coverage[$filename], $l) || $val > 0) { $coverage[$filename][$l] = $val; } } diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php index 92a2ca31..de33995e 100644 --- a/adminer/include/design.inc.php +++ b/adminer/include/design.inc.php @@ -182,7 +182,7 @@ function get_nonce() { function page_messages($error) { global $adminer; $uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]); - $messages = $_SESSION["messages"][$uri]; + $messages = idx($_SESSION["messages"], $uri); if ($messages) { echo "
" . implode("
\n
", $messages) . "
" . script("messagesPrint();"); unset($_SESSION["messages"][$uri]); diff --git a/adminer/include/editing.inc.php b/adminer/include/editing.inc.php index 9e067d87..de12030e 100644 --- a/adminer/include/editing.inc.php +++ b/adminer/include/editing.inc.php @@ -353,7 +353,7 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra foreach ($fields as $i => $field) { $i++; $orig = $field[($_POST ? "orig" : "field")]; - $display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == ""); + $display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !idx($_POST["drop_col"], $i))) && (support("drop_col") || $orig == ""); echo "\n"; echo ($type == "PROCEDURE" ? "" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . ""; if ($display) { diff --git a/adminer/include/errors.inc.php b/adminer/include/errors.inc.php index ac7c54c0..b9a88389 100644 --- a/adminer/include/errors.inc.php +++ b/adminer/include/errors.inc.php @@ -3,8 +3,7 @@ namespace Adminer; error_reporting(24575); // all but E_DEPRECATED (overriding mysqli methods without types is deprecated) set_error_handler(function ($errno, $errstr) { - // "offset on null" mutes $_GET["fields"][0] if there's no ?fields[]= (62017e3 is a wrong fix for this) // "Undefined array key" mutes $_GET["q"] if there's no ?q= // "Undefined offset" and "Undefined index" are older messages for the same thing - return !!preg_match('~^(Trying to access array offset on( value of type)? null|Undefined (array key|offset|index))~', $errstr); + return !!preg_match('~^(Undefined (array key|offset|index))~', $errstr); }, E_WARNING | E_NOTICE); // warning since PHP 8.0 diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index adec2ef9..95cdde83 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -65,6 +65,16 @@ function escape_string($val) { return substr(q($val), 1, -1); } +/** Get a possibly missing item from a possibly missing array +* @param array|null +* @param string|int +* @param mixed +* @return mixed +*/ +function idx($array, $key, $default = null) { + return ($array && array_key_exists($key, $array) ? $array[$key] : $default); +} + /** Remove non-digits from a string * @param string * @return string @@ -302,12 +312,13 @@ function where($where, $fields = array()) { foreach ((array) $where["where"] as $key => $val) { $key = bracket_escape($key, 1); // 1 - back $column = escape_key($key); - $field_type = $fields[$key]["type"]; + $field = ($fields ? $fields[$key] : array()); + $field_type = $field["type"]; $return[] = $column . (JUSH == "sql" && $field_type == "json" ? " = CAST(" . q($val) . " AS JSON)" : (JUSH == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints : (JUSH == "mssql" && strpos($field_type, "datetime") === false ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text but it does not work with datetime - : " = " . unconvert_field($fields[$key], q($val))))) + : " = " . unconvert_field($field, q($val))))) ; //! enum and set if (JUSH == "sql" && preg_match('~char|text~', $field_type) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters $return[] = "$column = " . q($val) . " COLLATE " . charset($connection) . "_bin"; diff --git a/adminer/include/html.inc.php b/adminer/include/html.inc.php index 97cf771b..c85b1f93 100644 --- a/adminer/include/html.inc.php +++ b/adminer/include/html.inc.php @@ -352,7 +352,7 @@ function process_input($field) { return null; } $idf = bracket_escape($field["field"]); - $function = $_POST["function"][$idf]; + $function = idx($_POST["function"], $idf); $value = $_POST["fields"][$idf]; if ($field["type"] == "enum" || $driver->enumLength($field)) { if ($value == -1) { @@ -453,7 +453,7 @@ function edit_form($table, $fields, $row, $update) { $autofocus = !$_POST; foreach ($fields as $name => $field) { echo "" . $adminer->fieldName($field); - $default = $_GET["set"][bracket_escape($name)]; + $default = idx($_GET["set"], bracket_escape($name)); if ($default === null) { $default = $field["default"]; if ($field["type"] == "bit" && preg_match("~^b'([01]*)'\$~", $default, $regs)) { @@ -477,7 +477,7 @@ function edit_form($table, $fields, $row, $update) { $value = $adminer->editVal($value, $field); } $function = ($_POST["save"] - ? (string) $_POST["function"][$name] + ? idx($_POST["function"], $name, "") : ($update && preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "now" : ($value === false ? null : ($value !== null ? '' : 'NULL')) diff --git a/adminer/indexes.inc.php b/adminer/indexes.inc.php index 89586f0d..02700a5f 100644 --- a/adminer/indexes.inc.php +++ b/adminer/indexes.inc.php @@ -33,8 +33,8 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) { ksort($index["columns"]); foreach ($index["columns"] as $key => $column) { if ($column != "") { - $length = $index["lengths"][$key]; - $desc = $index["descs"][$key]; + $length = idx($index["lengths"], $key); + $desc = idx($index["descs"], $key); $set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : ""); $columns[] = $column; $lengths[] = ($length ?: null); diff --git a/adminer/schema.inc.php b/adminer/schema.inc.php index f361f0fb..b2284d19 100644 --- a/adminer/schema.inc.php +++ b/adminer/schema.inc.php @@ -32,8 +32,8 @@ foreach (table_status('', true) as $table => $table_status) { foreach ($adminer->foreignKeys($table) as $val) { if (!$val["db"]) { $left = $base_left; - if ($table_pos[$table][1] || $table_pos[$val["table"]][1]) { - $left = min(floatval($table_pos[$table][1]), floatval($table_pos[$val["table"]][1])) - 1; + if (idx($table_pos[$table], 1) || idx($table_pos[$val["table"]], 1)) { + $left = min(idx($table_pos[$table], 1, 0), idx($table_pos[$val["table"]], 1, 0)) - 1; } else { $base_left -= .1; } @@ -71,7 +71,7 @@ foreach ($schema as $name => $table) { foreach ((array) $table["references"] as $target_name => $refs) { foreach ($refs as $left => $ref) { - $left1 = $left - $table_pos[$name][1]; + $left1 = $left - idx($table_pos[$name], 1); $i = 0; foreach ($ref[0] as $source) { echo "\n
" @@ -83,7 +83,7 @@ foreach ($schema as $name => $table) { foreach ((array) $referenced[$name] as $target_name => $refs) { foreach ($refs as $left => $columns) { - $left1 = $left - $table_pos[$name][1]; + $left1 = $left - idx($table_pos[$name], 1); $i = 0; foreach ($columns as $target) { echo "\n
" diff --git a/adminer/select.inc.php b/adminer/select.inc.php index 8ae4ca58..1cbb0683 100644 --- a/adminer/select.inc.php +++ b/adminer/select.inc.php @@ -339,7 +339,7 @@ if (!$columns && support("table")) { $rank = 1; foreach ($rows[0] as $key => $val) { if (!isset($unselected[$key])) { - $val = $_GET["columns"][key($select)]; + $val = idx($_GET["columns"], key($select)) ?: array(); $field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key]; $name = ($field ? $adminer->fieldName($field, $rank) : ($val["fun"] ? "*" : h($key))); if ($name != "") { @@ -450,7 +450,7 @@ if (!$columns && support("table")) { $val = select_value($val, $link, $field, $text_length); $id = h("val[$unique_idf][" . bracket_escape($key) . "]"); - $value = $_POST["val"][$unique_idf][bracket_escape($key)]; + $value = idx(idx($_POST["val"], $unique_idf), bracket_escape($key)); $editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key] && !$field["generated"]; $text = preg_match('~text|json|lob~', $field["type"]); echo "" . h($desc) . input_hidden("where[$i][col]", $name) . input_hidden("where[$i][op]", "=") . ":
\n"; + echo "
" . h($desc) . input_hidden("where[$i][col]", $name) . input_hidden("where[$i][op]", "=") . ":
\n"; unset($columns[$name]); } } @@ -294,7 +294,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row } if ($orders) { echo '
' . lang('Sort') . "
"; - echo ""; + echo ""; echo "
\n"; } if ($_GET["order"]) { diff --git a/plugins/drivers/elastic.php b/plugins/drivers/elastic.php index 4b9f1cc1..2369d0e8 100644 --- a/plugins/drivers/elastic.php +++ b/plugins/drivers/elastic.php @@ -274,7 +274,7 @@ if (isset($_GET["elastic"])) { function delete($table, $queryWhere, $limit = 0) { //! use $limit $ids = array(); - if (isset($_GET["where"]["_id"]) && $_GET["where"]["_id"]) { + if (idx($_GET["where"], "_id")) { $ids[] = $_GET["where"]["_id"]; } if (isset($_POST['check'])) {