diff --git a/adminer/database.inc.php b/adminer/database.inc.php index eb9f6ac3..87f31dd7 100644 --- a/adminer/database.inc.php +++ b/adminer/database.inc.php @@ -28,7 +28,7 @@ if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP c if (!$_POST["collation"]) { redirect(substr(ME, 0, -1)); } - query_redirect("ALTER DATABASE " . idf_escape($_POST["name"]) . " COLLATE $_POST[collation]", substr(ME, 0, -1), lang('Database has been altered.')); //! SQL injection - quotes are not allowed in MS SQL 2005 + query_redirect("ALTER DATABASE " . idf_escape($_POST["name"]) . (eregi('^[a-z0-9_]+$', $_POST["collation"]) ? " COLLATE $_POST[collation]" : ""), substr(ME, 0, -1), lang('Database has been altered.')); } } diff --git a/adminer/db.inc.php b/adminer/db.inc.php index 20944c96..b433c49f 100644 --- a/adminer/db.inc.php +++ b/adminer/db.inc.php @@ -154,7 +154,9 @@ if ($_GET["ns"] !== "") { echo '

' . lang('Create event') . "\n"; } - page_footer(); - echo "\n"; - exit; // page_footer() already called + if ($tables_list) { + page_footer(); + echo "\n"; + exit; // page_footer() already called + } } diff --git a/adminer/drivers/mssql.inc.php b/adminer/drivers/mssql.inc.php index 5d850a36..de3114bd 100644 --- a/adminer/drivers/mssql.inc.php +++ b/adminer/drivers/mssql.inc.php @@ -383,7 +383,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table) } function create_database($db, $collation) { - return queries("CREATE DATABASE " . idf_escape($db) . ($collation ? " COLLATE $collation" : "")); + return queries("CREATE DATABASE " . idf_escape($db) . (eregi('^[a-z0-9_]+$', $collation) ? " COLLATE $collation" : "")); } function drop_databases($databases) { @@ -391,7 +391,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table) } function rename_database($name, $collation) { - if ($collation) { + if (eregi('^[a-z0-9_]+$', $collation)) { queries("ALTER DATABASE " . idf_escape(DB) . " COLLATE $collation"); } queries("ALTER DATABASE " . idf_escape(DB) . " MODIFY NAME = " . idf_escape($name)); diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index 6398aa45..2cc9a0a3 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -22,11 +22,11 @@ if (isset($_GET["pgsql"])) { function connect($server, $username, $password) { set_error_handler(array($this, '_error')); $this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'"; - $this->_link = @pg_connect($this->_string . (DB != "" ? " dbname='" . addcslashes(DB, "'\\") . "'" : ""), PGSQL_CONNECT_FORCE_NEW); + $this->_link = @pg_connect($this->_string . (DB != "" ? " dbname='" . addcslashes(DB, "'\\") . "'" : " dbname='template1'"), PGSQL_CONNECT_FORCE_NEW); if (!$this->_link && DB != "") { // try to connect directly with database for performance $this->_database = false; - $this->_link = @pg_connect($this->_string, PGSQL_CONNECT_FORCE_NEW); + $this->_link = @pg_connect("$this->_string dbname='template1'", PGSQL_CONNECT_FORCE_NEW); } restore_error_handler(); if ($this->_link) { @@ -53,7 +53,7 @@ if (isset($_GET["pgsql"])) { } function close() { - $this->_link = @pg_connect($this->_string); + $this->_link = @pg_connect("$this->_string dbname='template1'"); } function query($query, $unbuffered = false) { diff --git a/adminer/drivers/sqlite.inc.php b/adminer/drivers/sqlite.inc.php index 89ce2f15..5418ac6c 100644 --- a/adminer/drivers/sqlite.inc.php +++ b/adminer/drivers/sqlite.inc.php @@ -344,13 +344,27 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) { function exact_value($val) { return q($val); } - + + function check_sqlite_name($name) { + // avoid creating PHP files on unsecured servers + global $connection; + $extensions = "db|sdb|sqlite"; + if (!preg_match("~^[^\\0]*\\.($extensions)\$~", $name)) { + $connection->error = lang('Please use one of the extensions %s.', str_replace("|", ", ", $extensions)); + return false; + } + return true; + } + function create_database($db, $collation) { global $connection; if (file_exists($db)) { $connection->error = lang('File exists.'); return false; } + if (!check_sqlite_name($db)) { + return false; + } $link = new Min_SQLite($db); //! exception handler $link->query('PRAGMA encoding = "UTF-8"'); $link->query('CREATE TABLE adminer (i)'); // otherwise creates empty file @@ -372,6 +386,9 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) { function rename_database($name, $collation) { global $connection; + if (!check_sqlite_name($name)) { + return false; + } $connection->Min_SQLite(":memory:"); $connection->error = lang('File exists.'); return @rename(DB, $name); diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index c47519f3..2944c9cd 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -32,6 +32,13 @@ class Adminer { return DB; } + /** Headers to send before HTML output + * @return null + */ + function headers() { + header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox NoScript plugin + } + /** Print login form * @return null */ @@ -484,7 +491,7 @@ document.getElementById('username').focus(); } /** Prints navigation after Adminer title - * @param string can be "auth" if there is no database connection or "db" if there is no database selected + * @param string can be "auth" if there is no database connection, "db" if there is no database selected, "ns" with invalid schema * @return null */ function navigation($missing) { @@ -516,10 +523,14 @@ document.getElementById('username').focus(); ?>

- - -"> - +" . bold(lang('SQL command'), isset($_GET["sql"])) . "\n"; + if (support("dump")) { + echo "" . bold(lang('Dump'), isset($_GET["dump"])) . "\n"; + } +} +?>

@@ -537,7 +548,7 @@ document.getElementById('username').focus(); set_schema($_GET["ns"]); } } - if ($_GET["ns"] !== "") { + if ($_GET["ns"] !== "" && !$missing) { $tables = tables_list(); if (!$tables) { echo "

" . lang('No tables.') . "\n"; diff --git a/adminer/include/connect.inc.php b/adminer/include/connect.inc.php index 242f1a89..1f58a6ef 100644 --- a/adminer/include/connect.inc.php +++ b/adminer/include/connect.inc.php @@ -6,7 +6,6 @@ function connect_error() { page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true); } else { if ($_POST["db"] && !$error) { - set_session("dbs", null); queries_redirect(substr(ME, 0, -1), lang('Databases have been dropped.'), drop_databases($_POST["db"])); } @@ -26,6 +25,7 @@ function connect_error() { echo "

" . lang('Logged as: %s', "" . h(logged_user()) . "") . "\n"; $databases = get_databases(); if ($databases) { + $scheme = support("scheme"); $collations = collations(); echo "\n"; echo "\n"; @@ -34,7 +34,7 @@ function connect_error() { $root = h(ME) . "db=" . urlencode($db); echo "
" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"])); echo "" . h($db) . ""; - echo "" . nbsp(db_collation($db, $collations)) . ""; + echo "" . nbsp(db_collation($db, $collations)) . ""; echo "?"; echo "\n"; } @@ -44,7 +44,9 @@ function connect_error() { } } page_footer("db"); - echo "\n"; + if ($databases) { + echo "\n"; + } } if (isset($_GET["status"])) { @@ -58,6 +60,13 @@ if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET exit; } -if (support("scheme") && DB != "" && $_GET["ns"] !== "" && (!isset($_GET["ns"]) || !set_schema($_GET["ns"]))) { - redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); +if (support("scheme") && DB != "" && $_GET["ns"] !== "") { + if (!isset($_GET["ns"])) { + redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); + } + if (!set_schema($_GET["ns"])) { + page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true); + page_footer("ns"); + exit; + } } diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php index 21301985..a7716bb7 100644 --- a/adminer/include/design.inc.php +++ b/adminer/include/design.inc.php @@ -9,7 +9,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { global $LANG, $HTTPS, $adminer, $connection, $drivers; header("Content-Type: text/html; charset=utf-8"); - header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox NoScript plugin + $adminer->headers(); if ($_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") { $title_all = $title . ($title2 != "" ? ": " . h($title2) : ""); $protocol = ($HTTPS ? "https" : "http"); @@ -76,7 +76,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { } /** Print HTML footer -* @param string auth|db +* @param string "auth", "db", "ns" * @return null */ function page_footer($missing = "") { diff --git a/adminer/lang/ca.inc.php b/adminer/lang/ca.inc.php index dbdb312b..6ba91fd4 100644 --- a/adminer/lang/ca.inc.php +++ b/adminer/lang/ca.inc.php @@ -62,7 +62,7 @@ $translations = array( 'Action' => 'Acció', 'edit' => 'edita', 'Page' => 'Plana', - 'Query executed OK, %d row(s) affected.' => array('Consulta executada correctament, %d fila modificada', 'Consulta executada correctament, %d files modificades'), + 'Query executed OK, %d row(s) affected.' => array('Consulta executada correctament, %d fila modificada.', 'Consulta executada correctament, %d files modificades.'), 'Error in query' => 'Error en la consulta', 'Execute' => 'Executa', 'Table' => 'Taula', @@ -78,14 +78,14 @@ $translations = array( 'Unable to upload a file.' => 'Impossible adjuntar el fitxer.', 'File upload' => 'Adjunta un fitxer', 'File uploads are disabled.' => 'L\'ddjunció de fitxers està desactivada.', - 'Routine has been called, %d row(s) affected.' => array('S\'ha cridat la rutina, %d fila modificada', 'S\'ha cridat la rutina, %d files modificades'), + 'Routine has been called, %d row(s) affected.' => array('S\'ha cridat la rutina, %d fila modificada.', 'S\'ha cridat la rutina, %d files modificades.'), 'Call' => 'Crida', 'No extension' => 'Cap extensió', 'None of the supported PHP extensions (%s) are available.' => 'No hi ha cap de les extensions PHP soporatades (%s) disponible.', 'Session support must be enabled.' => 'Cal que estigui permès l\'us de sessions.', 'Session expired, please login again.' => 'La sessió ha expirat, torna a iniciar-ne una.', 'Text length' => 'Longitud del text', - 'Foreign key has been dropped.' => 'S\'ha suprimit la clau forana', + 'Foreign key has been dropped.' => 'S\'ha suprimit la clau forana.', 'Foreign key has been altered.' => 'S\'ha modificat la clau forana.', 'Foreign key has been created.' => 'S\'ha creat la clau forana.', 'Foreign key' => 'Clau forana', @@ -120,9 +120,9 @@ $translations = array( 'Alter procedure' => 'Modifica el procediment', 'Return type' => 'Tipus retornat', 'Add trigger' => 'Afegeix un activador', - 'Trigger has been dropped.' => 'S\'ha suprimit l\'activador', - 'Trigger has been altered.' => 'S\'ha modificat l\'activador', - 'Trigger has been created.' => 'S\'ha creat l\'activador', + 'Trigger has been dropped.' => 'S\'ha suprimit l\'activador.', + 'Trigger has been altered.' => 'S\'ha modificat l\'activador.', + 'Trigger has been created.' => 'S\'ha creat l\'activador.', 'Alter trigger' => 'Modifica l\'activador', 'Create trigger' => 'Crea un activador', 'Time' => 'Temps', @@ -180,7 +180,7 @@ $translations = array( 'Tables have been truncated.' => 'S\'han escapçat les taules.', 'Rows' => 'Files', ',' => ',', - 'Tables have been moved.' => 'S\'han desplaçat les taules', + 'Tables have been moved.' => 'S\'han desplaçat les taules.', 'Move to other database' => 'Desplaça a una altra base de dades', 'Move' => 'Desplaça', 'Engine' => 'Motor', diff --git a/adminer/lang/cs.inc.php b/adminer/lang/cs.inc.php index 98b3e823..4c91e62a 100644 --- a/adminer/lang/cs.inc.php +++ b/adminer/lang/cs.inc.php @@ -25,6 +25,7 @@ $translations = array( 'Save' => 'Uložit', 'Drop' => 'Odstranit', 'Database has been dropped.' => 'Databáze byla odstraněna.', + 'Databases have been dropped.' => 'Databáze byly odstraněny.', 'Database has been created.' => 'Databáze byla vytvořena.', 'Database has been renamed.' => 'Databáze byla přejmenována.', 'Database has been altered.' => 'Databáze byla změněna.', @@ -40,7 +41,10 @@ $translations = array( 'Create new table' => 'Vytvořit novou tabulku', 'Item has been deleted.' => 'Položka byla smazána.', 'Item has been updated.' => 'Položka byla aktualizována.', + + // %s can contain auto-increment value 'Item%s has been inserted.' => 'Položka%s byla vložena.', + 'Edit' => 'Upravit', 'Insert' => 'Vložit', 'Save and insert next' => 'Uložit a vložit další', @@ -180,7 +184,7 @@ $translations = array( 'Tables have been truncated.' => 'Tabulky byly vyprázdněny.', 'Rows' => 'Řádků', ',' => ' ', - 'Tables have been moved.' => 'Tabulky byly přesunuty', + 'Tables have been moved.' => 'Tabulky byly přesunuty.', 'Move to other database' => 'Přesunout do jiné databáze', 'Move' => 'Přesunout', 'Engine' => 'Úložiště', @@ -227,16 +231,30 @@ $translations = array( 'File does not exist.' => 'Soubor neexistuje.', 'Permanent login' => 'Trvalé přihlášení', '%d in total' => '%d celkem', + + // label for e-mail attachments in Adminer Editor 'Attachments' => 'Přílohy', + + // label for database system selection (MySQL, SQLite, ...) 'System' => 'Systém', + + // link to last page if exact number is unknown 'last' => 'poslední', + + // new data type categories 'Network' => 'Síť', 'Geometry' => 'Geometrie', - 'Databases have been dropped.' => 'Databáze byly odstraněny.', + + // general SQLite error in create, drop or rename database 'File exists.' => 'Soubor existuje.', + 'Please use one of the extensions %s.' => 'Prosím použijte jednu z koncovek %s.', + + // selects now support in-place editing 'Double click on a value to modify it.' => 'Dvojklikněte na políčko, které chcete změnit.', 'Increase Text length to modify this value.' => 'Ke změně této hodnoty zvyšte Délku textů.', 'Use edit link to modify this value.' => 'Ke změně této hodnoty použijte odkaz upravit.', + + // PostgreSQL and MS SQL schema support 'Alter schema' => 'Pozměnit schéma', 'Create schema' => 'Vytvořit schéma', 'Schema has been dropped.' => 'Schéma bylo odstraněno.', @@ -244,19 +262,32 @@ $translations = array( 'Schema has been altered.' => 'Schéma bylo změněno.', 'schema' => 'schéma', 'Schema' => 'Schéma', + 'Invalid schema.' => 'Nesprávné schéma.', + + // PostgreSQL sequences support 'Sequences' => 'Sekvence', 'Create sequence' => 'Vytvořit sekvenci', 'Sequence has been dropped.' => 'Sekvence byla odstraněna.', 'Sequence has been created.' => 'Sekvence byla vytvořena.', 'Sequence has been altered.' => 'Sekvence byla změněna.', 'Alter sequence' => 'Pozměnit sekvenci', + + // PostgreSQL user types support 'User types' => 'Uživatelské typy', 'Create type' => 'Vytvořit typ', 'Type has been dropped.' => 'Typ byl odstraněn.', 'Type has been created.' => 'Typ byl vytvořen.', 'Alter type' => 'Pozměnit typ', + + // label for search in whole database 'Search data in tables' => 'Vyhledat data v tabulkách', + + // label for box with "Run webserver file adminer.sql" 'From server' => 'Ze serveru', + + // label for value '' in enum data type 'empty' => 'prázdné', + + // function translation used in Editor 'now' => 'teď', ); diff --git a/adminer/lang/hu.inc.php b/adminer/lang/hu.inc.php index ed44e2e9..88291d2b 100644 --- a/adminer/lang/hu.inc.php +++ b/adminer/lang/hu.inc.php @@ -69,7 +69,7 @@ $translations = array( 'Foreign keys' => 'Idegen kulcs', 'Triggers' => 'Trigger', 'View' => 'Nézet', - 'Unable to select the table' => 'Nem tudom kiválasztani a táblát.', + 'Unable to select the table' => 'Nem tudom kiválasztani a táblát', 'Invalid CSRF token. Send the form again.' => 'Érvénytelen CSRF azonosító. Küldd újra az űrlapot.', 'Comment' => 'Megjegyzés', 'Default values' => 'Alapértelmezett értékek', @@ -113,7 +113,7 @@ $translations = array( 'Database schema' => 'Adatbázis séma', 'Create procedure' => 'Eljárás létrehozása', 'Create function' => 'Funkció létrehozása', - 'Routine has been dropped.' => 'A rutin eldobva,', + 'Routine has been dropped.' => 'A rutin eldobva.', 'Routine has been altered.' => 'A rutin módosult.', 'Routine has been created.' => 'A rutin létrejött.', 'Alter function' => 'Funkció módosítása', @@ -180,7 +180,7 @@ $translations = array( 'Tables have been truncated.' => 'A tábla felszabadítva.', 'Rows' => 'Oszlop', ',' => ' ', - 'Tables have been moved.' => 'Táblák áthelyezve', + 'Tables have been moved.' => 'Táblák áthelyezve.', 'Move to other database' => 'Áthelyezés másik adatbázisba', 'Move' => 'Áthelyez', 'Engine' => 'Motor', @@ -194,13 +194,13 @@ $translations = array( 'Partitions' => 'Particiók', 'Partition name' => 'Partició neve', 'Values' => 'Értékek', - '%d row(s) have been imported.' => array('%d sor importálva.', '%d sor importálva', '%d sor importálva'), + '%d row(s) have been imported.' => array('%d sor importálva.', '%d sor importálva.', '%d sor importálva.'), 'CSV Import' => 'CSV importálása', 'Import' => 'Importálás', 'Show structure' => 'Struktúra', 'Select data' => 'Tartalom', 'Stop on error' => 'Hiba esetén megáll', - 'Maximum number of allowed fields exceeded. Please increase %s and %s.' => 'A maximális mezőszámot elérted. Növeld meg ezeket: %s, %s', + 'Maximum number of allowed fields exceeded. Please increase %s and %s.' => 'A maximális mezőszámot elérted. Növeld meg ezeket: %s, %s.', 'anywhere' => 'bárhol', '%.3f s' => '%.3f másodperc', '$1-$3-$5' => '$6.$4.$1', diff --git a/adminer/lang/it.inc.php b/adminer/lang/it.inc.php index df8287e2..900f1544 100644 --- a/adminer/lang/it.inc.php +++ b/adminer/lang/it.inc.php @@ -187,7 +187,7 @@ $translations = array( 'Truncate' => 'Svuota', 'Move to other database' => 'Sposta in altro database', 'Move' => 'Sposta', - '%d item(s) have been affected.' => array('Il risultato consiste in %d elemento', 'Il risultato consiste in %d elementi'), + '%d item(s) have been affected.' => array('Il risultato consiste in %d elemento.', 'Il risultato consiste in %d elementi.'), 'whole result' => 'intero risultato', 'Clone' => 'Clona', 'Maximum number of allowed fields exceeded. Please increase %s and %s.' => 'Troppi campi. Per favore aumentare %s e %s.', diff --git a/adminer/lang/ru.inc.php b/adminer/lang/ru.inc.php index a253c88b..b7d0ef5c 100644 --- a/adminer/lang/ru.inc.php +++ b/adminer/lang/ru.inc.php @@ -147,7 +147,7 @@ $translations = array( 'Move down' => 'Переместить вниз', 'Functions' => 'Функции', 'Aggregation' => 'Агрегация', - 'Export' => 'Експорт', + 'Export' => 'Экспорт', 'Output' => 'Выходные данные', 'open' => 'открыть', 'save' => 'сохранить', diff --git a/adminer/lang/sk.inc.php b/adminer/lang/sk.inc.php index 611f367b..33f5cc34 100644 --- a/adminer/lang/sk.inc.php +++ b/adminer/lang/sk.inc.php @@ -170,9 +170,9 @@ $translations = array( 'On completion preserve' => 'Po dokončení zachovat', 'Save and continue edit' => 'Uložiť a pokračovať v úpravách', 'original' => 'originál', - 'Tables have been truncated.' => 'Tabuľka bola vyprázdnená', - 'Tables have been moved.' => 'Tabuľka bola presunutá', - 'Tables have been dropped.' => 'Tabuľka bola odstránená', + 'Tables have been truncated.' => 'Tabuľka bola vyprázdnená.', + 'Tables have been moved.' => 'Tabuľka bola presunutá.', + 'Tables have been dropped.' => 'Tabuľka bola odstránená.', 'Tables and views' => 'Tabuľky a pohľady', 'Engine' => 'Typ', 'Collation' => 'Porovnávanie', diff --git a/adminer/lang/ta.inc.php b/adminer/lang/ta.inc.php index d716700d..53409554 100644 --- a/adminer/lang/ta.inc.php +++ b/adminer/lang/ta.inc.php @@ -2,14 +2,14 @@ $translations = array( 'Login' => 'நுழை', 'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.', - 'Invalid credentials.' => 'ச‌ரியான‌ விப‌ர‌ங்க‌ள் இல்லை', + 'Invalid credentials.' => 'ச‌ரியான‌ விப‌ர‌ங்க‌ள் இல்லை.', 'Server' => 'வ‌ழ‌ங்கி (Server)', 'Username' => 'ப‌ய‌னாள‌ர் (User)', 'Password' => 'க‌ட‌வுச்சொல்', 'Select database' => 'த‌க‌வ‌ல்த‌ள‌த்தை தேர்வு செய்', 'Invalid database.' => 'த‌க‌வ‌ல்த‌ள‌ம் ச‌ரியானதல்ல‌.', 'Create new database' => 'புதிய‌ த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு', - 'Table has been dropped.' => 'அட்ட‌வ‌ணை நீக்க‌ப்ப‌ட்ட‌து', + 'Table has been dropped.' => 'அட்ட‌வ‌ணை நீக்க‌ப்ப‌ட்ட‌து.', 'Table has been altered.' => 'அட்ட‌வணை மாற்ற‌ப்ப‌ட்ட‌து.', 'Table has been created.' => 'அட்ட‌வ‌ணை உருவாக்க‌ப்ப‌ட்ட‌து.', 'Alter table' => 'அட்ட‌வ‌ணையை மாற்று', @@ -62,13 +62,13 @@ $translations = array( 'edit' => 'தொகு', 'Page' => 'ப‌க்க‌ம்', 'Query executed OK, %d row(s) affected.' => array('வின‌வ‌ல் செய‌ல்ப‌டுத்த‌ப்ப‌ட்ட‌து, %d வ‌ரிசை மாற்ற‌ப்ப‌ட்ட‌து.', 'வின‌வ‌ல் செய‌ல்ப‌டுத்த‌ப்ப‌ட்ட‌து, %d வ‌ரிசைக‌ள் மாற்றப்ப‌ட்ட‌ன‌.'), - 'Error in query' => 'வின‌வ‌லில் த‌வ‌றுள்ள‌து.', + 'Error in query' => 'வின‌வ‌லில் த‌வ‌றுள்ள‌து', 'Execute' => 'செய‌ல்ப‌டுத்து', 'Table' => 'அட்ட‌வ‌ணை', 'Foreign keys' => 'வேற்று விசைக‌ள்', 'Triggers' => 'தூண்டுத‌ல்க‌ள்', 'View' => 'தோற்றம்', - 'Unable to select the table' => 'அட்ட‌வ‌ணையை தேர்வு செய்ய‌ முடிய‌வில்லை.', + 'Unable to select the table' => 'அட்ட‌வ‌ணையை தேர்வு செய்ய‌ முடிய‌வில்லை', 'Invalid CSRF token. Send the form again.' => 'CSRF டோக்க‌ன் செல்லாது. ப‌டிவ‌த்தை மீண்டும் அனுப்ப‌வும்.', 'Comment' => 'குறிப்பு', 'Default values' => 'உள்ளிருக்கும் (Default) ம‌திப்புக‌ள் ', @@ -121,8 +121,8 @@ $translations = array( 'Trigger has been dropped.' => 'தூண்டு விசை நீக்க‌ப்ப‌ட்ட‌து.', 'Trigger has been altered.' => 'தூண்டு விசை மாற்ற‌ப்ப‌ட்ட‌து.', 'Trigger has been created.' => 'தூண்டு விசை உருவாக்க‌ப்ப‌ட்ட‌து.', - 'Alter trigger' => 'தூண்டு விசையை மாற்று.', - 'Create trigger' => 'தூண்டு விசையை உருவாக்கு.', + 'Alter trigger' => 'தூண்டு விசையை மாற்று', + 'Create trigger' => 'தூண்டு விசையை உருவாக்கு', 'Time' => 'நேர‌ம்', 'Event' => 'நிக‌ழ்ச்சி', '%d row(s)' => array('%d வ‌ரிசை', '%d வ‌ரிசைக‌ள்'), @@ -257,6 +257,6 @@ $translations = array( 'Network' => 'நெட்வொர்க்', 'Geometry' => 'வ‌டிவ‌விய‌ல் (Geometry)', 'File exists.' => 'கோப்பு உள்ள‌து.', - 'Attachments' => 'இணைப்புக‌ள்.', + 'Attachments' => 'இணைப்புக‌ள்', 'now' => 'இப்பொழுது', ); diff --git a/adminer/script.inc.php b/adminer/script.inc.php index 3d872b46..81d663e9 100644 --- a/adminer/script.inc.php +++ b/adminer/script.inc.php @@ -1,5 +1,8 @@ 0, "Index_length" => 0, "Data_free" => 0); diff --git a/adminer/select.inc.php b/adminer/select.inc.php index 73430d08..412359b8 100644 --- a/adminer/select.inc.php +++ b/adminer/select.inc.php @@ -126,7 +126,7 @@ if ($_POST && !$error) { $set = array(); foreach ($row as $key => $val) { $key = bracket_escape($key, 1); // 1 - back - $set[] = idf_escape($key) . " = " . $adminer->processInput($fields[$key], $val); + $set[] = idf_escape($key) . " = " . (ereg('char|text', $fields[$key]["type"]) || $val != "" ? $adminer->processInput($fields[$key], $val) : "NULL"); } $result = queries("UPDATE" . limit1(table($TABLE) . " SET " . implode(", ", $set), " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : ""))); // can change row on a different page without unique key if (!$result) { diff --git a/changes.txt b/changes.txt index 716b9d2e..87894e2b 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,10 @@ Adminer 3.0.1-dev: Send the form by Ctrl+Enter in all textareas +Disable creating SQLite databases with extension other than db, sdb, sqlite +Ability to use Adminer in a frame through customization Catalan translation +MS SQL 2005 compatibility +PostgreSQL: connect if the eponymous database does not exist Adminer 3.0.0 (released 2010-10-15): Drivers for MS SQL, SQLite, PostgreSQL, Oracle diff --git a/editor/include/adminer.inc.php b/editor/include/adminer.inc.php index bc853542..9495d944 100644 --- a/editor/include/adminer.inc.php +++ b/editor/include/adminer.inc.php @@ -26,6 +26,10 @@ class Adminer { ); } + function headers() { + header("X-Frame-Options: deny"); + } + function loginForm() { ?> @@ -412,7 +416,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5 $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); } $return = q($return); - if (!ereg('varchar|text', $field["type"]) && $field["full_type"] != "tinyint(1)" && $value == "") { + if (!ereg('char|text', $field["type"]) && $field["full_type"] != "tinyint(1)" && $value == "") { $return = "NULL"; } elseif (ereg('^(md5|sha1)$', $function)) { $return = "$function($return)"; @@ -460,7 +464,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5

" . lang('No tables.') . "\n"; diff --git a/lang.php b/lang.php index e2b0ff85..a2f2bb5d 100644 --- a/lang.php +++ b/lang.php @@ -28,7 +28,7 @@ foreach (glob(dirname(__FILE__) . "/adminer/lang/" . ($_SESSION["lang"] ? $_SESS $messages = $messages_all; $file = file_get_contents($filename); $file = str_replace("\r", "", $file); - preg_match_all("~^(\\s*)(?:// )?(('(?:[^\\\\']+|\\\\.)*') => .*[^,\n]),?~m", $file, $matches, PREG_SET_ORDER); + preg_match_all("~^(\\s*(?:// [^'].*\\s+)?)(?:// )?(('(?:[^\\\\']+|\\\\.)*') => .*[^,\n]),?~m", $file, $matches, PREG_SET_ORDER); $s = ""; foreach ($matches as $match) { if (isset($messages[$match[3]])) { diff --git a/readme.txt b/readme.txt index ad3301a4..02f0c70a 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ Adminer - Database management in single PHP file -Adminer Editor - Database editor in single PHP file +Adminer Editor - Data manipulation for end-users http://www.adminer.org/ Supports: MySQL, PostgreSQL, SQLite, MS SQL, Oracle @@ -8,6 +8,7 @@ Apache License, Version 2.0 adminer/index.php - Run development version of Adminer editor/index.php - Run development version of Adminer Editor +editor/example.php - Example customization compile.php [driver] [lang] - Create a single file version lang.php [lang] - Update translations tests/selenium.html - Selenium test suite diff --git a/todo.txt b/todo.txt index 1e772430..611ed1b4 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,6 @@ Transactions in export Create view and routine options -Variables editation, especially timezone +Variables editation, especially timezone (or set by PHP date.timezone) Highlight SQL textarea, then display query inside textarea in select - may use external CodeMirror Blob download and image display in edit form (important for Editor with hidden fields in select) Add title to Logout, edit (in select) and select (in menu) in style "hever" @@ -34,6 +34,7 @@ Delimiter in export and SQL command Backward keys in Editor PostgreSQL: +Display number of schemas in databases overview Users - SELECT * FROM pg_user ORDER BY COUNT(*) Export - http://www.postgresql.org/docs/8.4/static/functions-info.html