From 5f7daff1e07dd90670167768a5f7223d39e0c94d Mon Sep 17 00:00:00 2001 From: Lionel Laffineur Date: Sun, 3 Dec 2023 23:04:42 +0100 Subject: [PATCH] Fixed warnings on table structure page and table data page --- adminer/drivers/mysql.inc.php | 5 ++ adminer/include/adminer.inc.php | 140 +++++++++++++++++--------------- adminer/include/design.inc.php | 2 +- adminer/include/driver.inc.php | 2 +- adminer/index.php | 2 +- adminer/select.inc.php | 87 +++++++++++--------- 6 files changed, 132 insertions(+), 106 deletions(-) diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 25d3e7f6..9d0d3c6b 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -544,6 +544,11 @@ if (!defined("DRIVER")) { $return = array(); foreach (get_rows("SHOW FULL COLUMNS FROM " . table($table)) as $row) { preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $row["Type"], $match); + for ($i = 0; $i < 5; $i++) { + if (isset($match[$i]) === false) { + $match[$i] = null; + } + } $return[$row["Field"]] = array( "field" => $row["Field"], "full_type" => $row["Type"], diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index 8781496c..76e175c5 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -398,21 +398,23 @@ class Adminer { } } $change_next = "this.parentNode.firstChild.onchange();"; - foreach (array_merge((array) $_GET["where"], array(array())) as $i => $val) { - if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) { - echo "
" . select_input( - " name='where[$i][col]'", - $columns, - $val["col"], - ($val ? "selectFieldChange" : "selectAddRow"), - "(" . lang('anywhere') . ")" - ); - echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next); - echo ""; - echo script("mixin(qsl('input'), {oninput: function () { $change_next }, onkeydown: selectSearchKeydown, onsearch: selectSearchSearch});", ""); - echo ""; - echo script('qsl(".icon").onclick = selectRemoveRow;', ""); - echo "
\n"; + if (isset($_GET["where"])) { + foreach (array_merge((array) $_GET["where"], array(array())) as $i => $val) { + if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) { + echo "
" . select_input( + " name='where[$i][col]'", + $columns, + $val["col"], + ($val ? "selectFieldChange" : "selectAddRow"), + "(" . lang('anywhere') . ")" + ); + echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next); + echo ""; + echo script("mixin(qsl('input'), {oninput: function () { $change_next }, onkeydown: selectSearchKeydown, onsearch: selectSearchSearch});", ""); + echo ""; + echo script('qsl(".icon").onclick = selectRemoveRow;', ""); + echo "
\n"; + } } } echo "\n"; @@ -427,14 +429,16 @@ class Adminer { function selectOrderPrint($order, $columns, $indexes) { print_fieldset("sort", lang('Sort'), $order); $i = 0; - foreach ((array) $_GET["order"] as $key => $val) { - if ($val != "") { - echo "
" . select_input(" name='order[$i]'", $columns, $val, "selectFieldChange"); - echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')); - echo " "; - echo script('qsl(".icon").onclick = selectRemoveRow;', ""); - echo "
\n"; - $i++; + if (isset($_GET["order"])) { + foreach ((array) $_GET["order"] as $key => $val) { + if ($val != "") { + echo "
" . select_input(" name='order[$i]'", $columns, $val, "selectFieldChange"); + echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')); + echo " "; + echo script('qsl(".icon").onclick = selectRemoveRow;', ""); + echo "
\n"; + $i++; + } } } echo "
" . select_input(" name='order[$i]'", $columns, "", "selectAddRow"); @@ -526,11 +530,13 @@ class Adminer { global $functions, $grouping; $select = array(); // select expressions, empty for * $group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used - foreach ((array) $_GET["columns"] as $key => $val) { - if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) { - $select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*")); - if (!in_array($val["fun"], $grouping)) { - $group[] = $select[$key]; + if (isset($_GET["columns"])) { + foreach ((array) $_GET["columns"] as $key => $val) { + if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) { + $select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*")); + if (!in_array($val["fun"], $grouping)) { + $group[] = $select[$key]; + } } } } @@ -550,39 +556,41 @@ class Adminer { $return[] = "MATCH (" . implode(", ", array_map('idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")"; } } - foreach ((array) $_GET["where"] as $key => $val) { - if ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators)) { - $prefix = ""; - $cond = " $val[op]"; - if (preg_match('~IN$~', $val["op"])) { - $in = process_length($val["val"]); - $cond .= " " . ($in != "" ? $in : "(NULL)"); - } elseif ($val["op"] == "SQL") { - $cond = " $val[val]"; // SQL injection - } elseif ($val["op"] == "LIKE %%") { - $cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); - } elseif ($val["op"] == "ILIKE %%") { - $cond = " ILIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); - } elseif ($val["op"] == "FIND_IN_SET") { - $prefix = "$val[op](" . q($val["val"]) . ", "; - $cond = ")"; - } elseif (!preg_match('~NULL$~', $val["op"])) { - $cond .= " " . $this->processInput($fields[$val["col"]], $val["val"]); - } - if ($val["col"] != "") { - $return[] = $prefix . $driver->convertSearch(idf_escape($val["col"]), $val, $fields[$val["col"]]) . $cond; - } else { - // find anywhere - $cols = array(); - foreach ($fields as $name => $field) { - if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"])) - && (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"])) - && (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"])) - ) { - $cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond; - } + if (isset($_GET["where"])) { + foreach ((array) $_GET["where"] as $key => $val) { + if ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators)) { + $prefix = ""; + $cond = " $val[op]"; + if (preg_match('~IN$~', $val["op"])) { + $in = process_length($val["val"]); + $cond .= " " . ($in != "" ? $in : "(NULL)"); + } elseif ($val["op"] == "SQL") { + $cond = " $val[val]"; // SQL injection + } elseif ($val["op"] == "LIKE %%") { + $cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); + } elseif ($val["op"] == "ILIKE %%") { + $cond = " ILIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); + } elseif ($val["op"] == "FIND_IN_SET") { + $prefix = "$val[op](" . q($val["val"]) . ", "; + $cond = ")"; + } elseif (!preg_match('~NULL$~', $val["op"])) { + $cond .= " " . $this->processInput($fields[$val["col"]], $val["val"]); + } + if ($val["col"] != "") { + $return[] = $prefix . $driver->convertSearch(idf_escape($val["col"]), $val, $fields[$val["col"]]) . $cond; + } else { + // find anywhere + $cols = array(); + foreach ($fields as $name => $field) { + if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"])) + && (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"])) + && (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"])) + ) { + $cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond; + } + } + $return[] = ($cols ? "(" . implode(" OR ", $cols) . ")" : "1 = 0"); } - $return[] = ($cols ? "(" . implode(" OR ", $cols) . ")" : "1 = 0"); } } } @@ -596,11 +604,13 @@ class Adminer { */ function selectOrderProcess($fields, $indexes) { $return = array(); - foreach ((array) $_GET["order"] as $key => $val) { - if ($val != "") { - $return[] = (preg_match('~^((COUNT\(DISTINCT |[A-Z0-9_]+\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\)|COUNT\(\*\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses [] - . (isset($_GET["desc"][$key]) ? " DESC" : "") - ; + if (isset($_GET["order"])) { + foreach ((array) $_GET["order"] as $key => $val) { + if ($val != "") { + $return[] = (preg_match('~^((COUNT\(DISTINCT |[A-Z0-9_]+\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\)|COUNT\(\*\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses [] + . (isset($_GET["desc"][$key]) ? " DESC" : "") + ; + } } } return $return; diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php index 7f41829b..70d79e5a 100644 --- a/adminer/include/design.inc.php +++ b/adminer/include/design.inc.php @@ -80,7 +80,7 @@ var thousandsSeparator = ''; echo '' . h(DB) . ' » '; } if (is_array($breadcrumb)) { - if ($_GET["ns"] != "") { + if (isset($_GET["ns"]) && $_GET["ns"] != "") { echo '' . h($_GET["ns"]) . ' » '; } foreach ($breadcrumb as $key => $val) { diff --git a/adminer/include/driver.inc.php b/adminer/include/driver.inc.php index 6ed385ed..d82a6aed 100644 --- a/adminer/include/driver.inc.php +++ b/adminer/include/driver.inc.php @@ -47,7 +47,7 @@ function get_driver($id) { $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page); if (!$query) { $query = "SELECT" . limit( - ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table), + (isset($_GET["page"]) && $_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table), ($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""), ($limit != "" ? +$limit : null), ($page ? $limit * $page : 0), diff --git a/adminer/index.php b/adminer/index.php index 38ef5538..3a9b6f9f 100644 --- a/adminer/index.php +++ b/adminer/index.php @@ -14,7 +14,7 @@ include "./include/tmpfile.inc.php"; $enum_length = "'(?:''|[^'\\\\]|\\\\.)*'"; $inout = "IN|OUT|INOUT"; -if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) { +if (isset($_GET["select"]) && ((isset($_POST["edit"]) && $_POST["edit"]) || (isset($_POST["clone"]) && $_POST["clone"])) && (isset($_POST["save"]) || !$_POST["save"])) { $_GET["edit"] = $_GET["select"]; } if (isset($_GET["callf"])) { diff --git a/adminer/select.inc.php b/adminer/select.inc.php index 956f948f..237ed709 100644 --- a/adminer/select.inc.php +++ b/adminer/select.inc.php @@ -4,8 +4,12 @@ $table_status = table_status1($TABLE); $indexes = indexes($TABLE); $fields = fields($TABLE); $foreign_keys = column_foreign_keys($TABLE); -$oid = $table_status["Oid"]; -parse_str($_COOKIE["adminer_import"], $adminer_import); +$oid = (isset($table_status["Oid"]) ? $table_status["Oid"] : null); +if (isset($_COOKIE["adminer_import"])) { + parse_str($_COOKIE["adminer_import"], $adminer_import); +} else { + $adminer_import = []; +} $rights = array(); // privilege => 0 $columns = array(); // selectable columns @@ -22,12 +26,12 @@ foreach ($fields as $key => $field) { } list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes); -$is_group = count($group) < count($select) || strstr($select[0], "DISTINCT"); +$is_group = count($group) < count($select) || (isset($select[0]) && strstr($select[0], "DISTINCT")); $where = $adminer->selectSearchProcess($fields, $indexes); $order = $adminer->selectOrderProcess($fields, $indexes); $limit = $adminer->selectLimitProcess(); -if ($_GET["val"] && is_ajax()) { +if (isset($_GET["val"]) && $_GET["val"] && is_ajax()) { header("Content-Type: text/plain; charset=utf-8"); foreach ($_GET["val"] as $unique_idf => $row) { $as = convert_field($fields[key($row)]); @@ -225,11 +229,13 @@ if (is_ajax()) { $set = null; if (isset($rights["insert"]) || !support("table")) { $set = ""; - foreach ((array) $_GET["where"] as $val) { - if ($foreign_keys[$val["col"]] && count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "=" - || (!$val["op"] && !preg_match('~[_%]~', $val["val"])) // LIKE in Editor - )) { - $set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]); + if (isset($_GET["where"])) { + foreach ((array) $_GET["where"] as $val) { + if ($foreign_keys[$val["col"]] && count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "=" + || (!$val["op"] && !preg_match('~[_%]~', $val["val"])) // LIKE in Editor + )) { + $set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]); + } } } } @@ -253,7 +259,7 @@ if (!$columns && support("table")) { $adminer->selectActionPrint($indexes); echo "\n"; - $page = $_GET["page"]; + $page = (isset($_GET["page"]) ? $_GET["page"] : null); if ($page == "last") { $found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group)); $page = floor(max(0, $found_rows - 1) / $limit); @@ -301,7 +307,7 @@ if (!$columns && support("table")) { } // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest) - if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql") { + if (isset($_GET["page"]) && $_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql") { $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode } @@ -316,7 +322,7 @@ if (!$columns && support("table")) { echo "" . (!$group && $select ? "" : "" . script("qs('#all-page').onclick = partial(formCheck, /check/);", "") - . " " . lang('Modify') . ""); + . " " . lang('Modify') . ""); $names = array(); $functions = array(); reset($select); @@ -333,7 +339,7 @@ if (!$columns && support("table")) { $href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key); $desc = "&desc%5B0%5D=1"; echo "" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", ""); - echo ''; // $order[0] == $key - COUNT(*) + echo ''; // $order[0] == $key - COUNT(*) echo apply_sql_function($val["fun"] ?? null, $name) . ""; //! columns looking like functions echo "