ARI Adminer – WordPress Database Manager - Version 1.11.2

Version Description

Download this release

Release Info

Developer arisoft
Plugin Icon 128x128 ARI Adminer – WordPress Database Manager
Version 1.11.2
Comparing to
See all releases

Code changes from version 1.1.11 to 1.11.2

Files changed (52) hide show
  1. adminer/adminer/adminer/database.inc.php +1 -1
  2. adminer/adminer/adminer/db.inc.php +7 -7
  3. adminer/adminer/adminer/drivers/elastic.inc.php +12 -7
  4. adminer/adminer/adminer/drivers/mongo.inc.php +40 -53
  5. adminer/adminer/adminer/drivers/mssql.inc.php +10 -8
  6. adminer/adminer/adminer/drivers/mysql.inc.php +33 -12
  7. adminer/adminer/adminer/drivers/pgsql.inc.php +34 -19
  8. adminer/adminer/adminer/drivers/simpledb.inc.php +11 -0
  9. adminer/adminer/adminer/drivers/sqlite.inc.php +10 -5
  10. adminer/adminer/adminer/event.inc.php +1 -1
  11. adminer/adminer/adminer/file.inc.php +1 -9
  12. adminer/adminer/adminer/include/adminer.inc.php +35 -25
  13. adminer/adminer/adminer/include/auth.inc.php +11 -7
  14. adminer/adminer/adminer/include/bootstrap.inc.php +4 -9
  15. adminer/adminer/adminer/include/connect.inc.php +2 -2
  16. adminer/adminer/adminer/include/driver.inc.php +12 -1
  17. adminer/adminer/adminer/include/editing.inc.php +8 -10
  18. adminer/adminer/adminer/include/functions.inc.php +19 -30
  19. adminer/adminer/adminer/include/pdo.inc.php +3 -0
  20. adminer/adminer/adminer/include/version.inc.php +1 -1
  21. adminer/adminer/adminer/indexes.inc.php +1 -1
  22. adminer/adminer/adminer/lang/cs.inc.php +5 -2
  23. adminer/adminer/adminer/lang/he.inc.php +0 -1
  24. adminer/adminer/adminer/lang/ms.inc.php +0 -1
  25. adminer/adminer/adminer/lang/pl.inc.php +0 -1
  26. adminer/adminer/adminer/lang/ru.inc.php +0 -1
  27. adminer/adminer/adminer/lang/tr.inc.php +0 -1
  28. adminer/adminer/adminer/lang/xx.inc.php +4 -1
  29. adminer/adminer/adminer/privileges.inc.php +1 -1
  30. adminer/adminer/adminer/processlist.inc.php +2 -2
  31. adminer/adminer/adminer/script.inc.php +2 -2
  32. adminer/adminer/adminer/select.inc.php +4 -4
  33. adminer/adminer/adminer/sql.inc.php +5 -4
  34. adminer/adminer/adminer/sqlite.php +5 -2
  35. adminer/adminer/adminer/static/editing.js +21 -3
  36. adminer/adminer/adminer/static/functions.js +7 -12
  37. adminer/adminer/adminer/table.inc.php +3 -3
  38. adminer/adminer/adminer/user.inc.php +4 -4
  39. adminer/adminer/adminer/variables.inc.php +1 -1
  40. adminer/adminer/editor/include/adminer.inc.php +14 -13
  41. adminer/adminer/editor/include/editing.inc.php +1 -1
  42. adminer/adminer/plugins/dump-alter.php +1 -1
  43. adminer/adminer/plugins/file-upload.php +1 -1
  44. adminer/adminer/plugins/plugin.php +5 -0
  45. adminer/adminer/plugins/tables-filter.php +10 -17
  46. ari-adminer.php +1 -1
  47. assets/themes/bradezone/adminer.css +1 -1
  48. assets/themes/nette/adminer.css +1 -1
  49. assets/themes/nicu/adminer.css +1 -1
  50. assets/themes/pilot/adminer.css +10 -5
  51. includes/defines.php +1 -1
  52. readme.txt +8 -2
adminer/adminer/adminer/database.inc.php CHANGED
@@ -47,7 +47,7 @@ if ($_POST) {
47
} elseif ($jush == "sql") {
48
// propose database name with limited privileges
49
foreach (get_vals("SHOW GRANTS") as $grant) {
50
- if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\\.\\*)?~', $grant, $match) && $match[1]) {
51
$name = stripcslashes(idf_unescape("`$match[2]`"));
52
break;
53
}
47
} elseif ($jush == "sql") {
48
// propose database name with limited privileges
49
foreach (get_vals("SHOW GRANTS") as $grant) {
50
+ if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) {
51
$name = stripcslashes(idf_unescape("`$match[2]`"));
52
break;
53
}
adminer/adminer/adminer/db.inc.php CHANGED
@@ -104,18 +104,18 @@ if ($adminer->homepage()) {
104
echo ($link ? "<td align='right'>" . (support("table") || $key == "Rows" || (support("indexes") && $key != "Data_length")
105
? "<a href='" . h(ME . "$link[0]=") . urlencode($name) . "'$id title='$link[1]'>?</a>"
106
: "<span$id>?</span>"
107
- ) : "<td id='$key-" . h($name) . "'>&nbsp;");
108
}
109
$tables++;
110
}
111
- echo (support("comment") ? "<td id='Comment-" . h($name) . "'>&nbsp;" : "");
112
}
113
114
- echo "<tr><td>&nbsp;<th>" . lang('%d in total', count($tables_list));
115
- echo "<td>" . nbsp($jush == "sql" ? $connection->result("SELECT @@storage_engine") : "");
116
- echo "<td>" . nbsp(db_collation(DB, collations()));
117
foreach (array("Data_length", "Index_length", "Data_free") as $key) {
118
- echo "<td align='right' id='sum-$key'>&nbsp;";
119
}
120
121
echo "</table>\n";
@@ -159,7 +159,7 @@ if ($adminer->homepage()) {
159
$routines = routines();
160
if ($routines) {
161
echo "<table cellspacing='0'>\n";
162
- echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td>&nbsp;</thead>\n";
163
odd('');
164
foreach ($routines as $row) {
165
$name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first
104
echo ($link ? "<td align='right'>" . (support("table") || $key == "Rows" || (support("indexes") && $key != "Data_length")
105
? "<a href='" . h(ME . "$link[0]=") . urlencode($name) . "'$id title='$link[1]'>?</a>"
106
: "<span$id>?</span>"
107
+ ) : "<td id='$key-" . h($name) . "'>");
108
}
109
$tables++;
110
}
111
+ echo (support("comment") ? "<td id='Comment-" . h($name) . "'>" : "");
112
}
113
114
+ echo "<tr><td><th>" . lang('%d in total', count($tables_list));
115
+ echo "<td>" . h($jush == "sql" ? $connection->result("SELECT @@storage_engine") : "");
116
+ echo "<td>" . h(db_collation(DB, collations()));
117
foreach (array("Data_length", "Index_length", "Data_free") as $key) {
118
+ echo "<td align='right' id='sum-$key'>";
119
}
120
121
echo "</table>\n";
159
$routines = routines();
160
if ($routines) {
161
echo "<table cellspacing='0'>\n";
162
+ echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td></thead>\n";
163
odd('');
164
foreach ($routines as $row) {
165
$name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first
adminer/adminer/adminer/drivers/elastic.inc.php CHANGED
@@ -2,10 +2,10 @@
2
$drivers["elastic"] = "Elasticsearch (beta)";
3
4
if (isset($_GET["elastic"])) {
5
- $possible_drivers = array("json");
6
define("DRIVER", "elastic");
7
8
- if (function_exists('json_decode')) {
9
class Min_DB {
10
var $extension = "JSON", $server_info, $errno, $error, $_url;
11
@@ -129,7 +129,7 @@ if (isset($_GET["elastic"])) {
129
}
130
}
131
foreach ($where as $val) {
132
- list($col,$op,$val) = explode(" ",$val,3);
133
if ($col == "_id") {
134
$data["query"]["ids"]["values"][] = $val;
135
}
@@ -177,7 +177,8 @@ if (isset($_GET["elastic"])) {
177
return new Min_Result($return);
178
}
179
180
- function update($type, $record, $queryWhere) {
181
$parts = preg_split('~ *= *~', $queryWhere);
182
if (count($parts) == 2) {
183
$id = trim($parts[1]);
@@ -195,7 +196,8 @@ if (isset($_GET["elastic"])) {
195
return $response['created'];
196
}
197
198
- function delete($type, $queryWhere) {
199
$ids = array();
200
if (is_array($_GET["where"]) && $_GET["where"]["_id"]) {
201
$ids[] = $_GET["where"]["_id"];
@@ -225,8 +227,11 @@ if (isset($_GET["elastic"])) {
225
function connect() {
226
global $adminer;
227
$connection = new Min_DB;
228
- $credentials = $adminer->credentials();
229
- if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
230
return $connection;
231
}
232
return $connection->error;
2
$drivers["elastic"] = "Elasticsearch (beta)";
3
4
if (isset($_GET["elastic"])) {
5
+ $possible_drivers = array("json + allow_url_fopen");
6
define("DRIVER", "elastic");
7
8
+ if (function_exists('json_decode') && ini_bool('allow_url_fopen')) {
9
class Min_DB {
10
var $extension = "JSON", $server_info, $errno, $error, $_url;
11
129
}
130
}
131
foreach ($where as $val) {
132
+ list($col, $op, $val) = explode(" ", $val, 3);
133
if ($col == "_id") {
134
$data["query"]["ids"]["values"][] = $val;
135
}
177
return new Min_Result($return);
178
}
179
180
+ function update($type, $record, $queryWhere, $limit = 0, $separator = "\n") {
181
+ //! use $limit
182
$parts = preg_split('~ *= *~', $queryWhere);
183
if (count($parts) == 2) {
184
$id = trim($parts[1]);
196
return $response['created'];
197
}
198
199
+ function delete($type, $queryWhere, $limit = 0) {
200
+ //! use $limit
201
$ids = array();
202
if (is_array($_GET["where"]) && $_GET["where"]["_id"]) {
203
$ids[] = $_GET["where"]["_id"];
227
function connect() {
228
global $adminer;
229
$connection = new Min_DB;
230
+ list($server, $username, $password) = $adminer->credentials();
231
+ if ($password != "" && $connection->connect($server, $username, "")) {
232
+ return lang('Database does not support password.');
233
+ }
234
+ if ($connection->connect($server, $username, $password)) {
235
return $connection;
236
}
237
return $connection->error;
adminer/adminer/adminer/drivers/mongo.inc.php CHANGED
@@ -7,26 +7,10 @@ if (isset($_GET["mongo"])) {
7
8
if (class_exists('MongoDB')) {
9
class Min_DB {
10
- var $extension = "Mongo", $error, $last_id, $_link, $_db;
11
-
12
- function connect($server, $username, $password) {
13
- global $adminer;
14
- $db = $adminer->database();
15
- $options = array();
16
- if ($username != "") {
17
- $options["username"] = $username;
18
- $options["password"] = $password;
19
- }
20
- if ($db != "") {
21
- $options["db"] = $db;
22
- }
23
- try {
24
- $this->_link = @new MongoClient("mongodb://$server", $options);
25
- return true;
26
- } catch (Exception $ex) {
27
- $this->error = $ex->getMessage();
28
- return false;
29
- }
30
}
31
32
function query($query) {
@@ -214,30 +198,14 @@ if (isset($_GET["mongo"])) {
214
215
} elseif (class_exists('MongoDB\Driver\Manager')) {
216
class Min_DB {
217
- var $extension = "MongoDB", $error, $last_id;
218
/** @var MongoDB\Driver\Manager */
219
var $_link;
220
var $_db, $_db_name;
221
222
- function connect($server, $username, $password) {
223
- global $adminer;
224
- $db = $adminer->database();
225
- $options = array();
226
- if ($username != "") {
227
- $options["username"] = $username;
228
- $options["password"] = $password;
229
- }
230
- if ($db != "") {
231
- $options["db"] = $db;
232
- }
233
- try {
234
- $class = 'MongoDB\Driver\Manager';
235
- $this->_link = new $class("mongodb://$server", $options);
236
- return true;
237
- } catch (Exception $ex) {
238
- $this->error = $ex->getMessage();
239
- return false;
240
- }
241
}
242
243
function query($query) {
@@ -245,13 +213,8 @@ if (isset($_GET["mongo"])) {
245
}
246
247
function select_db($database) {
248
- try {
249
- $this->_db_name = $database;
250
- return true;
251
- } catch (Exception $ex) {
252
- $this->error = $ex->getMessage();
253
- return false;
254
- }
255
}
256
257
function quote($string) {
@@ -405,7 +368,7 @@ if (isset($_GET["mongo"])) {
405
}
406
407
function get_databases($flush) {
408
- /** @var $connection Min_DB */
409
global $connection;
410
$return = array();
411
$class = 'MongoDB\Driver\Command';
@@ -516,7 +479,7 @@ if (isset($_GET["mongo"])) {
516
}
517
518
function where_to_query($whereAnd = array(), $whereOr = array()) {
519
- global $operators;
520
$data = array();
521
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
522
if (is_array($where)) {
@@ -528,7 +491,7 @@ if (isset($_GET["mongo"])) {
528
$class = 'MongoDB\BSON\ObjectID';
529
$val = new $class($val);
530
}
531
- if (!in_array($op, $operators)) {
532
continue;
533
}
534
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
@@ -618,6 +581,10 @@ if (isset($_GET["mongo"])) {
618
return $return;
619
}
620
621
function last_id() {
622
global $connection;
623
return $connection->last_id;
@@ -641,11 +608,31 @@ if (isset($_GET["mongo"])) {
641
function connect() {
642
global $adminer;
643
$connection = new Min_DB;
644
- $credentials = $adminer->credentials();
645
- if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
646
return $connection;
647
}
648
- return $connection->error;
649
}
650
651
function alter_indexes($table, $alter) {
7
8
if (class_exists('MongoDB')) {
9
class Min_DB {
10
+ var $extension = "Mongo", $server_info = MongoClient::VERSION, $error, $last_id, $_link, $_db;
11
+
12
+ function connect($uri, $options) {
13
+ return @new MongoClient($uri, $options);
14
}
15
16
function query($query) {
198
199
} elseif (class_exists('MongoDB\Driver\Manager')) {
200
class Min_DB {
201
+ var $extension = "MongoDB", $server_info = MONGODB_VERSION, $error, $last_id;
202
/** @var MongoDB\Driver\Manager */
203
var $_link;
204
var $_db, $_db_name;
205
206
+ function connect($uri, $options) {
207
+ $class = 'MongoDB\Driver\Manager';
208
+ return new $class($uri, $options);
209
}
210
211
function query($query) {
213
}
214
215
function select_db($database) {
216
+ $this->_db_name = $database;
217
+ return true;
218
}
219
220
function quote($string) {
368
}
369
370
function get_databases($flush) {
371
+ /** @var Min_DB */
372
global $connection;
373
$return = array();
374
$class = 'MongoDB\Driver\Command';
479
}
480
481
function where_to_query($whereAnd = array(), $whereOr = array()) {
482
+ global $adminer;
483
$data = array();
484
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
485
if (is_array($where)) {
491
$class = 'MongoDB\BSON\ObjectID';
492
$val = new $class($val);
493
}
494
+ if (!in_array($op, $adminer->operators)) {
495
continue;
496
}
497
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
581
return $return;
582
}
583
584
+ function create_database($db, $collation) {
585
+ return true;
586
+ }
587
+
588
function last_id() {
589
global $connection;
590
return $connection->last_id;
608
function connect() {
609
global $adminer;
610
$connection = new Min_DB;
611
+ list($server, $username, $password) = $adminer->credentials();
612
+ $options = array();
613
+ if ($username . $password != "") {
614
+ $options["username"] = $username;
615
+ $options["password"] = $password;
616
+ }
617
+ $db = $adminer->database();
618
+ if ($db != "") {
619
+ $options["db"] = $db;
620
+ }
621
+ try {
622
+ $connection->_link = $connection->connect("mongodb://$server", $options);
623
+ if ($password != "") {
624
+ $options["password"] = "";
625
+ try {
626
+ $connection->connect("mongodb://$server", $options);
627
+ return lang('Database does not support password.');
628
+ } catch (Exception $ex) {
629
+ // this is what we want
630
+ }
631
+ }
632
return $connection;
633
+ } catch (Exception $ex) {
634
+ return $ex->getMessage();
635
}
636
}
637
638
function alter_indexes($table, $alter) {
adminer/adminer/adminer/drivers/mssql.inc.php CHANGED
@@ -24,7 +24,7 @@ if (isset($_GET["mssql"])) {
24
}
25
26
function connect($server, $username, $password) {
27
- $this->_link = @sqlsrv_connect($server, array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8"));
28
if ($this->_link) {
29
$info = sqlsrv_server_info($this->_link);
30
$this->server_info = $info['SQLServerVersion'];
@@ -147,8 +147,10 @@ if (isset($_GET["mssql"])) {
147
$this->_link = @mssql_connect($server, $username, $password);
148
if ($this->_link) {
149
$result = $this->query("SELECT SERVERPROPERTY('ProductLevel'), SERVERPROPERTY('Edition')");
150
- $row = $result->fetch_row();
151
- $this->server_info = $this->result("sp_server_info 2", 2) . " [$row[0]] $row[1]";
152
} else {
153
$this->error = mssql_get_last_message();
154
}
@@ -239,7 +241,7 @@ if (isset($_GET["mssql"])) {
239
var $extension = "PDO_DBLIB";
240
241
function connect($server, $username, $password) {
242
- $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\\d)~', ';port=\\1', $server)), $username, $password);
243
return true;
244
}
245
@@ -406,7 +408,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
406
407
function view($name) {
408
global $connection;
409
- return array("select" => preg_replace('~^(?:[^[]|\\[[^]]*])*\\s+AS\\s+~isU', '', $connection->result("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name))));
410
}
411
412
function collations() {
@@ -423,7 +425,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
423
424
function error() {
425
global $connection;
426
- return nl_br(h(preg_replace('~^(\\[[^]]*])+~m', '', $connection->error)));
427
}
428
429
function create_database($db, $collation) {
@@ -454,7 +456,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
454
if (!$val) {
455
$alter["DROP"][] = " COLUMN $column";
456
} else {
457
- $val[1] = preg_replace("~( COLLATE )'(\\w+)'~", "\\1\\2", $val[1]);
458
if ($field[0] == "") {
459
$alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()")
460
} else {
@@ -561,7 +563,7 @@ WHERE s.xtype = 'TR' AND s.name = " . q($name)
561
); // triggers are not schema-scoped
562
$return = reset($rows);
563
if ($return) {
564
- $return["Statement"] = preg_replace('~^.+\\s+AS\\s+~isU', '', $return["text"]); //! identifiers, comments
565
}
566
return $return;
567
}
24
}
25
26
function connect($server, $username, $password) {
27
+ $this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8"));
28
if ($this->_link) {
29
$info = sqlsrv_server_info($this->_link);
30
$this->server_info = $info['SQLServerVersion'];
147
$this->_link = @mssql_connect($server, $username, $password);
148
if ($this->_link) {
149
$result = $this->query("SELECT SERVERPROPERTY('ProductLevel'), SERVERPROPERTY('Edition')");
150
+ if ($result) {
151
+ $row = $result->fetch_row();
152
+ $this->server_info = $this->result("sp_server_info 2", 2) . " [$row[0]] $row[1]";
153
+ }
154
} else {
155
$this->error = mssql_get_last_message();
156
}
241
var $extension = "PDO_DBLIB";
242
243
function connect($server, $username, $password) {
244
+ $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
245
return true;
246
}
247
408
409
function view($name) {
410
global $connection;
411
+ return array("select" => preg_replace('~^(?:[^[]|\[[^]]*])*\s+AS\s+~isU', '', $connection->result("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name))));
412
}
413
414
function collations() {
425
426
function error() {
427
global $connection;
428
+ return nl_br(h(preg_replace('~^(\[[^]]*])+~m', '', $connection->error)));
429
}
430
431
function create_database($db, $collation) {
456
if (!$val) {
457
$alter["DROP"][] = " COLUMN $column";
458
} else {
459
+ $val[1] = preg_replace("~( COLLATE )'(\\w+)'~", '\1\2', $val[1]);
460
if ($field[0] == "") {
461
$alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()")
462
} else {
563
); // triggers are not schema-scoped
564
$return = reset($rows);
565
if ($return) {
566
+ $return["Statement"] = preg_replace('~^.+\s+AS\s+~isU', '', $return["text"]); //! identifiers, comments
567
}
568
return $return;
569
}
adminer/adminer/adminer/drivers/mysql.inc.php CHANGED
@@ -30,6 +30,7 @@ if (!defined("DRIVER")) {
30
(!is_numeric($port) ? $port : $socket),
31
($ssl ? 64 : 0) // 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16)
32
);
33
return $return;
34
}
35
@@ -56,7 +57,7 @@ if (!defined("DRIVER")) {
56
}
57
}
58
59
- } elseif (extension_loaded("mysql") && !(ini_get("sql.safe_mode") && extension_loaded("pdo_mysql"))) {
60
class Min_DB {
61
var
62
$extension = "MySQL", ///< @var string extension name
@@ -74,6 +75,10 @@ if (!defined("DRIVER")) {
74
* @return bool
75
*/
76
function connect($server, $username, $password) {
77
$this->_link = @mysql_connect(
78
($server != "" ? $server : ini_get("mysql.default_host")),
79
("$server$username" != "" ? $username : ini_get("mysql.default_user")),
@@ -230,17 +235,17 @@ if (!defined("DRIVER")) {
230
231
function connect($server, $username, $password) {
232
global $adminer;
233
- $options = array();
234
$ssl = $adminer->connectSsl();
235
if ($ssl) {
236
- $options = array(
237
PDO::MYSQL_ATTR_SSL_KEY => $ssl['key'],
238
PDO::MYSQL_ATTR_SSL_CERT => $ssl['cert'],
239
PDO::MYSQL_ATTR_SSL_CA => $ssl['ca'],
240
);
241
}
242
$this->dsn(
243
- "mysql:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\\d)~', ';port=\\1', $server)),
244
$username,
245
$password,
246
$options
@@ -298,8 +303,18 @@ if (!defined("DRIVER")) {
298
return queries($prefix . implode(",\n", $values) . $suffix);
299
}
300
301
function convertSearch($idf, $val, $field) {
302
- return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"])
303
? "CONVERT($idf USING " . charset($this->_conn) . ")"
304
: $idf
305
);
@@ -376,7 +391,7 @@ if (!defined("DRIVER")) {
376
$return = get_session("dbs");
377
if ($return === null) {
378
$query = (min_version(5)
379
- ? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA"
380
: "SHOW DATABASES"
381
); // SHOW DATABASES can be disabled by skip_show_database
382
$return = ($flush ? slow_query($query) : get_vals($query));
@@ -484,7 +499,7 @@ if (!defined("DRIVER")) {
484
) as $row) {
485
if ($row["Engine"] == "InnoDB") {
486
// ignore internal comment, unnecessary since MySQL 5.1.21
487
- $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]);
488
}
489
if (!isset($row["Engine"])) {
490
$row["Comment"] = "";
@@ -521,7 +536,7 @@ if (!defined("DRIVER")) {
521
function fields($table) {
522
$return = array();
523
foreach (get_rows("SHOW FULL COLUMNS FROM " . table($table)) as $row) {
524
- preg_match('~^([^( ]+)(?:\\((.+)\\))?( unsigned)?( zerofill)?$~', $row["Type"], $match);
525
$return[$row["Field"]] = array(
526
"field" => $row["Field"],
527
"full_type" => $row["Type"],
@@ -591,7 +606,7 @@ if (!defined("DRIVER")) {
591
*/
592
function view($name) {
593
global $connection;
594
- return array("select" => preg_replace('~^(?:[^`]|`[^`]*`)*\\s+AS\\s+~isU', '', $connection->result("SHOW CREATE VIEW " . table($name), 1)));
595
}
596
597
/** Get sorted grouped list of collations
@@ -801,6 +816,12 @@ if (!defined("DRIVER")) {
801
) {
802
return false;
803
}
804
}
805
foreach ($views as $table) {
806
$name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table));
@@ -870,7 +891,7 @@ if (!defined("DRIVER")) {
870
"field" => $name,
871
"type" => strtolower($param[5]),
872
"length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]),
873
- "unsigned" => strtolower(preg_replace('~\\s+~', ' ', trim("$param[8] $param[7]"))),
874
"null" => 1,
875
"full_type" => $param[4],
876
"inout" => strtoupper($param[1]),
@@ -976,7 +997,7 @@ if (!defined("DRIVER")) {
976
global $connection;
977
$return = $connection->result("SHOW CREATE TABLE " . table($table), 1);
978
if (!$auto_increment) {
979
- $return = preg_replace('~ AUTO_INCREMENT=\\d+~', '', $return); //! skip comments
980
}
981
return $return;
982
}
@@ -1105,7 +1126,7 @@ if (!defined("DRIVER")) {
1105
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
1106
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
1107
array(
1108
- "char" => "md5/sha1/password/encrypt/uuid", //! JavaScript for disabling maxlength
1109
"binary" => "md5/sha1",
1110
"date|time" => "now",
1111
), array(
30
(!is_numeric($port) ? $port : $socket),
31
($ssl ? 64 : 0) // 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16)
32
);
33
+ $this->options(MYSQLI_OPT_LOCAL_INFILE, false);
34
return $return;
35
}
36
57
}
58
}
59
60
+ } elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) {
61
class Min_DB {
62
var
63
$extension = "MySQL", ///< @var string extension name
75
* @return bool
76
*/
77
function connect($server, $username, $password) {
78
+ if (ini_bool("mysql.allow_local_infile")) {
79
+ $this->error = lang('Disable %s or enable %s or %s extensions.', "'mysql.allow_local_infile'", "MySQLi", "PDO_MySQL");
80
+ return false;
81
+ }
82
$this->_link = @mysql_connect(
83
($server != "" ? $server : ini_get("mysql.default_host")),
84
("$server$username" != "" ? $username : ini_get("mysql.default_user")),
235
236
function connect($server, $username, $password) {
237
global $adminer;
238
+ $options = array(PDO::MYSQL_ATTR_LOCAL_INFILE => false);
239
$ssl = $adminer->connectSsl();
240
if ($ssl) {
241
+ $options += array(
242
PDO::MYSQL_ATTR_SSL_KEY => $ssl['key'],
243
PDO::MYSQL_ATTR_SSL_CERT => $ssl['cert'],
244
PDO::MYSQL_ATTR_SSL_CA => $ssl['ca'],
245
);
246
}
247
$this->dsn(
248
+ "mysql:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)),
249
$username,
250
$password,
251
$options
303
return queries($prefix . implode(",\n", $values) . $suffix);
304
}
305
306
+ function slowQuery($query, $timeout) {
307
+ if (min_version('5.7.8', '10.1.2')) {
308
+ if (preg_match('~MariaDB~', $this->_conn->server_info)) {
309
+ return "SET STATEMENT max_statement_time=$timeout FOR $query";
310
+ } elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) {
311
+ return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]";
312
+ }
313
+ }
314
+ }
315
+
316
function convertSearch($idf, $val, $field) {
317
+ return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"]) && preg_match('~[\x80-\xFF]~', $val['val'])
318
? "CONVERT($idf USING " . charset($this->_conn) . ")"
319
: $idf
320
);
391
$return = get_session("dbs");
392
if ($return === null) {
393
$query = (min_version(5)
394
+ ? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME"
395
: "SHOW DATABASES"
396
); // SHOW DATABASES can be disabled by skip_show_database
397
$return = ($flush ? slow_query($query) : get_vals($query));
499
) as $row) {
500
if ($row["Engine"] == "InnoDB") {
501
// ignore internal comment, unnecessary since MySQL 5.1.21
502
+ $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]);
503
}
504
if (!isset($row["Engine"])) {
505
$row["Comment"] = "";
536
function fields($table) {
537
$return = array();
538
foreach (get_rows("SHOW FULL COLUMNS FROM " . table($table)) as $row) {
539
+ preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $row["Type"], $match);
540
$return[$row["Field"]] = array(
541
"field" => $row["Field"],
542
"full_type" => $row["Type"],
606
*/
607
function view($name) {
608
global $connection;
609
+ return array("select" => preg_replace('~^(?:[^`]|`[^`]*`)*\s+AS\s+~isU', '', $connection->result("SHOW CREATE VIEW " . table($name), 1)));
610
}
611
612
/** Get sorted grouped list of collations
816
) {
817
return false;
818
}
819
+ foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_\\"))) as $row) {
820
+ $trigger = $row["Trigger"];
821
+ if (!queries("CREATE TRIGGER " . ($target == DB ? idf_escape("copy_$trigger") : idf_escape($target) . "." . idf_escape($trigger)) . " $row[Timing] $row[Event] ON $name FOR EACH ROW\n$row[Statement];")) {
822
+ return false;
823
+ }
824
+ }
825
}
826
foreach ($views as $table) {
827
$name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table));
891
"field" => $name,
892
"type" => strtolower($param[5]),
893
"length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]),
894
+ "unsigned" => strtolower(preg_replace('~\s+~', ' ', trim("$param[8] $param[7]"))),
895
"null" => 1,
896
"full_type" => $param[4],
897
"inout" => strtoupper($param[1]),
997
global $connection;
998
$return = $connection->result("SHOW CREATE TABLE " . table($table), 1);
999
if (!$auto_increment) {
1000
+ $return = preg_replace('~ AUTO_INCREMENT=\d+~', '', $return); //! skip comments
1001
}
1002
return $return;
1003
}
1126
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
1127
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
1128
array(
1129
+ "char" => "md5/sha1/password/encrypt/uuid",
1130
"binary" => "md5/sha1",
1131
"date|time" => "now",
1132
), array(
adminer/adminer/adminer/drivers/pgsql.inc.php CHANGED
@@ -6,7 +6,7 @@ if (isset($_GET["pgsql"])) {
6
define("DRIVER", "pgsql");
7
if (extension_loaded("pgsql")) {
8
class Min_DB {
9
- var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error;
10
11
function _error($errno, $error) {
12
if (ini_bool("html_errors")) {
@@ -69,12 +69,18 @@ if (isset($_GET["pgsql"])) {
69
$this->error = "";
70
if (!$result) {
71
$this->error = pg_last_error($this->_link);
72
- return false;
73
} elseif (!pg_num_fields($result)) {
74
$this->affected_rows = pg_affected_rows($result);
75
- return true;
76
}
77
- return new Min_Result($result);
78
}
79
80
function multi_query($query) {
@@ -139,7 +145,7 @@ if (isset($_GET["pgsql"])) {
139
140
} elseif (extension_loaded("pdo_pgsql")) {
141
class Min_DB extends Min_PDO {
142
- var $extension = "PDO_PgSQL";
143
144
function connect($server, $username, $password) {
145
global $adminer;
@@ -155,14 +161,19 @@ if (isset($_GET["pgsql"])) {
155
return ($adminer->database() == $database);
156
}
157
158
- function value($val, $field) {
159
- return $val;
160
- }
161
-
162
function quoteBinary($s) {
163
return q($s);
164
}
165
166
function warnings() {
167
return ''; // not implemented in PDO_PgSQL as of PHP 7.2.1
168
}
@@ -197,17 +208,21 @@ if (isset($_GET["pgsql"])) {
197
return true;
198
}
199
200
function convertSearch($idf, $val, $field) {
201
- return (preg_match('~char|text' . (is_numeric($val["val"]) && !preg_match('~LIKE~', $val["op"]) ? '|' . number_type() : '') . '~', $field["type"])
202
? $idf
203
: "CAST($idf AS text)"
204
);
205
}
206
207
- function value($val, $field) {
208
- return $this->_conn->value($val, $field);
209
- }
210
-
211
function quoteBinary($s) {
212
return $this->_conn->quoteBinary($s);
213
}
@@ -271,7 +286,7 @@ if (isset($_GET["pgsql"])) {
271
function limit1($table, $query, $where, $separator = "\n") {
272
return (preg_match('~^INTO~', $query)
273
? limit($query, $where, 1, 0, $separator)
274
- : " $query WHERE ctid = (SELECT ctid FROM " . table($table) . $where . $separator . "LIMIT 1)"
275
);
276
}
277
@@ -358,7 +373,7 @@ ORDER BY a.attnum"
358
$row["full_type"] = $row["type"] . $length . $addon . $array;
359
}
360
$row["null"] = !$row["attnotnull"];
361
- $row["auto_increment"] = preg_match('~^nextval\\(~i', $row["default"]);
362
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
363
if (preg_match('~(.+)::[^)]+(.*)~', $row["default"], $match)) {
364
$row["default"] = ($match[1] == "NULL" ? null : (($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2]));
@@ -434,8 +449,8 @@ WHERE table_schema = current_schema() AND table_name = " . q($name))));
434
function error() {
435
global $connection;
436
$return = h($connection->error);
437
- if (preg_match('~^(.*\\n)?([^\\n]*)\\n( *)\\^(\\n.*)?$~s', $return, $match)) {
438
- $return = $match[1] . preg_replace('~((?:[^&]|&[^;]*;){' . strlen($match[3]) . '})(.*)~', '\\1<b>\\2</b>', $match[2]) . $match[4];
439
}
440
return nl_br($return);
441
}
@@ -830,7 +845,7 @@ AND typelem = 0"
830
$structured_types[$key] = array_keys($val);
831
}
832
$unsigned = array();
833
- $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid SQL injection
834
$functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
835
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
836
$edit_functions = array(
6
define("DRIVER", "pgsql");
7
if (extension_loaded("pgsql")) {
8
class Min_DB {
9
+ var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout;
10
11
function _error($errno, $error) {
12
if (ini_bool("html_errors")) {
69
$this->error = "";
70
if (!$result) {
71
$this->error = pg_last_error($this->_link);
72
+ $return = false;
73
} elseif (!pg_num_fields($result)) {
74
$this->affected_rows = pg_affected_rows($result);
75
+ $return = true;
76
+ } else {
77
+ $return = new Min_Result($result);
78
}
79
+ if ($this->timeout) {
80
+ $this->timeout = 0;
81
+ $this->query("RESET statement_timeout");
82
+ }
83
+ return $return;
84
}
85
86
function multi_query($query) {
145
146
} elseif (extension_loaded("pdo_pgsql")) {
147
class Min_DB extends Min_PDO {
148
+ var $extension = "PDO_PgSQL", $timeout;
149
150
function connect($server, $username, $password) {
151
global $adminer;
161
return ($adminer->database() == $database);
162
}
163
164
function quoteBinary($s) {
165
return q($s);
166
}
167
168
+ function query($query, $unbuffered = false) {
169
+ $return = parent::query($query, $unbuffered);
170
+ if ($this->timeout) {
171
+ $this->timeout = 0;
172
+ parent::query("RESET statement_timeout");
173
+ }
174
+ return $return;
175
+ }
176
+
177
function warnings() {
178
return ''; // not implemented in PDO_PgSQL as of PHP 7.2.1
179
}
208
return true;
209
}
210
211
+ function slowQuery($query, $timeout) {
212
+ $this->_conn->query("SET statement_timeout = " . (1000 * $timeout));
213
+ $this->_conn->timeout = 1000 * $timeout;
214
+ return $query;
215
+ }
216
+
217
function convertSearch($idf, $val, $field) {
218
+ return (preg_match('~char|text'
219
+ . (!preg_match('~LIKE~', $val["op"]) ? '|date|time(stamp)?|boolean|uuid|' . number_type() : '')
220
+ . '~', $field["type"])
221
? $idf
222
: "CAST($idf AS text)"
223
);
224
}
225
226
function quoteBinary($s) {
227
return $this->_conn->quoteBinary($s);
228
}
286
function limit1($table, $query, $where, $separator = "\n") {
287
return (preg_match('~^INTO~', $query)
288
? limit($query, $where, 1, 0, $separator)
289
+ : " $query" . (is_view(table_status1($table)) ? $where : " WHERE ctid = (SELECT ctid FROM " . table($table) . $where . $separator . "LIMIT 1)")
290
);
291
}
292
373
$row["full_type"] = $row["type"] . $length . $addon . $array;
374
}
375
$row["null"] = !$row["attnotnull"];
376
+ $row["auto_increment"] = preg_match('~^nextval\(~i', $row["default"]);
377
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
378
if (preg_match('~(.+)::[^)]+(.*)~', $row["default"], $match)) {
379
$row["default"] = ($match[1] == "NULL" ? null : (($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2]));
449
function error() {
450
global $connection;
451
$return = h($connection->error);
452
+ if (preg_match('~^(.*\n)?([^\n]*)\n( *)\^(\n.*)?$~s', $return, $match)) {
453
+ $return = $match[1] . preg_replace('~((?:[^&]|&[^;]*;){' . strlen($match[3]) . '})(.*)~', '\1<b>\2</b>', $match[2]) . $match[4];
454
}
455
return nl_br($return);
456
}
845
$structured_types[$key] = array_keys($val);
846
}
847
$unsigned = array();
848
+ $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
849
$functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
850
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
851
$edit_functions = array(
adminer/adminer/adminer/drivers/simpledb.inc.php CHANGED
@@ -19,6 +19,7 @@ if (isset($_GET["simpledb"])) {
19
$params['NextToken'] = $this->next;
20
}
21
$result = sdb_request_all('Select', 'Item', $params, $this->timeout); //! respect $unbuffered
22
if ($result === false) {
23
return $result;
24
}
@@ -236,12 +237,22 @@ if (isset($_GET["simpledb"])) {
236
function rollback() {
237
return false;
238
}
239
240
}
241
242
243
244
function connect() {
245
return new Min_DB;
246
}
247
19
$params['NextToken'] = $this->next;
20
}
21
$result = sdb_request_all('Select', 'Item', $params, $this->timeout); //! respect $unbuffered
22
+ $this->timeout = 0;
23
if ($result === false) {
24
return $result;
25
}
237
function rollback() {
238
return false;
239
}
240
+
241
+ function slowQuery($query, $timeout) {
242
+ $this->_conn->timeout = $timeout;
243
+ return $query;
244
+ }
245
246
}
247
248
249
250
function connect() {
251
+ global $adminer;
252
+ list(, , $password) = $adminer->credentials();
253
+ if ($password != "") {
254
+ return lang('Database does not support password.');
255
+ }
256
return new Min_DB;
257
}
258
adminer/adminer/adminer/drivers/sqlite.inc.php CHANGED
@@ -152,7 +152,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
152
153
function fetch_field() {
154
$name = $this->_result->fieldName($this->_offset++);
155
- $pattern = '(\\[.*]|"(?:[^"]|"")*"|(.+))';
156
if (preg_match("~^($pattern\\.)?$pattern\$~", $name, $match)) {
157
$table = ($match[3] != "" ? $match[3] : idf_unescape($match[2]));
158
$name = ($match[5] != "" ? $match[5] : idf_unescape($match[4]));
@@ -240,6 +240,11 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
240
}
241
242
function connect() {
243
return new Min_DB;
244
}
245
@@ -273,7 +278,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
273
}
274
275
function tables_list() {
276
- return get_key_vals("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY (name = 'sqlite_sequence'), name", 1);
277
}
278
279
function count_tables($databases) {
@@ -402,7 +407,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
402
403
function view($name) {
404
global $connection;
405
- return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE name = " . q($name)))); //! identifiers may be inside []
406
}
407
408
function collations() {
@@ -649,7 +654,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
649
if ($name == "") {
650
return array("Statement" => "BEGIN\n\t;\nEND");
651
}
652
- $idf = '(?:[^`"\\s]+|`[^`]*`|"[^"]*")+';
653
$trigger_options = trigger_options();
654
preg_match(
655
"~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is",
@@ -670,7 +675,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
670
$return = array();
671
$trigger_options = trigger_options();
672
foreach (get_rows("SELECT * FROM sqlite_master WHERE type = 'trigger' AND tbl_name = " . q($table)) as $row) {
673
- preg_match('~^CREATE\\s+TRIGGER\\s*(?:[^`"\\s]+|`[^`]*`|"[^"]*")+\\s*(' . implode("|", $trigger_options["Timing"]) . ')\\s*(.*)\\s+ON\\b~iU', $row["sql"], $match);
674
$return[$row["name"]] = array($match[1], $match[2]);
675
}
676
return $return;
152
153
function fetch_field() {
154
$name = $this->_result->fieldName($this->_offset++);
155
+ $pattern = '(\[.*]|"(?:[^"]|"")*"|(.+))';
156
if (preg_match("~^($pattern\\.)?$pattern\$~", $name, $match)) {
157
$table = ($match[3] != "" ? $match[3] : idf_unescape($match[2]));
158
$name = ($match[5] != "" ? $match[5] : idf_unescape($match[4]));
240
}
241
242
function connect() {
243
+ global $adminer;
244
+ list(, , $password) = $adminer->credentials();
245
+ if ($password != "") {
246
+ return lang('Database does not support password.');
247
+ }
248
return new Min_DB;
249
}
250
278
}
279
280
function tables_list() {
281
+ return get_key_vals("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY (name = 'sqlite_sequence'), name");
282
}
283
284
function count_tables($databases) {
407
408
function view($name) {
409
global $connection;
410
+ return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE name = " . q($name)))); //! identifiers may be inside []
411
}
412
413
function collations() {
654
if ($name == "") {
655
return array("Statement" => "BEGIN\n\t;\nEND");
656
}
657
+ $idf = '(?:[^`"\s]+|`[^`]*`|"[^"]*")+';
658
$trigger_options = trigger_options();
659
preg_match(
660
"~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is",
675
$return = array();
676
$trigger_options = trigger_options();
677
foreach (get_rows("SELECT * FROM sqlite_master WHERE type = 'trigger' AND tbl_name = " . q($table)) as $row) {
678
+ preg_match('~^CREATE\s+TRIGGER\s*(?:[^`"\s]+|`[^`]*`|"[^"]*")+\s*(' . implode("|", $trigger_options["Timing"]) . ')\s*(.*)\s+ON\b~iU', $row["sql"], $match);
679
$return[$row["name"]] = array($match[1], $match[2]);
680
}
681
return $return;
adminer/adminer/adminer/event.inc.php CHANGED
@@ -42,7 +42,7 @@ if (!$row && $EVENT != "") {
42
<tr><th><?php echo lang('Every'); ?><td><input type="number" name="INTERVAL_VALUE" value="<?php echo h($row["INTERVAL_VALUE"]); ?>" class="size"> <?php echo html_select("INTERVAL_FIELD", $intervals, $row["INTERVAL_FIELD"]); ?>
43
<tr><th><?php echo lang('Status'); ?><td><?php echo html_select("STATUS", $statuses, $row["STATUS"]); ?>
44
<tr><th><?php echo lang('Comment'); ?><td><input name="EVENT_COMMENT" value="<?php echo h($row["EVENT_COMMENT"]); ?>" maxlength="64">
45
- <tr><th>&nbsp;<td><?php echo checkbox("ON_COMPLETION", "PRESERVE", $row["ON_COMPLETION"] == "PRESERVE", lang('On completion preserve')); ?>
46
</table>
47
<p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?>
48
<p>
42
<tr><th><?php echo lang('Every'); ?><td><input type="number" name="INTERVAL_VALUE" value="<?php echo h($row["INTERVAL_VALUE"]); ?>" class="size"> <?php echo html_select("INTERVAL_FIELD", $intervals, $row["INTERVAL_FIELD"]); ?>
43
<tr><th><?php echo lang('Status'); ?><td><?php echo html_select("STATUS", $statuses, $row["STATUS"]); ?>
44
<tr><th><?php echo lang('Comment'); ?><td><input name="EVENT_COMMENT" value="<?php echo h($row["EVENT_COMMENT"]); ?>" maxlength="64">
45
+ <tr><th><td><?php echo checkbox("ON_COMPLETION", "PRESERVE", $row["ON_COMPLETION"] == "PRESERVE", lang('On completion preserve')); ?>
46
</table>
47
<p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?>
48
<p>
adminer/adminer/adminer/file.inc.php CHANGED
@@ -1,13 +1,5 @@
1
<?php
2
- //! rewrite in compile.php to cache moderately with -dev version
3
- if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
4
- header("HTTP/1.1 304 Not Modified");
5
- exit;
6
- }
7
-
8
- header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
9
- header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
10
- header("Cache-Control: immutable");
11
12
if ($_GET["file"] == "favicon.ico") {
13
header("Content-Type: image/x-icon");
1
<?php
2
+ // caching headers added in compile.php
3
4
if ($_GET["file"] == "favicon.ico") {
5
header("Content-Type: image/x-icon");
adminer/adminer/adminer/include/adminer.inc.php CHANGED
@@ -75,7 +75,7 @@ class Adminer {
75
* @return float number of seconds
76
*/
77
function queryTimeout() {
78
- return 5;
79
}
80
81
/** Headers to send before HTML output
@@ -118,19 +118,26 @@ class Adminer {
118
*/
119
function loginForm() {
120
global $drivers;
121
- ?>
122
- <table cellspacing="0">
123
- <tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>
124
- <tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]" placeholder="localhost" autocapitalize="off">
125
- <tr><th><?php echo lang('Username'); ?><td><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
126
- <tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
127
- <tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>" autocapitalize="off">
128
- </table>
129
- <?php
130
- echo script("focus(qs('#username'));");
131
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
132
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
133
}
134
135
/** Authorize the user
136
* @param string
@@ -138,9 +145,8 @@ class Adminer {
138
* @return mixed true for success, string for error message, false for unknown error
139
*/
140
function login($login, $password) {
141
- global $jush;
142
- if ($jush == "sqlite") {
143
- return lang('<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.', target_blank(), '<code>login()</code>');
144
}
145
return true;
146
}
@@ -312,7 +318,7 @@ class Adminer {
312
echo ($field["null"] ? " <i>NULL</i>" : "");
313
echo ($field["auto_increment"] ? " <i>" . lang('Auto Increment') . "</i>" : "");
314
echo (isset($field["default"]) ? " <span title='" . lang('Default value') . "'>[<b>" . h($field["default"]) . "</b>]</span>" : "");
315
- echo (support("comment") ? "<td>" . nbsp($field["comment"]) : "");
316
echo "\n";
317
}
318
echo "</table>\n";
@@ -553,7 +559,7 @@ class Adminer {
553
// find anywhere
554
$cols = array();
555
foreach ($fields as $name => $field) {
556
- if ((is_numeric($val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
557
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
558
) {
559
$cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond;
@@ -575,7 +581,7 @@ class Adminer {
575
$return = array();
576
foreach ((array) $_GET["order"] as $key => $val) {
577
if ($val != "") {
578
- $return[] = (preg_match('~^((COUNT\\(DISTINCT |[A-Z0-9_]+\\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\\)|COUNT\\(\\*\\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses []
579
. (isset($_GET["desc"][$key]) ? " DESC" : "")
580
;
581
}
@@ -718,7 +724,7 @@ class Adminer {
718
$return = "$function()";
719
} elseif (preg_match('~^current_(date|timestamp)$~', $function)) {
720
$return = $function;
721
- } elseif (preg_match('~^([+-]|\\|\\|)$~', $function)) {
722
$return = idf_escape($name) . " $function $return";
723
} elseif (preg_match('~^[+-] interval$~', $function)) {
724
$return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+\$~i", $value) ? $value : $return);
@@ -837,7 +843,7 @@ class Adminer {
837
foreach ($row as $key => $val) {
838
$field = $fields[$key];
839
$row[$key] = ($val !== null
840
- ? unconvert_field($field, preg_match(number_type(), $field["type"]) && $val != '' ? $val : q($val))
841
: "NULL"
842
);
843
}
@@ -962,7 +968,7 @@ class Adminer {
962
}
963
$server_info = $connection->server_info;
964
?>
965
- bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\\d\\.?\\d).*~s', '\\1', $server_info) : ""); ?>'<?php echo (preg_match('~MariaDB~', $server_info) ? ", true" : ""); ?>);
966
</script>
967
<?php
968
}
@@ -991,6 +997,9 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\\d\\.?\\d).*~s'
991
function databasesPrint($missing) {
992
global $adminer, $connection;
993
$databases = $this->databases();
994
?>
995
<form action="">
996
<p id="dbs">
@@ -1010,11 +1019,12 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\\d\\.?\\d).*~s'
1010
}
1011
}
1012
}
1013
- echo (isset($_GET["sql"]) ? '<input type="hidden" name="sql" value="">'
1014
- : (isset($_GET["schema"]) ? '<input type="hidden" name="schema" value="">'
1015
- : (isset($_GET["dump"]) ? '<input type="hidden" name="dump" value="">'
1016
- : (isset($_GET["privileges"]) ? '<input type="hidden" name="privileges" value="">'
1017
- : ""))));
1018
echo "</p></form>\n";
1019
}
1020
75
* @return float number of seconds
76
*/
77
function queryTimeout() {
78
+ return 2;
79
}
80
81
/** Headers to send before HTML output
118
*/
119
function loginForm() {
120
global $drivers;
121
+ echo "<table cellspacing='0'>\n";
122
+ echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER) . "\n");
123
+ echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n");
124
+ echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocapitalize="off">' . script("focus(qs('#username'));"));
125
+ echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]">' . "\n");
126
+ echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n");
127
+ echo "</table>\n";
128
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
129
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
130
}
131
+
132
+ /** Get login form field
133
+ * @param string
134
+ * @param string HTML
135
+ * @param string HTML
136
+ * @return string
137
+ */
138
+ function loginFormField($name, $heading, $value) {
139
+ return $heading . $value;
140
+ }
141
142
/** Authorize the user
143
* @param string
145
* @return mixed true for success, string for error message, false for unknown error
146
*/
147
function login($login, $password) {
148
+ if ($password == "") {
149
+ return lang('Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.', target_blank());
150
}
151
return true;
152
}
318
echo ($field["null"] ? " <i>NULL</i>" : "");
319
echo ($field["auto_increment"] ? " <i>" . lang('Auto Increment') . "</i>" : "");
320
echo (isset($field["default"]) ? " <span title='" . lang('Default value') . "'>[<b>" . h($field["default"]) . "</b>]</span>" : "");
321
+ echo (support("comment") ? "<td>" . h($field["comment"]) : "");
322
echo "\n";
323
}
324
echo "</table>\n";
559
// find anywhere
560
$cols = array();
561
foreach ($fields as $name => $field) {
562
+ if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
563
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
564
) {
565
$cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond;
581
$return = array();
582
foreach ((array) $_GET["order"] as $key => $val) {
583
if ($val != "") {
584
+ $return[] = (preg_match('~^((COUNT\(DISTINCT |[A-Z0-9_]+\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\)|COUNT\(\*\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses []
585
. (isset($_GET["desc"][$key]) ? " DESC" : "")
586
;
587
}
724
$return = "$function()";
725
} elseif (preg_match('~^current_(date|timestamp)$~', $function)) {
726
$return = $function;
727
+ } elseif (preg_match('~^([+-]|\|\|)$~', $function)) {
728
$return = idf_escape($name) . " $function $return";
729
} elseif (preg_match('~^[+-] interval$~', $function)) {
730
$return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+\$~i", $value) ? $value : $return);
843
foreach ($row as $key => $val) {
844
$field = $fields[$key];
845
$row[$key] = ($val !== null
846
+ ? unconvert_field($field, preg_match(number_type(), $field["type"]) && $val != '' ? $val : q(($val === false ? 0 : $val)))
847
: "NULL"
848
);
849
}
968
}
969
$server_info = $connection->server_info;
970
?>
971
+ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $server_info) : ""); ?>'<?php echo (preg_match('~MariaDB~', $server_info) ? ", true" : ""); ?>);
972
</script>
973
<?php
974
}
997
function databasesPrint($missing) {
998
global $adminer, $connection;
999
$databases = $this->databases();
1000
+ if ($databases && !in_array(DB, $databases)) {
1001
+ array_unshift($databases, DB);
1002
+ }
1003
?>
1004
<form action="">
1005
<p id="dbs">
1019
}
1020
}
1021
}
1022
+ foreach (array("import", "sql", "schema", "dump", "privileges") as $val) {
1023
+ if (isset($_GET[$val])) {
1024
+ echo "<input type='hidden' name='$val' value=''>";
1025
+ break;
1026
+ }
1027
+ }
1028
echo "</p></form>\n";
1029
}
1030
adminer/adminer/adminer/include/auth.inc.php CHANGED
@@ -120,6 +120,7 @@ function auth_error($error) {
120
if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$has_token) {
121
$error = lang('Session expired, please login again.');
122
} else {
123
add_invalid_login();
124
$password = get_password();
125
if ($password !== null) {
@@ -149,14 +150,17 @@ function auth_error($error) {
149
exit;
150
}
151
152
if (isset($_GET["username"])) {
153
- if (!class_exists("Min_DB")) {
154
- unset($_SESSION["pwds"][DRIVER]);
155
- unset_permanent();
156
- page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
157
- page_footer("auth");
158
- exit;
159
- }
160
list($host, $port) = explode(":", SERVER, 2);
161
if (is_numeric($port) && $port < 1024) {
162
auth_error(lang('Connecting to privileged ports is not allowed.'));
120
if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$has_token) {
121
$error = lang('Session expired, please login again.');
122
} else {
123
+ restart_session();
124
add_invalid_login();
125
$password = get_password();
126
if ($password !== null) {
150
exit;
151
}
152
153
+ if (isset($_GET["username"]) && !class_exists("Min_DB")) {
154
+ unset($_SESSION["pwds"][DRIVER]);
155
+ unset_permanent();
156
+ page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
157
+ page_footer("auth");
158
+ exit;
159
+ }
160
+
161
+ stop_session(true);
162
+
163
if (isset($_GET["username"])) {
164
list($host, $port) = explode(":", SERVER, 2);
165
if (is_numeric($port) && $port < 1024) {
166
auth_error(lang('Connecting to privileged ports is not allowed.'));
adminer/adminer/adminer/include/bootstrap.inc.php CHANGED
@@ -33,7 +33,7 @@ if ($_GET["script"] == "version") {
33
exit;
34
}
35
36
- global $adminer, $connection, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $has_token, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
37
38
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
39
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
@@ -44,13 +44,13 @@ if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { /
44
if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) {
45
$_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"];
46
}
47
- $HTTPS = $_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off");
48
49
@ini_set("session.use_trans_sid", false); // protect links in export, @ - may be disabled
50
if (!defined("SID")) {
51
session_cache_limiter(""); // to allow restarting session
52
session_name("adminer_sid"); // use specific session name to get own namespace
53
- $params = array(0, preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS);
54
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
55
$params[] = true; // HttpOnly
56
}
@@ -83,7 +83,7 @@ include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
83
84
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost
85
define("DB", $_GET["db"]); // for the sake of speed and size
86
- define("ME", preg_replace('~^[^?]*/([^?]*).*~', '\\1', $_SERVER["REQUEST_URI"]) . '?'
87
. (sid() ? SID . '&' : '')
88
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
89
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
@@ -95,11 +95,6 @@ include "./include/adminer.inc.php";
95
include "../adminer/include/design.inc.php";
96
include "../adminer/include/xxtea.inc.php";
97
include "../adminer/include/auth.inc.php";
98
-
99
- if (!ini_bool("session.use_cookies") || @ini_set("session.use_cookies", false) !== false) { // @ - may be disabled
100
- session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later
101
- }
102
-
103
include "./include/editing.inc.php";
104
include "./include/connect.inc.php";
105
33
exit;
34
}
35
36
+ global $adminer, $connection, $driver, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $has_token, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
37
38
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
39
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
44
if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) {
45
$_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"];
46
}
47
+ $HTTPS = ($_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off")) || ini_bool("session.cookie_secure"); // session.cookie_secure could be set on HTTP if we are behind a reverse proxy
48
49
@ini_set("session.use_trans_sid", false); // protect links in export, @ - may be disabled
50
if (!defined("SID")) {
51
session_cache_limiter(""); // to allow restarting session
52
session_name("adminer_sid"); // use specific session name to get own namespace
53
+ $params = array(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS);
54
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
55
$params[] = true; // HttpOnly
56
}
83
84
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost
85
define("DB", $_GET["db"]); // for the sake of speed and size
86
+ define("ME", preg_replace('~^[^?]*/([^?]*).*~', '\1', $_SERVER["REQUEST_URI"]) . '?'
87
. (sid() ? SID . '&' : '')
88
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
89
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
95
include "../adminer/include/design.inc.php";
96
include "../adminer/include/xxtea.inc.php";
97
include "../adminer/include/auth.inc.php";
98
include "./include/editing.inc.php";
99
include "./include/connect.inc.php";
100
adminer/adminer/adminer/include/connect.inc.php CHANGED
@@ -32,7 +32,7 @@ function connect_error() {
32
echo "<table cellspacing='0' class='checkable'>\n";
33
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
34
echo "<thead><tr>"
35
- . (support("database") ? "<td>&nbsp;" : "")
36
. "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>"
37
. "<td>" . lang('Collation')
38
. "<td>" . lang('Tables')
@@ -47,7 +47,7 @@ function connect_error() {
47
$id = h("Db-" . $db);
48
echo "<tr" . odd() . ">" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : "");
49
echo "<th><a href='$root' id='$id'>" . h($db) . "</a>";
50
- $collation = nbsp(db_collation($db, $collations));
51
echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation);
52
echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>" . ($_GET["dbsize"] ? $tables : "?") . "</a>";
53
echo "<td align='right' id='size-" . h($db) . "'>" . ($_GET["dbsize"] ? db_size($db) : "?");
32
echo "<table cellspacing='0' class='checkable'>\n";
33
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
34
echo "<thead><tr>"
35
+ . (support("database") ? "<td>" : "")
36
. "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>"
37
. "<td>" . lang('Collation')
38
. "<td>" . lang('Tables')
47
$id = h("Db-" . $db);
48
echo "<tr" . odd() . ">" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : "");
49
echo "<th><a href='$root' id='$id'>" . h($db) . "</a>";
50
+ $collation = h(db_collation($db, $collations));
51
echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation);
52
echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>" . ($_GET["dbsize"] ? $tables : "?") . "</a>";
53
echo "<td align='right' id='size-" . h($db) . "'>" . ($_GET["dbsize"] ? db_size($db) : "?");
adminer/adminer/adminer/include/driver.inc.php CHANGED
@@ -113,6 +113,14 @@
113
return queries("ROLLBACK");
114
}
115
116
/** Convert column to be searchable
117
* @param string escaped column name
118
* @param array array("op" => , "val" => )
@@ -129,7 +137,10 @@
129
* @return string
130
*/
131
function value($val, $field) {
132
- return $val;
133
}
134
135
/** Quote binary string
113
return queries("ROLLBACK");
114
}
115
116
+ /** Return query with a timeout
117
+ * @param string
118
+ * @param int seconds
119
+ * @return string or null if the driver doesn't support query timeouts
120
+ */
121
+ function slowQuery($query, $timeout) {
122
+ }
123
+
124
/** Convert column to be searchable
125
* @param string escaped column name
126
* @param array array("op" => , "val" => )
137
* @return string
138
*/
139
function value($val, $field) {
140
+ return (method_exists($this->_conn, 'value')
141
+ ? $this->_conn->value($val, $field)
142
+ : (is_resource($val) ? stream_get_contents($val) : $val)
143
+ );
144
}
145
146
/** Quote binary string
adminer/adminer/adminer/include/editing.inc.php CHANGED
@@ -64,8 +64,6 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
64
$val = "<i>NULL</i>";
65
} elseif ($blobs[$key] && !is_utf8($val)) {
66
$val = "<i>" . lang('%d byte(s)', strlen($val)) . "</i>"; //! link to download
67
- } elseif (!strlen($val)) { // strlen - SQLite can return int
68
- $val = "&nbsp;"; // some content to print a border
69
} else {
70
$val = h($val);
71
if ($types[$key] == 254) { // 254 - char
@@ -156,7 +154,7 @@ echo optionlist(array_merge($extra_types, $structured_types), $type);
156
?></select>
157
<?php echo on_help("getTarget(event).value", 1); ?>
158
<?php echo script("mixin(qsl('select'), {onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange});", ""); ?>
159
- <td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); ?> aria-labelledby="label-length"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php //! type="number" with enabled JavaScript
160
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
161
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
162
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>' . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), $field["on_update"]) . '</select>' : '');
@@ -245,7 +243,7 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
245
$fields = array_values($fields);
246
?>
247
<thead><tr>
248
- <?php if ($type == "PROCEDURE") { ?><td>&nbsp;<?php } ?>
249
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
250
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
251
<td id="label-length"><?php echo lang('Length'); ?>
@@ -285,9 +283,9 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
285
}
286
echo "<td>";
287
echo (support("move_col") ?
288
- "<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>&nbsp;"
289
- . "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='↑' title='" . lang('Move up') . "'>&nbsp;"
290
- . "<input type='image' class='icon' name='down[$i]' src='../adminer/static/down.gif' alt='↓' title='" . lang('Move down') . "'>&nbsp;"
291
: "");
292
echo ($orig == "" || support("drop_col") ? "<input type='image' class='icon' name='drop_col[$i]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" : "");
293
}
@@ -360,7 +358,7 @@ function grant($grant, $privileges, $columns, $on) {
360
: queries("$grant ALL PRIVILEGES$on") && queries("$grant GRANT OPTION$on")
361
);
362
}
363
- return queries("$grant " . preg_replace('~(GRANT OPTION)\\([^)]*\\)~', '\\1', implode("$columns, ", $privileges) . $columns) . $on);
364
}
365
366
/** Drop old object and create a new one
@@ -443,7 +441,7 @@ function create_routine($routine, $row) {
443
* @return string
444
*/
445
function remove_definer($query) {
446
- return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $query); //! proper escaping of user
447
}
448
449
/** Format foreign key to use in SQL query
@@ -499,7 +497,7 @@ function ini_bytes($ini) {
499
function doc_link($paths, $text = "<sup>?</sup>") {
500
global $jush, $connection;
501
$server_info = $connection->server_info;
502
- $version = preg_replace('~^(\\d\\.?\\d).*~s', '\\1', $server_info); // two most significant digits
503
$urls = array(
504
'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
505
'sqlite' => "https://www.sqlite.org/",
64
$val = "<i>NULL</i>";
65
} elseif ($blobs[$key] && !is_utf8($val)) {
66
$val = "<i>" . lang('%d byte(s)', strlen($val)) . "</i>"; //! link to download
67
} else {
68
$val = h($val);
69
if ($types[$key] == 254) { // 254 - char
154
?></select>
155
<?php echo on_help("getTarget(event).value", 1); ?>
156
<?php echo script("mixin(qsl('select'), {onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange});", ""); ?>
157
+ <td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?> aria-labelledby="label-length"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php
158
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
159
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
160
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>' . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), $field["on_update"]) . '</select>' : '');
243
$fields = array_values($fields);
244
?>
245
<thead><tr>
246
+ <?php if ($type == "PROCEDURE") { ?><td><?php } ?>
247
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
248
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
249
<td id="label-length"><?php echo lang('Length'); ?>
283
}
284
echo "<td>";
285
echo (support("move_col") ?
286
+ "<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'> "
287
+ . "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='↑' title='" . lang('Move up') . "'> "
288
+ . "<input type='image' class='icon' name='down[$i]' src='../adminer/static/down.gif' alt='↓' title='" . lang('Move down') . "'> "
289
: "");
290
echo ($orig == "" || support("drop_col") ? "<input type='image' class='icon' name='drop_col[$i]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" : "");
291
}
358
: queries("$grant ALL PRIVILEGES$on") && queries("$grant GRANT OPTION$on")
359
);
360
}
361
+ return queries("$grant " . preg_replace('~(GRANT OPTION)\([^)]*\)~', '\1', implode("$columns, ", $privileges) . $columns) . $on);
362
}
363
364
/** Drop old object and create a new one
441
* @return string
442
*/
443
function remove_definer($query) {
444
+ return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\1)', logged_user()) . '`~', '\1', $query); //! proper escaping of user
445
}
446
447
/** Format foreign key to use in SQL query
497
function doc_link($paths, $text = "<sup>?</sup>") {
498
global $jush, $connection;
499
$server_info = $connection->server_info;
500
+ $version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits
501
$urls = array(
502
'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
503
'sqlite' => "https://www.sqlite.org/",
adminer/adminer/adminer/include/functions.inc.php CHANGED
@@ -154,14 +154,6 @@ function h($string) {
154
return str_replace("\0", "&#0;", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
155
}
156
157
- /** Escape for TD
158
- * @param string
159
- * @return string
160
- */
161
- function nbsp($string) {
162
- return (trim($string) != "" ? h($string) : "&nbsp;");
163
- }
164
-
165
/** Convert \n to <br>
166
* @param string
167
* @return string
@@ -401,19 +393,16 @@ function get_vals($query, $column = 0) {
401
/** Get keys from first column and values from second
402
* @param string
403
* @param Min_DB
404
- * @param float
405
* @param bool
406
* @return array
407
*/
408
- function get_key_vals($query, $connection2 = null, $timeout = 0, $set_keys = true) {
409
global $connection;
410
if (!is_object($connection2)) {
411
$connection2 = $connection;
412
}
413
$return = array();
414
- $connection2->timeout = $timeout;
415
$result = $connection2->query($query);
416
- $connection2->timeout = 0;
417
if (is_object($result)) {
418
while ($row = $result->fetch_row()) {
419
if ($set_keys) {
@@ -490,7 +479,7 @@ function where($where, $fields = array()) {
490
$key = bracket_escape($key, 1); // 1 - back
491
$column = escape_key($key);
492
$return[] = $column
493
- . ($jush == "sql" && preg_match('~^[0-9]*\\.[0-9]*$~', $val) ? " LIKE " . q(addcslashes($val, "%_\\"))
494
: ($jush == "mssql" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val))
495
: " = " . unconvert_field($fields[$key], q($val))
496
)) // LIKE because of floats but slow with ints, in MS SQL because of text
@@ -557,7 +546,7 @@ function cookie($name, $value, $lifetime = 2592000) { // 2592000 - 30 days
557
global $HTTPS;
558
return header("Set-Cookie: $name=" . urlencode($value)
559
. ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "")
560
- . "; path=" . preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"])
561
. ($HTTPS ? "; secure" : "")
562
. "; HttpOnly; SameSite=lax",
563
false);
@@ -572,12 +561,13 @@ function restart_session() {
572
}
573
}
574
575
- /** Stop session if it would be possible to restart it later
576
* @return null
577
*/
578
- function stop_session() {
579
- if (!ini_bool("session.use_cookies")) {
580
- session_write_close();
581
}
582
}
583
@@ -607,7 +597,7 @@ function set_session($key, $val) {
607
*/
608
function auth_url($vendor, $server, $username, $db = null) {
609
global $drivers;
610
- preg_match('~([^?]*)\\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . ($db !== null ? "db|" : "") . session_name()), $match);
611
return "$match[1]?"
612
. (sid() ? SID . "&" : "")
613
. ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "")
@@ -767,7 +757,7 @@ function get_file($key, $decompress = false) {
767
}
768
$name = $file["name"][$key];
769
$tmp_name = $file["tmp_name"][$key];
770
- $content = file_get_contents($decompress && preg_match('~\\.gz$~', $name)
771
? "compress.zlib://$tmp_name"
772
: $tmp_name
773
); //! may not be reachable because of open_basedir
@@ -812,7 +802,7 @@ function repeat_pattern($pattern, $length) {
812
*/
813
function is_utf8($val) {
814
// don't print control chars except \t\r\n
815
- return (preg_match('~~u', $val) && !preg_match('~[\\0-\\x8\\xB\\xC\\xE-\\x1F]~', $val));
816
}
817
818
/** Shorten UTF-8 string
@@ -946,14 +936,14 @@ function input($field, $value, $function) {
946
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
947
$attrs = " name='fields[$name]'";
948
if ($field["type"] == "enum") {
949
- echo nbsp($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
950
} else {
951
$has_function = (in_array($function, $functions) || isset($functions[$function]));
952
echo (count($functions) > 1
953
? "<select name='function[$name]'>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
954
. on_help("getTarget(event).value.replace(/^SQL\#x2F;, '')", 1)
955
. script("qsl('select').onchange = functionChange;", "")
956
- : nbsp(reset($functions))
957
) . '<td>';
958
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
959
if ($input != "") {
@@ -982,7 +972,7 @@ function input($field, $value, $function) {
982
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
983
} else {
984
// int(3) is only a display hint
985
- $maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
986
if ($jush == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
987
$maxlength += 7; // microtime
988
}
@@ -1253,9 +1243,7 @@ function select_value($val, $link, $field, $text_length) {
1253
}
1254
$return = $adminer->editVal($val, $field);
1255
if ($return !== null) {
1256
- if ($return === "") { // === - may be int
1257
- $return = "&nbsp;";
1258
- } elseif (!is_utf8($return)) {
1259
$return = "\0"; // htmlspecialchars of binary data returns an empty string
1260
} elseif ($text_length != "" && is_shortable($field)) {
1261
$return = shorten_utf8($return, max(0, +$text_length)); // usage of LEFT() would reduce traffic but complicate query - expected average speedup: .001 s VS .01 s on local network
@@ -1315,10 +1303,11 @@ function count_rows($table, $where, $is_group, $group) {
1315
* @return array of strings
1316
*/
1317
function slow_query($query) {
1318
- global $adminer, $token;
1319
$db = $adminer->database();
1320
$timeout = $adminer->queryTimeout();
1321
- if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
1322
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
1323
?>
1324
<script<?php echo nonce(); ?>>
@@ -1333,7 +1322,7 @@ var timeout = setTimeout(function () {
1333
}
1334
ob_flush();
1335
flush();
1336
- $return = @get_key_vals($query, $connection2, $timeout, false); // @ - may be killed
1337
if ($connection2) {
1338
echo script("clearTimeout(timeout);");
1339
ob_flush();
154
return str_replace("\0", "&#0;", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
155
}
156
157
/** Convert \n to <br>
158
* @param string
159
* @return string
393
/** Get keys from first column and values from second
394
* @param string
395
* @param Min_DB
396
* @param bool
397
* @return array
398
*/
399
+ function get_key_vals($query, $connection2 = null, $set_keys = true) {
400
global $connection;
401
if (!is_object($connection2)) {
402
$connection2 = $connection;
403
}
404
$return = array();
405
$result = $connection2->query($query);
406
if (is_object($result)) {
407
while ($row = $result->fetch_row()) {
408
if ($set_keys) {
479
$key = bracket_escape($key, 1); // 1 - back
480
$column = escape_key($key);
481
$return[] = $column
482
+ . ($jush == "sql" && preg_match('~^[0-9]*\.[0-9]*$~', $val) ? " LIKE " . q(addcslashes($val, "%_\\"))
483
: ($jush == "mssql" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val))
484
: " = " . unconvert_field($fields[$key], q($val))
485
)) // LIKE because of floats but slow with ints, in MS SQL because of text
546
global $HTTPS;
547
return header("Set-Cookie: $name=" . urlencode($value)
548
. ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "")
549
+ . "; path=" . preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"])
550
. ($HTTPS ? "; secure" : "")
551
. "; HttpOnly; SameSite=lax",
552
false);
561
}
562
}
563
564
+ /** Stop session if possible
565
+ * @param bool
566
* @return null
567
*/
568
+ function stop_session($force = false) {
569
+ if (!ini_bool("session.use_cookies") || ($force && @ini_set("session.use_cookies", false) !== false)) { // @ - may be disabled
570
+ session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later
571
}
572
}
573
597
*/
598
function auth_url($vendor, $server, $username, $db = null) {
599
global $drivers;
600
+ preg_match('~([^?]*)\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . ($db !== null ? "db|" : "") . session_name()), $match);
601
return "$match[1]?"
602
. (sid() ? SID . "&" : "")
603
. ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "")
757
}
758
$name = $file["name"][$key];
759
$tmp_name = $file["tmp_name"][$key];
760
+ $content = file_get_contents($decompress && preg_match('~\.gz$~', $name)
761
? "compress.zlib://$tmp_name"
762
: $tmp_name
763
); //! may not be reachable because of open_basedir
802
*/
803
function is_utf8($val) {
804
// don't print control chars except \t\r\n
805
+ return (preg_match('~~u', $val) && !preg_match('~[\0-\x8\xB\xC\xE-\x1F]~', $val));
806
}
807
808
/** Shorten UTF-8 string
936
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
937
$attrs = " name='fields[$name]'";
938
if ($field["type"] == "enum") {
939
+ echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
940
} else {
941
$has_function = (in_array($function, $functions) || isset($functions[$function]));
942
echo (count($functions) > 1
943
? "<select name='function[$name]'>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
944
. on_help("getTarget(event).value.replace(/^SQL\#x2F;, '')", 1)
945
. script("qsl('select').onchange = functionChange;", "")
946
+ : h(reset($functions))
947
) . '<td>';
948
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
949
if ($input != "") {
972
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
973
} else {
974
// int(3) is only a display hint
975
+ $maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match) ? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
976
if ($jush == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
977
$maxlength += 7; // microtime
978
}
1243
}
1244
$return = $adminer->editVal($val, $field);
1245
if ($return !== null) {
1246
+ if (!is_utf8($return)) {
1247
$return = "\0"; // htmlspecialchars of binary data returns an empty string
1248
} elseif ($text_length != "" && is_shortable($field)) {
1249
$return = shorten_utf8($return, max(0, +$text_length)); // usage of LEFT() would reduce traffic but complicate query - expected average speedup: .001 s VS .01 s on local network
1303
* @return array of strings
1304
*/
1305
function slow_query($query) {
1306
+ global $adminer, $token, $driver;
1307
$db = $adminer->database();
1308
$timeout = $adminer->queryTimeout();
1309
+ $slow_query = $driver->slowQuery($query, $timeout);
1310
+ if (!$slow_query && support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
1311
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
1312
?>
1313
<script<?php echo nonce(); ?>>
1322
}
1323
ob_flush();
1324
flush();
1325
+ $return = @get_key_vals(($slow_query ? $slow_query : $query), $connection2, false); // @ - may be killed
1326
if ($connection2) {
1327
echo script("clearTimeout(timeout);");
1328
ob_flush();
adminer/adminer/adminer/include/pdo.inc.php CHANGED
@@ -29,6 +29,9 @@ if (extension_loaded('pdo')) {
29
$this->error = "";
30
if (!$result) {
31
list(, $this->errno, $this->error) = $this->errorInfo();
32
return false;
33
}
34
$this->store_result($result);
29
$this->error = "";
30
if (!$result) {
31
list(, $this->errno, $this->error) = $this->errorInfo();
32
+ if (!$this->error) {
33
+ $this->error = lang('Unknown error.');
34
+ }
35
return false;
36
}
37
$this->store_result($result);
adminer/adminer/adminer/include/version.inc.php CHANGED
@@ -1,2 +1,2 @@
1
<?php
2
- $VERSION = "4.6.2";
1
<?php
2
+ $VERSION = "4.6.3";
adminer/adminer/adminer/indexes.inc.php CHANGED
@@ -99,7 +99,7 @@ if (!$row) {
99
<th id="label-type"><?php echo lang('Index Type'); ?>
100
<th><input type="submit" class="wayoff"><?php echo lang('Column (length)'); ?>
101
<th id="label-name"><?php echo lang('Name'); ?>
102
- <th><noscript><input type='image' class='icon' name='add[0]' src='../adminer/static/plus.gif' alt='+' title='<?php echo lang('Add next'); ?>'></noscript>&nbsp;
103
</thead>
104
<?php
105
if ($primary) {
99
<th id="label-type"><?php echo lang('Index Type'); ?>
100
<th><input type="submit" class="wayoff"><?php echo lang('Column (length)'); ?>
101
<th id="label-name"><?php echo lang('Name'); ?>
102
+ <th><noscript><?php echo "<input type='image' class='icon' name='add[0]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>"; ?></noscript>
103
</thead>
104
<?php
105
if ($primary) {
adminer/adminer/adminer/lang/cs.inc.php CHANGED
@@ -10,9 +10,10 @@ $translations = array(
10
'Logout' => 'Odhlásit',
11
'Logged as: %s' => 'Přihlášen jako: %s',
12
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
13
- 'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Díky za použití Admineru, zvažte <a href="%s">příspěvek</a>.',
14
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
15
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => 'Pro přihlášení k SQLite <a href="https://www.adminer.org/cs/extension/"%s>implementujte</a> metodu %s.',
16
'Too many unsuccessful logins, try again in %d minute(s).' => array('Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minutu.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minuty.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minut.'),
17
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnost hlavního hesla vypršela. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo stále.',
18
'Language' => 'Jazyk',
@@ -21,6 +22,7 @@ $translations = array(
21
'No extension' => 'Žádné rozšíření',
22
'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).',
23
'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.',
24
'Session support must be enabled.' => 'Session proměnné musí být povolené.',
25
'Session expired, please login again.' => 'Session vypršela, přihlašte se prosím znovu.',
26
'The action will be performed after successful login with the same credentials.' => 'Akce bude provedena po úspěšném přihlášení se stejnými přihlašovacími údaji.',
@@ -53,6 +55,7 @@ $translations = array(
53
'Query executed OK, %d row(s) affected.' => array('Příkaz proběhl v pořádku, byl změněn %d záznam.', 'Příkaz proběhl v pořádku, byly změněny %d záznamy.', 'Příkaz proběhl v pořádku, bylo změněno %d záznamů.'),
54
'No commands to execute.' => 'Žádné příkazy k vykonání.',
55
'Error in query' => 'Chyba v dotazu',
56
'Warnings' => 'Varování',
57
'ATTACH queries are not supported.' => 'Dotazy ATTACH nejsou podporované.',
58
'Execute' => 'Provést',
10
'Logout' => 'Odhlásit',
11
'Logged as: %s' => 'Přihlášen jako: %s',
12
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
13
+ 'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Díky za použití Admineru, <a href="%s">příspějte</a> na vývoj.',
14
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
15
+ 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje přístup k databázi bez hesla, <a href="https://www.adminer.org/cs/password/"%s>více informací</a>.',
16
+ 'Database does not support password.' => 'Databáze nepodporuje heslo.',
17
'Too many unsuccessful logins, try again in %d minute(s).' => array('Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minutu.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minuty.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minut.'),
18
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnost hlavního hesla vypršela. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo stále.',
19
'Language' => 'Jazyk',
22
'No extension' => 'Žádné rozšíření',
23
'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).',
24
'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.',
25
+ 'Disable %s or enable %s or %s extensions.' => 'Zakažte %s nebo povolte extenze %s nebo %s.',
26
'Session support must be enabled.' => 'Session proměnné musí být povolené.',
27
'Session expired, please login again.' => 'Session vypršela, přihlašte se prosím znovu.',
28
'The action will be performed after successful login with the same credentials.' => 'Akce bude provedena po úspěšném přihlášení se stejnými přihlašovacími údaji.',
55
'Query executed OK, %d row(s) affected.' => array('Příkaz proběhl v pořádku, byl změněn %d záznam.', 'Příkaz proběhl v pořádku, byly změněny %d záznamy.', 'Příkaz proběhl v pořádku, bylo změněno %d záznamů.'),
56
'No commands to execute.' => 'Žádné příkazy k vykonání.',
57
'Error in query' => 'Chyba v dotazu',
58
+ 'Unknown error.' => 'Neznámá chyba.',
59
'Warnings' => 'Varování',
60
'ATTACH queries are not supported.' => 'Dotazy ATTACH nejsou podporované.',
61
'Execute' => 'Provést',
adminer/adminer/adminer/lang/he.inc.php CHANGED
@@ -276,7 +276,6 @@ $translations = array(
276
'ATTACH queries are not supported.' => 'שאילתת ATTACH אינה נתמכת',
277
'%d / ' => '%d / ',
278
'Limit rows' => 'הגבל שורות',
279
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>התקן</a> את תוסף SQLite בשביל להתחבר',
280
'Default value' => 'ערך ברירת מחדל',
281
'Full table scan' => 'סריקה טבלה מלאה',
282
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
276
'ATTACH queries are not supported.' => 'שאילתת ATTACH אינה נתמכת',
277
'%d / ' => '%d / ',
278
'Limit rows' => 'הגבל שורות',
279
'Default value' => 'ערך ברירת מחדל',
280
'Full table scan' => 'סריקה טבלה מלאה',
281
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
adminer/adminer/adminer/lang/ms.inc.php CHANGED
@@ -12,7 +12,6 @@ $translations = array(
12
'Logout successful.' => 'Log keluar berjaya.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="%s">menderma</a>.',
14
'Invalid credentials.' => 'Akses tidak sah.',
15
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk menggunakan SQLite.',
16
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
17
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
18
'Language' => 'Bahasa',
12
'Logout successful.' => 'Log keluar berjaya.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="%s">menderma</a>.',
14
'Invalid credentials.' => 'Akses tidak sah.',
15
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
16
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
17
'Language' => 'Bahasa',
adminer/adminer/adminer/lang/pl.inc.php CHANGED
@@ -12,7 +12,6 @@ $translations = array(
12
'Logout successful.' => 'Wylogowano pomyślnie.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="%s">dotację</a>.',
14
'Invalid credentials.' => 'Nieprawidłowe dane logowania.',
15
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> metodę %s aby użyć SQLite.',
16
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
17
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
18
'Language' => 'Język',
12
'Logout successful.' => 'Wylogowano pomyślnie.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="%s">dotację</a>.',
14
'Invalid credentials.' => 'Nieprawidłowe dane logowania.',
15
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
16
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
17
'Language' => 'Język',
adminer/adminer/adminer/lang/ru.inc.php CHANGED
@@ -276,7 +276,6 @@ $translations = array(
276
'ATTACH queries are not supported.' => 'ATTACH-запросы не поддерживаются.',
277
'%d / ' => '%d / ',
278
'Limit rows' => 'Лимит строк',
279
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Реализуйте</a> метод %s, чтобы использовать SQLite.',
280
'Default value' => 'Значение по умолчанию',
281
'Full table scan' => 'Анализ полной таблицы',
282
'Too many unsuccessful logins, try again in %d minute(s).' => array('Слишком много неудачных попыток входа. Попробуйте снова через %d минуту.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минуты.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минут.'),
276
'ATTACH queries are not supported.' => 'ATTACH-запросы не поддерживаются.',
277
'%d / ' => '%d / ',
278
'Limit rows' => 'Лимит строк',
279
'Default value' => 'Значение по умолчанию',
280
'Full table scan' => 'Анализ полной таблицы',
281
'Too many unsuccessful logins, try again in %d minute(s).' => array('Слишком много неудачных попыток входа. Попробуйте снова через %d минуту.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минуты.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минут.'),
adminer/adminer/adminer/lang/tr.inc.php CHANGED
@@ -12,7 +12,6 @@ $translations = array(
12
'Logout successful.' => 'Oturum başarıyla sonlandı.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="%s">bağış yapmayı düşünün</a>.',
14
'Invalid credentials.' => 'Geçersiz kimlik bilgileri.',
15
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => 'SQLite kullanmak için <a href="https://www.adminer.org/en/extension/"%s>%s metodunu</a> kullanın.',
16
'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'),
17
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.',
18
'Language' => 'Dil',
12
'Logout successful.' => 'Oturum başarıyla sonlandı.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="%s">bağış yapmayı düşünün</a>.',
14
'Invalid credentials.' => 'Geçersiz kimlik bilgileri.',
15
'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'),
16
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.',
17
'Language' => 'Dil',
adminer/adminer/adminer/lang/xx.inc.php CHANGED
@@ -12,7 +12,8 @@ $translations = array(
12
'Logout successful.' => 'Xx.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Xx <a href="%s">xx</a>.',
14
'Invalid credentials.' => 'Xx.',
15
- '<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
16
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
17
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
18
'Language' => 'Xx',
@@ -21,6 +22,7 @@ $translations = array(
21
'No extension' => 'Xx',
22
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
23
'Connecting to privileged ports is not allowed.' => 'Xx.',
24
'Session support must be enabled.' => 'Xx.',
25
'Session expired, please login again.' => 'Xx.',
26
'The action will be performed after successful login with the same credentials.' => 'Xx.',
@@ -53,6 +55,7 @@ $translations = array(
53
'Query executed OK, %d row(s) affected.' => array('Xx, %d.', 'Xx, %d.'),
54
'No commands to execute.' => 'Xx.',
55
'Error in query' => 'Xx',
56
'Warnings' => 'Xx',
57
'ATTACH queries are not supported.' => 'Xx.',
58
'Execute' => 'Xx',
12
'Logout successful.' => 'Xx.',
13
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Xx <a href="%s">xx</a>.',
14
'Invalid credentials.' => 'Xx.',
15
+ 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
16
+ 'Database does not support password.' => 'Xx.',
17
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
18
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
19
'Language' => 'Xx',
22
'No extension' => 'Xx',
23
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
24
'Connecting to privileged ports is not allowed.' => 'Xx.',
25
+ 'Disable %s or enable %s or %s extensions.' => 'Xx %s xx %s xx %s xx.',
26
'Session support must be enabled.' => 'Xx.',
27
'Session expired, please login again.' => 'Xx.',
28
'The action will be performed after successful login with the same credentials.' => 'Xx.',
55
'Query executed OK, %d row(s) affected.' => array('Xx, %d.', 'Xx, %d.'),
56
'No commands to execute.' => 'Xx.',
57
'Error in query' => 'Xx',
58
+ 'Unknown error.' => 'Xx.',
59
'Warnings' => 'Xx',
60
'ATTACH queries are not supported.' => 'Xx.',
61
'Execute' => 'Xx',
adminer/adminer/adminer/privileges.inc.php CHANGED
@@ -15,7 +15,7 @@ hidden_fields_get();
15
echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
16
echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
17
echo "<table cellspacing='0'>\n";
18
- echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th>&nbsp;</thead>\n";
19
20
while ($row = $result->fetch_assoc()) {
21
echo '<tr' . odd() . '><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n";
15
echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
16
echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
17
echo "<table cellspacing='0'>\n";
18
+ echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n";
19
20
while ($row = $result->fetch_assoc()) {
21
echo '<tr' . odd() . '><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n";
adminer/adminer/adminer/processlist.inc.php CHANGED
@@ -21,7 +21,7 @@ $i = -1;
21
foreach (process_list() as $i => $row) {
22
23
if (!$i) {
24
- echo "<thead><tr lang='en'>" . (support("kill") ? "<th>&nbsp;" : "");
25
foreach ($row as $key => $val) {
26
echo "<th>$key" . doc_link(array(
27
'sql' => "show-processlist.html#processlist_" . strtolower($key),
@@ -38,7 +38,7 @@ foreach (process_list() as $i => $row) {
38
($jush == "pgsql" && $key == "current_query" && $val != "<IDLE>") ||
39
($jush == "oracle" && $key == "sql_text" && $val != "")
40
? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Clone') . '</a>'
41
- : nbsp($val)
42
);
43
}
44
echo "\n";
21
foreach (process_list() as $i => $row) {
22
23
if (!$i) {
24
+ echo "<thead><tr lang='en'>" . (support("kill") ? "<th>" : "");
25
foreach ($row as $key => $val) {
26
echo "<th>$key" . doc_link(array(
27
'sql' => "show-processlist.html#processlist_" . strtolower($key),
38
($jush == "pgsql" && $key == "current_query" && $val != "<IDLE>") ||
39
($jush == "oracle" && $key == "sql_text" && $val != "")
40
? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Clone') . '</a>'
41
+ : h($val)
42
);
43
}
44
echo "\n";
adminer/adminer/adminer/script.inc.php CHANGED
@@ -4,10 +4,10 @@ header("Content-Type: text/javascript; charset=utf-8");
4
if ($_GET["script"] == "db") {
5
$sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0);
6
foreach (table_status() as $name => $table_status) {
7
- json_row("Comment-$name", nbsp($table_status["Comment"]));
8
if (!is_view($table_status)) {
9
foreach (array("Engine", "Collation") as $key) {
10
- json_row("$key-$name", nbsp($table_status[$key]));
11
}
12
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
13
if ($table_status[$key] != "") {
4
if ($_GET["script"] == "db") {
5
$sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0);
6
foreach (table_status() as $name => $table_status) {
7
+ json_row("Comment-$name", h($table_status["Comment"]));
8
if (!is_view($table_status)) {
9
foreach (array("Engine", "Collation") as $key) {
10
+ json_row("$key-$name", h($table_status[$key]));
11
}
12
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
13
if ($table_status[$key] != "") {
adminer/adminer/adminer/select.inc.php CHANGED
@@ -184,7 +184,7 @@ if ($_POST && !$error) {
184
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
185
$result = true;
186
$cols = array_keys($fields);
187
- preg_match_all('~(?>"[^"]*"|[^"\\r\\n]+)+~', $file, $matches);
188
$affected = count($matches[0]);
189
$driver->begin();
190
$separator = ($_POST["separator"] == "csv" ? "," : ($_POST["separator"] == "tsv" ? "\t" : ";"));
@@ -369,7 +369,7 @@ if (!$columns && support("table")) {
369
if (!$unique_array) {
370
$unique_array = array();
371
foreach ($rows[$n] as $key => $val) {
372
- if (!preg_match('~^(COUNT\\((\\*|(DISTINCT )?`(?:[^`]|``)+`)\\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\\(`(?:[^`]|``)+`\\))$~', $key)) { //! columns looking like functions
373
$unique_array[$key] = $val;
374
}
375
}
@@ -407,9 +407,9 @@ if (!$columns && support("table")) {
407
foreach ($foreign_key["source"] as $i => $source) {
408
$link .= where_link($i, $foreign_key["target"][$i], $rows[$n][$source]);
409
}
410
- $link = ($foreign_key["db"] != "" ? preg_replace('~([?&]db=)[^&]+~', '\\1' . urlencode($foreign_key["db"]), ME) : ME) . 'select=' . urlencode($foreign_key["table"]) . $link; // InnoDB supports non-UNIQUE keys
411
if ($foreign_key["ns"]) {
412
- $link = preg_replace('~([?&]ns=)[^&]+~', '\\1' . urlencode($foreign_key["ns"]), $link);
413
}
414
if (count($foreign_key["source"]) == 1) {
415
break;
184
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
185
$result = true;
186
$cols = array_keys($fields);
187
+ preg_match_all('~(?>"[^"]*"|[^"\r\n]+)+~', $file, $matches);
188
$affected = count($matches[0]);
189
$driver->begin();
190
$separator = ($_POST["separator"] == "csv" ? "," : ($_POST["separator"] == "tsv" ? "\t" : ";"));
369
if (!$unique_array) {
370
$unique_array = array();
371
foreach ($rows[$n] as $key => $val) {
372
+ if (!preg_match('~^(COUNT\((\*|(DISTINCT )?`(?:[^`]|``)+`)\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\(`(?:[^`]|``)+`\))$~', $key)) { //! columns looking like functions
373
$unique_array[$key] = $val;
374
}
375
}
407
foreach ($foreign_key["source"] as $i => $source) {
408
$link .= where_link($i, $foreign_key["target"][$i], $rows[$n][$source]);
409
}
410
+ $link = ($foreign_key["db"] != "" ? preg_replace('~([?&]db=)[^&]+~', '\1' . urlencode($foreign_key["db"]), ME) : ME) . 'select=' . urlencode($foreign_key["table"]) . $link; // InnoDB supports non-UNIQUE keys
411
if ($foreign_key["ns"]) {
412
+ $link = preg_replace('~([?&]ns=)[^&]+~', '\1' . urlencode($foreign_key["ns"]), $link);
413
}
414
if (count($foreign_key["source"]) == 1) {
415
break;
adminer/adminer/adminer/sql.inc.php CHANGED
@@ -56,7 +56,7 @@ if (!$error && $_POST) {
56
}
57
$commands = 0;
58
$errors = array();
59
- $parse = '[\'"' . ($jush == "sql" ? '`#' : ($jush == "sqlite" ? '`[' : ($jush == "mssql" ? '[' : ''))) . ']|/\\*|-- |#x27; . ($jush == "pgsql" ? '|\\$[^$]*\\#x27; : '');
60
$total_start = microtime(true);
61
parse_str($_COOKIE["adminer_export"], $adminer_export);
62
$dump_format = $adminer->dumpFormat();
@@ -78,7 +78,7 @@ if (!$error && $_POST) {
78
$offset = $pos + strlen($found);
79
80
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end
81
- while (preg_match('(' . ($found == '/*' ? '\\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES
82
$s = $match[0][0];
83
if (!$s && $fp && !feof($fp)) {
84
$query .= fread($fp, 1e5);
@@ -225,13 +225,14 @@ if (!isset($_GET["import"])) {
225
226
} else {
227
echo "<fieldset><legend>" . lang('File upload') . "</legend><div>";
228
echo (ini_bool("file_uploads")
229
- ? "SQL (&lt; " . ini_get("upload_max_filesize") . "B): <input type='file' name='sql_file[]' multiple>\n$execute" // ignore post_max_size because it is for all form fields together and bytes computing would be necessary
230
: lang('File uploads are disabled.')
231
);
232
echo "</div></fieldset>\n";
233
echo "<fieldset><legend>" . lang('From server') . "</legend><div>";
234
- echo lang('Webserver file %s', "<code>" . h($adminer->importServerPath()) . (extension_loaded("zlib") ? "[.gz]" : "") . "</code>");
235
echo ' <input type="submit" name="webfile" value="' . lang('Run file') . '">';
236
echo "</div></fieldset>\n";
237
echo "<p>";
56
}
57
$commands = 0;
58
$errors = array();
59
+ $parse = '[\'"' . ($jush == "sql" ? '`#' : ($jush == "sqlite" ? '`[' : ($jush == "mssql" ? '[' : ''))) . ']|/\*|-- |#x27; . ($jush == "pgsql" ? '|\$[^$]*\#x27; : '');
60
$total_start = microtime(true);
61
parse_str($_COOKIE["adminer_export"], $adminer_export);
62
$dump_format = $adminer->dumpFormat();
78
$offset = $pos + strlen($found);
79
80
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end
81
+ while (preg_match('(' . ($found == '/*' ? '\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES
82
$s = $match[0][0];
83
if (!$s && $fp && !feof($fp)) {
84
$query .= fread($fp, 1e5);
225
226
} else {
227
echo "<fieldset><legend>" . lang('File upload') . "</legend><div>";
228
+ $gz = (extension_loaded("zlib") ? "[.gz]" : "");
229
echo (ini_bool("file_uploads")
230
+ ? "SQL$gz (&lt; " . ini_get("upload_max_filesize") . "B): <input type='file' name='sql_file[]' multiple>\n$execute" // ignore post_max_size because it is for all form fields together and bytes computing would be necessary
231
: lang('File uploads are disabled.')
232
);
233
echo "</div></fieldset>\n";
234
echo "<fieldset><legend>" . lang('From server') . "</legend><div>";
235
+ echo lang('Webserver file %s', "<code>" . h($adminer->importServerPath()) . "$gz</code>");
236
echo ' <input type="submit" name="webfile" value="' . lang('Run file') . '">';
237
echo "</div></fieldset>\n";
238
echo "<p>";
adminer/adminer/adminer/sqlite.php CHANGED
@@ -1,8 +1,11 @@
1
<?php
2
function adminer_object() {
3
include_once "../plugins/plugin.php";
4
- include_once "../plugins/login-sqlite.php";
5
- return new AdminerPlugin(array(new AdminerLoginSqlite("admin", password_hash("", PASSWORD_DEFAULT))));
6
}
7
8
include "./index.php";
1
<?php
2
function adminer_object() {
3
include_once "../plugins/plugin.php";
4
+ include_once "../plugins/login-password-less.php";
5
+ return new AdminerPlugin(array(
6
+ // TODO: inline the result of password_hash() so that the password is not visible in source codes
7
+ new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
8
+ ));
9
}
10
11
include "./index.php";
adminer/adminer/adminer/static/editing.js CHANGED
@@ -395,8 +395,7 @@ function editingLengthFocus() {
395
var td = this.parentNode;
396
if (/(enum|set)#x2F;.test(selectValue(td.previousSibling.firstChild))) {
397
var edit = qs('#enum-edit');
398
- var val = this.value;
399
- edit.value = (/^'.+'#x2F;.test(val) ? val.substr(1, val.length - 2).replace(/','/g, "\n").replace(/''/g, "'") : val); //! doesn't handle 'a'',''b' correctly
400
td.appendChild(edit);
401
this.style.display = 'none';
402
edit.style.display = 'inline';
@@ -404,13 +403,32 @@ function editingLengthFocus() {
404
}
405
}
406
407
/** Finish editing of enum or set
408
* @this HTMLTextAreaElement
409
*/
410
function editingLengthBlur() {
411
var field = this.parentNode.firstChild;
412
var val = this.value;
413
- field.value = (/^'[^\n]+'#x2F;.test(val) ? val : val && "'" + val.replace(/\n+#x2F;, '').replace(/'/g, "''").replace(/\n/g, "','") + "'");
414
field.style.display = 'inline';
415
this.style.display = 'none';
416
}
395
var td = this.parentNode;
396
if (/(enum|set)#x2F;.test(selectValue(td.previousSibling.firstChild))) {
397
var edit = qs('#enum-edit');
398
+ edit.value = enumValues(this.value);
399
td.appendChild(edit);
400
this.style.display = 'none';
401
edit.style.display = 'inline';
403
}
404
}
405
406
+ /** Get enum values
407
+ * @param string
408
+ * @return string values separated by newlines
409
+ */
410
+ function enumValues(s) {
411
+ var re = /(^|,)\s*'(([^\\']|\\.|'')*)'\s*/g;
412
+ var result = [];
413
+ var offset = 0;
414
+ var match;
415
+ while (match = re.exec(s)) {
416
+ if (offset != match.index) {
417
+ break;
418
+ }
419
+ result.push(match[2].replace(/'(')|\\(.)/g, '$1$2'));
420
+ offset += match[0].length;
421
+ }
422
+ return (offset == s.length ? result.join('\n') : s);
423
+ }
424
+
425
/** Finish editing of enum or set
426
* @this HTMLTextAreaElement
427
*/
428
function editingLengthBlur() {
429
var field = this.parentNode.firstChild;
430
var val = this.value;
431
+ field.value = (/^'[^\n]+'#x2F;.test(val) ? val : val && "'" + val.replace(/\n+#x2F;, '').replace(/'/g, "''").replace(/\\/g, '\\\\').replace(/\n/g, "','") + "'");
432
field.style.display = 'inline';
433
this.style.display = 'none';
434
}
adminer/adminer/adminer/static/functions.js CHANGED
@@ -205,14 +205,9 @@ function formCheck(name) {
205
/** Check all rows in <table class="checkable">
206
*/
207
function tableCheck() {
208
- var tables = qsa('table', document);
209
- for (var i=0; i < tables.length; i++) {
210
- if (/(^|\s)checkable(\s|$)/.test(tables[i].className)) {
211
- var trs = qsa('tr', tables[i]);
212
- for (var j=0; j < trs.length; j++) {
213
- trCheck(trs[j].firstChild.firstChild);
214
- }
215
- }
216
}
217
}
218
@@ -319,13 +314,13 @@ function checkboxClick(event) {
319
320
/** Set HTML code of an element
321
* @param string
322
- * @param string undefined to set parentNode to &nbsp;
323
*/
324
function setHtml(id, html) {
325
- var el = qs('#' + id);
326
if (el) {
327
if (html == null) {
328
- el.parentNode.innerHTML = '&nbsp;';
329
} else {
330
el.innerHTML = html;
331
}
@@ -716,7 +711,7 @@ function selectClick(event, text, warning) {
716
});
717
input.rows = rows;
718
}
719
- if (value == '\u00A0' || qsa('i', td).length) { // &nbsp; or i - NULL
720
value = '';
721
}
722
if (document.selection) {
205
/** Check all rows in <table class="checkable">
206
*/
207
function tableCheck() {
208
+ var inputs = qsa('table.checkable td:first-child input', document);
209
+ for (var i=0; i < inputs.length; i++) {
210
+ trCheck(inputs[i]);
211
}
212
}
213
314
315
/** Set HTML code of an element
316
* @param string
317
+ * @param string undefined to set parentNode to empty string
318
*/
319
function setHtml(id, html) {
320
+ var el = qs('[id="' + id.replace(/[\\"]/g, '\\amp;') + '"]'); // database name is used as ID
321
if (el) {
322
if (html == null) {
323
+ el.parentNode.innerHTML = '';
324
} else {
325
el.innerHTML = html;
326
}
711
});
712
input.rows = rows;
713
}
714
+ if (qsa('i', td).length) { // <i> - NULL
715
value = '';
716
}
717
if (document.selection) {
adminer/adminer/adminer/table.inc.php CHANGED
@@ -34,7 +34,7 @@ if (!is_view($table_status)) {
34
$foreign_keys = foreign_keys($TABLE);
35
if ($foreign_keys) {
36
echo "<table cellspacing='0'>\n";
37
- echo "<thead><tr><th>" . lang('Source') . "<td>" . lang('Target') . "<td>" . lang('ON DELETE') . "<td>" . lang('ON UPDATE') . "<td>&nbsp;</thead>\n";
38
foreach ($foreign_keys as $name => $foreign_key) {
39
echo "<tr title='" . h($name) . "'>";
40
echo "<th><i>" . implode("</i>, <i>", array_map('h', $foreign_key["source"])) . "</i>";
@@ -43,8 +43,8 @@ if (!is_view($table_status)) {
43
. "</a>"
44
;
45
echo "(<i>" . implode("</i>, <i>", array_map('h', $foreign_key["target"])) . "</i>)";
46
- echo "<td>" . nbsp($foreign_key["on_delete"]) . "\n";
47
- echo "<td>" . nbsp($foreign_key["on_update"]) . "\n";
48
echo '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>';
49
}
50
echo "</table>\n";
34
$foreign_keys = foreign_keys($TABLE);
35
if ($foreign_keys) {
36
echo "<table cellspacing='0'>\n";
37
+ echo "<thead><tr><th>" . lang('Source') . "<td>" . lang('Target') . "<td>" . lang('ON DELETE') . "<td>" . lang('ON UPDATE') . "<td></thead>\n";
38
foreach ($foreign_keys as $name => $foreign_key) {
39
echo "<tr title='" . h($name) . "'>";
40
echo "<th><i>" . implode("</i>, <i>", array_map('h', $foreign_key["source"])) . "</i>";
43
. "</a>"
44
;
45
echo "(<i>" . implode("</i>, <i>", array_map('h', $foreign_key["target"])) . "</i>)";
46
+ echo "<td>" . h($foreign_key["on_delete"]) . "\n";
47
+ echo "<td>" . h($foreign_key["on_update"]) . "\n";
48
echo '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>';
49
}
50
echo "</table>\n";
adminer/adminer/adminer/user.inc.php CHANGED
@@ -29,7 +29,7 @@ $old_pass = "";
29
30
if (isset($_GET["host"]) && ($result = $connection->query("SHOW GRANTS FOR " . q($USER) . "@" . q($_GET["host"])))) { //! use information_schema for MySQL 5 - column names in column privileges are not escaped
31
while ($row = $result->fetch_row()) {
32
- if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match) && preg_match_all('~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~', $match[1], $matches, PREG_SET_ORDER)) { //! escape the part between ON and TO
33
foreach ($matches as $val) {
34
if ($val[1] != "USAGE") {
35
$grants["$match[2]$val[2]"][$val[1]] = true;
@@ -84,7 +84,7 @@ if ($_POST && !$error) {
84
$grant = array_diff($grant, $old_grant);
85
unset($grants[$object]);
86
}
87
- if (preg_match('~^(.+)\\s*(\\(.*\\))?$~U', $object, $match) && (
88
!grant("REVOKE", $revoke, $match[2], " ON $match[1] FROM $new_user") //! SQL injection
89
|| !grant("GRANT", $grant, $match[2], " ON $match[1] TO $new_user")
90
)) {
@@ -99,7 +99,7 @@ if ($_POST && !$error) {
99
queries("DROP USER $old_user");
100
} elseif (!isset($_GET["grant"])) {
101
foreach ($grants as $object => $revoke) {
102
- if (preg_match('~^(.+)(\\(.*\\))?$~U', $object, $match)) {
103
grant("REVOKE", array_keys($revoke), $match[2], " ON $match[1] FROM $new_user");
104
}
105
}
@@ -165,7 +165,7 @@ foreach (array(
165
$name = "'grants[$i][" . h(strtoupper($privilege)) . "]'";
166
$value = $grant[strtoupper($privilege)];
167
if ($context == "Server Admin" && $object != (isset($grants["*.*"]) ? "*.*" : ".*")) {
168
- echo "<td>&nbsp;";
169
} elseif (isset($_GET["grant"])) {
170
echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>";
171
} else {
29
30
if (isset($_GET["host"]) && ($result = $connection->query("SHOW GRANTS FOR " . q($USER) . "@" . q($_GET["host"])))) { //! use information_schema for MySQL 5 - column names in column privileges are not escaped
31
while ($row = $result->fetch_row()) {
32
+ if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match) && preg_match_all('~ *([^(,]*[^ ,(])( *\([^)]+\))?~', $match[1], $matches, PREG_SET_ORDER)) { //! escape the part between ON and TO
33
foreach ($matches as $val) {
34
if ($val[1] != "USAGE") {
35
$grants["$match[2]$val[2]"][$val[1]] = true;
84
$grant = array_diff($grant, $old_grant);
85
unset($grants[$object]);
86
}
87
+ if (preg_match('~^(.+)\s*(\(.*\))?$~U', $object, $match) && (
88
!grant("REVOKE", $revoke, $match[2], " ON $match[1] FROM $new_user") //! SQL injection
89
|| !grant("GRANT", $grant, $match[2], " ON $match[1] TO $new_user")
90
)) {
99
queries("DROP USER $old_user");
100
} elseif (!isset($_GET["grant"])) {
101
foreach ($grants as $object => $revoke) {
102
+ if (preg_match('~^(.+)(\(.*\))?$~U', $object, $match)) {
103
grant("REVOKE", array_keys($revoke), $match[2], " ON $match[1] FROM $new_user");
104
}
105
}
165
$name = "'grants[$i][" . h(strtoupper($privilege)) . "]'";
166
$value = $grant[strtoupper($privilege)];
167
if ($context == "Server Admin" && $object != (isset($grants["*.*"]) ? "*.*" : ".*")) {
168
+ echo "<td>";
169
} elseif (isset($_GET["grant"])) {
170
echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>";
171
} else {
adminer/adminer/adminer/variables.inc.php CHANGED
@@ -10,7 +10,7 @@ if (!$variables) {
10
foreach ($variables as $key => $val) {
11
echo "<tr>";
12
echo "<th><code class='jush-" . $jush . ($status ? "status" : "set") . "'>" . h($key) . "</code>";
13
- echo "<td>" . nbsp($val);
14
}
15
echo "</table>\n";
16
}
10
foreach ($variables as $key => $val) {
11
echo "<tr>";
12
echo "<th><code class='jush-" . $jush . ($status ? "status" : "set") . "'>" . h($key) . "</code>";
13
+ echo "<td>" . h($val);
14
}
15
echo "</table>\n";
16
}
adminer/adminer/editor/include/adminer.inc.php CHANGED
@@ -71,17 +71,18 @@ class Adminer {
71
}
72
73
function loginForm() {
74
- ?>
75
- <table cellspacing="0">
76
- <tr><th><?php echo lang('Username'); ?><td><input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
77
- <tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
78
- </table>
79
- <?php
80
- echo script("focus(qs('#username'));");
81
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
82
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
83
}
84
85
function login($login, $password) {
86
return true;
87
}
@@ -189,7 +190,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
189
}
190
191
function selectVal($val, $link, $field, $original) {
192
- $return = ($val === null ? "&nbsp;" : $val);
193
$link = h($link);
194
if (preg_match('~blob|bytea~', $field["type"]) && !is_utf8($val)) {
195
$return = lang('%d byte(s)', strlen($original));
@@ -197,7 +198,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
197
$return = "<img src='$link' alt='$return'>";
198
}
199
}
200
- if (like_bool($field) && $return != "&nbsp;") { // bool
201
$return = (preg_match('~^(1|t|true|y|yes|on)$~i', $val) ? lang('yes') : lang('no'));
202
}
203
if ($link) {
@@ -213,7 +214,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
213
214
function editVal($val, $field) {
215
if (preg_match('~date|timestamp~', $field["type"]) && $val !== null) {
216
- return preg_replace('~^(\\d{2}(\\d+))-(0?(\\d+))-(0?(\\d+))~', lang('$1-$3-$5'), $val);
217
}
218
return $val;
219
}
@@ -418,7 +419,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
418
$field = idf_escape($_POST["email_field"]);
419
$subject = $_POST["email_subject"];
420
$message = $_POST["email_message"];
421
- preg_match_all('~\\{\\$([a-z0-9_]+)\\}~i', "$subject.$message", $matches); // allows {$name} in subject or message
422
$rows = get_rows("SELECT DISTINCT $field" . ($matches[1] ? ", " . implode(", ", array_map('idf_escape', array_unique($matches[1]))) : "") . " FROM " . table($_GET["select"])
423
. " WHERE $field IS NOT NULL AND $field != ''"
424
. ($where ? " AND " . implode(" AND ", $where) : "")
@@ -484,7 +485,7 @@ qsl('div').onclick = whisperClick;", "")
484
);
485
}
486
if (like_bool($field)) {
487
- return '<input type="checkbox" value="' . h($value ? $value : 1) . '"' . ($value ? ' checked' : '') . "$attrs>";
488
}
489
$hint = "";
490
if (preg_match('~time~', $field["type"])) {
@@ -511,7 +512,7 @@ qsl('div').onclick = whisperClick;", "")
511
return "$function()";
512
}
513
$return = $value;
514
- if (preg_match('~date|timestamp~', $field["type"]) && preg_match('(^' . str_replace('\\$1', '(?P<p1>\\d*)', preg_replace('~(\\\\\\$([2-6]))~', '(?P<p\\2>\\d{1,2})', preg_quote(lang('$1-$3-$5')))) . '(.*))', $value, $match)) {
515
$return = ($match["p1"] != "" ? $match["p1"] : ($match["p2"] != "" ? ($match["p2"] < 70 ? 20 : 19) . $match["p2"] : gmdate("Y"))) . "-$match[p3]$match[p4]-$match[p5]$match[p6]" . end($match);
516
}
517
$return = ($field["type"] == "bit" && preg_match('~^[0-9]+$~', $value) ? $return : q($return));
71
}
72
73
function loginForm() {
74
+ echo "<table cellspacing='0'>\n";
75
+ echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocapitalize="off">' . script("focus(qs('#username'));"));
76
+ echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]">' . "\n");
77
+ echo "</table>\n";
78
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
79
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
80
}