Merge branch 'QA_4_6' into STABLE

This commit is contained in:
Isaac Bennetch 2016-11-24 11:41:12 -05:00
commit 50c3f125fe
339 changed files with 142747 additions and 133258 deletions

4
.gitignore vendored
View File

@ -7,6 +7,7 @@
# Upload/save dirs
/upload/
/save/
/tmp/
# For setup script
/config/
# ctags
@ -22,8 +23,9 @@ phpmyadmin.wpj
.idea
.netbeans
*.sw[op]
# IIS files
# Web server files
web.config
.htaccess
# Locales
/locale/
# Backups

107
ChangeLog
View File

@ -1,6 +1,113 @@
phpMyAdmin - ChangeLog
======================
4.6.5 (2016-11-24)
- issue Remove potentionally license problematic sRGB profile
- issue #12459 Display read only fields as read only when editing
- issue #12384 Fix expanding of navigation pane when clicking on database
- issue #12430 Impove partitioning support
- issue #12374 Reintroduced simplified PmaAbsoluteUri configuration directive
- issue Always use UTC time in HTTP headers
- issue #12479 Simplified validation of external links
- issue #12483 Fix browsing tables with built in transformations
- issue #12485 Do not show warning about short blowfish_secret if none is set
- issue #12251 Fixed random logouts due to wrong cookie path
- issue #12480 Fixed editing of ENUM/SET/DECIMAL fields structure
- issue #12497 Missing escaping of configuration used in SQL (hide_db and only_db)
- issue #12476 Add error checking in reading advisory rules file
- issue #12477 Add checking missing elements and confirming element types from json_decode
- issue #12251 Automatically save SQL query in browser local storage rather than in cookie
- issue #12292 Unable to edit transformations
- issue #12502 Remove unused paramenter when connecting to MySQLi
- issue #12303 Fix number formatting with different settings of precision in PHP
- issue #12405 Use single quotes in PHP code
- issue #12534 Option for the dropped column is not removed from 'after_field' select, after the column is dropped
- issue #12531 Properly detect DROP DATABASE queries
- issue #12470 Fix possible race condition in setting URL hash
- issue #11924 Remove caching of server information
- issue #11628 Proper parsing of INSERT ... ON DUPLICATE KEY queries
- issue #12545 Proper parsing of CREATE TABLE ... PARTITION queries
- issue #12473 Code can throw unhandled exception
- issue #12550 Do not try to keep alive session even after expiry
- issue #12512 Fixed rendering BBCode links in setup
- issue #12518 Fixed copy of table with generated columns
- issue #12221 Fixed export of table with generated columns
- issue #12320 Copying a user does not copy usergroup
- issue #12272 Adding a new row with default enum goes to no selection when you want to add more then 2 rows
- issue #12487 Drag and drop import prevents file dropping to blob column file selector on the insert tab
- issue #12554 Absence of scrolling makes it impossible to read longer text values in grid editing
- issue #12530 "Edit routine" crashes when the current user is not the definer, even if privileges are adequate
- issue #12300 Export selective tables by-default dumps Events also
- issue #12298 Fixed export of view definitions
- issue #12242 Edit routine detail dialog does not fill "Return length" field in mysql functions
- issue #12575 New index Confirm adds whitespace around the field name
- issue #12382 Bug in zoom search
- issue #12321 Assign LIMIT clause only to syntactically correct queries
- issue #12461 Can't Execute SQL With Sub-Query Due To "LIMIT 0,25" Inserted At Wrong Place
- issue #12511 Clarify documentation on ArbitraryServerRegexp
- issue #12508 Remove duplicate code in SQL escaping
- issue #12475 Cleanup code for getting table information
- issue #12579 phpMyAdmin's export of a Select statment without a FROM clause generates Wrong SQL
- issue #12316 Correct export of complex SELECT statements
- issue #12080 Fixed parsing of subselect queries
- issue #11740 Fixed handling DELETE ... USING queries
- issue #12100 Fixed handling of CASE operator
- issue #12455 Query history stores separate entry for every letter typed
- issue #12327 Create PHP code no longer works
- issue #12179 Fixed bookmarking of query with multiple statements
- issue #12419 Wrong description on GRANT OPTION
- issue #12615 Fixed regexp for matching browser versions
- issue #12569 Avoid showing import errors twice
- issue #12362 prefs_manage.php can leave an orphaned temporary file
- issue #12619 Unable to export csv when using union select
- issue #12625 Broken Edit links in query results of JOIN query
- issue #12634 Drop DB error in import if DB doesn't exist
- issue #12338 Designer reverts to first saved ER after EACH relation create or delete
- issue #12639 'Show trace' in Console generates JS error for functions in query's trace called without any arguments
- issue #12366 Fix user creation with certain MariaDB setups
- issue #12616 Refuse to work with mbstring.func_overload enabled
- issue #12472 Properly report connection without password in setup
- issue #12365 Fix records count for large tables
- issue #12533 Fix records count for complex queries
- issue #12454 Query history not updated in console until page refresh
- issue #12344 Fixed parsing of labels in loop
- issue #12228 Fixed parsing of BEGIN labels
- issue #12637 Fixed editing some timestamp values
- issue #12622 Fixed javascript error in designer
- issue #12334 Missing page indicator or VIEWs
- issue #12610 Export of tables with Timestamp/Datetime/Time columns defined with ON UPDATE clause with precision fails
- issue #12661 Error inserting into pma__history after timeout
- issue #12195 Row_format = fixed not visible
- issue #12665 Cannot add a foreign key - non-indexed fields not listed in InnoDB tables
- issue #12674 Allow for proper MySQL-allowed strings as identifiers
- issue #12651 Allow for partial dates on table insert page
- issue #12681 Fixed designer with tables using special chars
- issue #12652 Fixed visual query builder for foreign keys with more fields
- issue #12257 Improved search page performance
- issue #12322 Avoid selecting default function for foreign keys
- issue #12453 Fixed escaping of SQL parts in some corner cases
- issue #12542 Missing table name in account privileges editor
- issue #12691 Remove ksort call on empty array in PMA_getPlugins function
- issue #12443 Check parameter type before processing
- issue #12299 Avoid generating too long URLs in search
- issue #12361 Fix self SQL injection in table-specific privileges
- issue #12698 Add link to release notes and download on new version notification
- issue #12712 Error when trying to setup replication (fatal error in call to an old PMA_DBI_connect function)
- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
- issue [security] Possible to bypass logout timeout, see PMASA-2016-62
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
- issue [security] Multiple XSS weaknesses, see PMASA-2016-64
- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
- issue [security] BBCode injection to login page, see PMASA-2016-67
- issue [security] Denial-of-service (DOS) vulnerability in table partitioning, see PMASA-2016-68
- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
4.6.4 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
- issue [security] Improve session cookie code for openid.php and signon.php example files

2
README
View File

@ -1,7 +1,7 @@
phpMyAdmin - Readme
===================
Version 4.6.4
Version 4.6.5
A web interface for MySQL and MariaDB.

View File

@ -26,9 +26,9 @@ Code status
:alt: Buildtime Trend badge
:target: https://buildtimetrend.herokuapp.com/dashboard/phpmyadmin/phpmyadmin
.. image:: https://todofy.org/b/phpmyadmin/phpmyadmin
:alt: todofy badge
:target: https://todofy.org/r/phpmyadmin/phpmyadmin
.. image:: https://bestpractices.coreinfrastructure.org/projects/213/badge
:alt: CII Best Practices
:target: https://bestpractices.coreinfrastructure.org/projects/213
Download
--------

View File

@ -47,7 +47,8 @@ $foreignData = PMA_getForeignData(
isset($_REQUEST['foreign_filter'])
? $_REQUEST['foreign_filter']
: '',
isset($foreign_limit) ? $foreign_limit : null
isset($foreign_limit) ? $foreign_limit : null,
true // for getting value in $foreignData['the_total']
);
// HTML output

View File

@ -109,7 +109,7 @@ foreach ($tables as $each_table) {
} else {
$structure_checked = $is_checked;
}
if (isset($_GET['table_data'])) {
if (isset($_GET['table_data']) && is_array($_GET['table_data'])) {
$data_checked = PMA_getCheckedClause(
$each_table['Name'], $_GET['table_data']
);

View File

@ -305,7 +305,7 @@ if ($cfgRelation['pdfwork'] && $num_tables > 0) {
SELECT *
FROM ' . PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . PMA\libraries\Util::backquote($cfgRelation['pdf_pages']) . '
WHERE db_name = \'' . PMA\libraries\Util::sqlAddSlashes($GLOBALS['db'])
WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($GLOBALS['db'])
. '\'';
$test_rs = PMA_queryAsControlUser(
$test_query,

View File

@ -114,7 +114,7 @@ $cfgRelation = PMA_getRelationsParam();
$all_tables_query = ' SELECT table_name, MAX(version) as version FROM ' .
PMA\libraries\Util::backquote($cfgRelation['db']) . '.' .
PMA\libraries\Util::backquote($cfgRelation['tracking']) .
' WHERE db_name = \'' . PMA\libraries\Util::sqlAddSlashes($_REQUEST['db']) .
' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($_REQUEST['db']) .
'\' ' .
' GROUP BY table_name' .
' ORDER BY table_name ASC';

View File

@ -51,7 +51,7 @@ copyright = u'2012 - 2016, The phpMyAdmin devel team'
# built documents.
#
# The short X.Y version.
version = '4.6.4'
version = '4.6.5'
# The full version, including alpha/beta/rc tags.
release = version

View File

@ -41,10 +41,9 @@ Basic settings
:type: string
:default: ``''``
.. deprecated:: 4.6.0
.. versionchanged:: 4.6.5
This setting is no longer available since phpMyAdmin 4.6.0. Please
adjust your webserver instead.
This setting was not available in phpMyAdmin 4.6.0 - 4.6.4.
Sets here the complete :term:`URL` (with full path) to your phpMyAdmin
installation's directory. E.g.
@ -63,7 +62,7 @@ Basic settings
fails to detect your path, please post a bug report on our bug tracker so
we can improve the code.
.. seealso:: :ref:`faq1_40`
.. seealso:: :ref:`faq1_40`, :ref:`faq2_5`, :ref:`faq4_7`, :ref:`faq5_16`
.. config:option:: $cfg['PmaNoRelation_DisableWarning']
@ -1548,6 +1547,30 @@ Cookie authentication options
to the given regular expression. The regular expression must be enclosed
with a delimiter character.
It is recommended to include start and end symbols in the regullar
expression, so that you can avoid partial matches on the string.
**Examples:**
.. code-block:: php
// Allow connection to three listed servers:
$cfg['ArbitraryServerRegexp'] = '/^(server|another|yetdifferent)$/';
// Allow connection to range of IP addresses:
$cfg['ArbitraryServerRegexp'] = '@^192\.168\.0\.[0-9]{1,}$@';
// Allow connection to server name ending with -mysql:
$cfg['ArbitraryServerRegexp'] = '@^[^:]\-mysql$@';
.. note::
The whole server name is matched, it can include port as well. Due to
way MySQL is permissive in connection parameters, it is possible to use
connection strings as ```server:3306-mysql```. This can be used to
bypass regullar expression by the suffix, while connecting to another
server.
.. config:option:: $cfg['CaptchaLoginPublicKey']
:type: string

View File

@ -561,7 +561,7 @@ This is not specific to phpmyadmin, it's just the behavior of Apache.
ProxyPassReverse /mirror/foo/ http://backend.example.com/%7Euser/phpmyadmin
ProxyPassReverseCookiePath /%7Euser/phpmyadmin /mirror/foo
.. seealso:: <https://httpd.apache.org/docs/2.2/mod/mod_proxy.html>
.. seealso:: <https://httpd.apache.org/docs/2.2/mod/mod_proxy.html>, :config:option:`$cfg['PmaAbsoluteUri']`
.. _faq1_41:
@ -714,9 +714,9 @@ revision.
Check your webserver setup if it correctly fills in either PHP_SELF or REQUEST_URI variables.
If you are running phpMyAdmin older than 4.6.0, you can also check the value
you set for the :config:option:`$cfg['PmaAbsoluteUri']` directive in the
phpMyAdmin configuration file.
If you are running phpMyAdmin behind reverse proxy, please set the
:config:option:`$cfg['PmaAbsoluteUri']` directive in the phpMyAdmin
configuration file to match your setup.
.. _faq2_6:
@ -1387,6 +1387,9 @@ rewritten, if possible it is suggested that you upgrade to take
advantage of the new features. For additional help on this subject,
look for the word "upload" in this document.
Note: For errors while importing of dumps exported from older MySQL versions to newer MySQL versions,
please check :ref:`faq6_41`.
.. _faq6_6:
6.6 How can I use the relation table in Query-by-example?
@ -2094,6 +2097,31 @@ Parameters should be prefixed with a colon(:) and when the "Bind parameters" che
these parameters will be identified and input fields for these parameters will be presented.
Values entered in these field will be substituted in the query before being executed.
.. _faq6_41:
6.41 I get import errors while importing the dumps exported from older MySQL versions (pre-5.7.6) into newer MySQL versions (5.7.7+), but they work fine when imported back on same older versions ?
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you get errors like *#1031 - Table storage engine for 'table_name' doesn't have this option*
while importing the dumps exported from pre-5.7.7 MySQL servers into new MySQL server versions 5.7.7+,
it might be because ROW_FORMAT=FIXED is not supported with InnoDB tables. Moreover, the value of
`innodb_strict_mode <http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_strict_mode>`_ would define if this would be reported as a warning or as an error.
Since MySQL version 5.7.9, the default value for `innodb_strict_mode` is `ON` and thus would generate
an error when such a CREATE TABLE or ALTER TABLE statement is encountered.
There are two ways of preventing such errors while importing:
* Change the value of `innodb_strict_mode` to `OFF` before starting the import and turn it `ON` after
the import is successfully completed.
* This can be achieved in two ways:
* Go to 'Variables' page and edit the value of `innodb_strict_mode`
* Run the query : `SET GLOBAL `innodb_strict_mode` = '[value]'`
After the import is done, it is suggested that the value of `innodb_strict_mode` should be reset to the
original value.
.. _faqproject:
phpMyAdmin project

View File

@ -149,16 +149,38 @@ environment variables:
By default, :ref:`cookie` is used, but if :envvar:`PMA_USER` and
:envvar:`PMA_PASSWORD` are set, it is switched to :ref:`auth_config`.
Additionally configuration can be tweaked by :file:`/config.user.inc.php`. If
.. note::
The credentials you need to login are stored in the MySQL server, in case
of Docker image there are various ways to set it (for example
:envvar:`MYSQL_ROOT_PASSWORD` when starting MySQL container). Please check
documentation for `MariaDB container <https://hub.docker.com/r/_/mariadb/>`_
or `MySQL container <https://hub.docker.com/r/_/mysql/>`_.
Additionally configuration can be tweaked by :file:`/www/config.user.inc.php`. If
this file exists, it will be loaded after configuration generated from above
environment variables, so you can override any configuration variable. This
configuraiton can be added as a volume when invoking docker using
`-v /some/local/directory/config.user.inc.php:/config.user.inc.php` parameters.
`-v /some/local/directory/config.user.inc.php:/www/config.user.inc.php` parameters.
.. seealso::
See :ref:`config` for detailed description of configuration options.
Docker Volumes
--------------
You can use following volumes to customise image behavior:
:file:`/www/config.user.inc.php`
Can be used for additional settings, see previous chapter for more details.
:file:`/sessions/`
Directory where PHP sessions are stored. You might want to share this
for example when uswing :ref:`auth_signon`.
Docker Examples
---------------
@ -748,6 +770,7 @@ are always ways to make your installation more secure:
* Serve phpMyAdmin on HTTPS only. Preferably, you should use HSTS as well, so that
you're protected from protocol downgrade attacks.
* Remove the ``test`` directory from phpMyAdmin, unless you are developing and need test suite.
* Remove the ``setup`` directory from phpMyAdmin, you will probably not
use it after the initial setup.
* Properly choose an authentication method - :ref:`cookie`

View File

@ -117,8 +117,8 @@ libraries/plugins/transformations/TEMPLATE\_ABSTRACT files for adding
your own transformation plug-in. You can also generate a new
transformation plug-in (with or without the abstract transformation
class), by using
:file:`libraries/plugins/transformations/generator_plugin.sh` or
:file:`libraries/plugins/transformations/generator_main_class.sh`.
:file:`scripts/transformations_generator_plugin.sh` or
:file:`scripts/transformations_generator_main_class.sh`.
The applyTransformation() method always gets passed three variables:

View File

@ -120,13 +120,13 @@ if (! empty($sql_query)) {
// making sure that :param does not apply values to :param1
$sql_query = preg_replace(
'/' . $quoted . '([^a-zA-Z0-9_])/',
PMA\libraries\Util::sqlAddSlashes($replacement) . '${1}',
$GLOBALS['dbi']->escapeString($replacement) . '${1}',
$sql_query
);
// for parameters the appear at the end of the string
$sql_query = preg_replace(
'/' . $quoted . '$/',
PMA\libraries\Util::sqlAddSlashes($replacement),
$GLOBALS['dbi']->escapeString($replacement),
$sql_query
);
}
@ -199,7 +199,10 @@ if ($_POST == array() && $_GET == array()) {
$_SESSION['Import_message']['message'] = $message->getDisplay();
$_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto'];
$message->display();
$response = PMA\libraries\Response::getInstance();
$response->setRequestStatus(false);
$response->addJSON('message', $message);
exit; // the footer is displayed automatically
}
@ -613,8 +616,8 @@ if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_fil
// Something to skip? (because timeout has passed)
if (! $error && isset($_POST['skip'])) {
$original_skip = $skip = $_POST['skip'];
while ($skip > 0) {
$original_skip = $skip = intval($_POST['skip']);
while ($skip > 0 && ! $finished) {
PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progressivity, otherwise we eat all memory!
$read_multiply = 1;
@ -785,6 +788,7 @@ if ($go_sql) {
}
$html_output = '';
foreach ($sql_queries as $sql_query) {
// parse sql query
@ -797,6 +801,19 @@ if ($go_sql) {
// @todo: possibly refactor
extract($analyzed_sql_results);
// Check if User is allowed to issue a 'DROP DATABASE' Statement
if (PMA_hasNoRightsToDropDatabase(
$analyzed_sql_results, $cfg['AllowUserDropDatabase'], $GLOBALS['is_superuser']
)) {
PMA\libraries\Util::mysqlDie(
__('"DROP DATABASE" statements are disabled.'),
'',
false,
$_SESSION['Import_message']['go_back_url']
);
return;
} // end if
if ($table != $table_from_sql && !empty($table_from_sql)) {
$table = $table_from_sql;
}
@ -807,7 +824,7 @@ if ($go_sql) {
$db, // db
$table, // table
null, // find_real_end
$_REQUEST['sql_query'], // sql_query_for_bookmark
null, // sql_query_for_bookmark - see below
null, // extra_data
null, // message_to_show
null, // message
@ -823,6 +840,18 @@ if ($go_sql) {
);
}
// sql_query_for_bookmark is not included in PMA_executeQueryAndGetQueryResponse
// since only one bookmark has to be added for all the queries submitted through
// the SQL tab
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
$cfgBookmark = PMA_Bookmark_getParams();
PMA_storeTheQueryAsBookmark(
$db, $cfgBookmark['user'],
$_REQUEST['sql_query'], $_POST['bkm_label'],
isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null
);
}
$response = PMA\libraries\Response::getInstance();
$response->addJSON('ajax_reload', $ajax_reload);
$response->addHTML($html_output);

View File

@ -152,7 +152,7 @@ if ($server > 0 || count($cfg['Servers']) > 1
. 'please do not change root, debian-sys-maint and pma users. '
. 'More information is available at %s.'
),
'<a href="url.php?url=https://demo.phpmyadmin.net/" target="_blank">demo.phpmyadmin.net</a>'
'<a href="url.php?url=https://demo.phpmyadmin.net/" target="_blank" rel="noopener noreferrer">demo.phpmyadmin.net</a>'
);
echo '</p>';
echo '</div>';
@ -389,7 +389,7 @@ PMA_printListItem(
PMA_printListItem(
__('Official Homepage'),
'li_pma_homepage',
PMA_linkURL('https://www.phpMyAdmin.net/'),
PMA_linkURL('https://www.phpmyadmin.net/'),
null,
'_blank'
);
@ -428,21 +428,6 @@ echo '</div>';
echo '</div>';
/**
* As we try to handle charsets by ourself, mbstring overloads just
* break it, see bug 1063821.
*/
if (@extension_loaded('mbstring') && @ini_get('mbstring.func_overload') > 1) {
trigger_error(
__(
'You have enabled mbstring.func_overload in your PHP '
. 'configuration. This option is incompatible with phpMyAdmin '
. 'and might cause some data to be corrupted!'
),
E_USER_WARNING
);
}
/**
* mbstring is used for handling multibytes inside parser, so it is good
* to tell user something might be broken without it, see bug #1063149.
@ -518,8 +503,7 @@ if (! empty($_SESSION['encryption_key'])) {
),
E_USER_WARNING
);
}
if (strlen($GLOBALS['cfg']['blowfish_secret']) < 32) {
} elseif (strlen($GLOBALS['cfg']['blowfish_secret']) < 32) {
trigger_error(
__(
'The secret passphrase in configuration (blowfish_secret) is too short.'

View File

@ -33,6 +33,7 @@ CodeMirror.sqlLint = function(text, updateLinting, options, cm) {
token: PMA_commonParams.get('token'),
server: PMA_commonParams.get('server'),
options: options.lintOptions,
no_history: true,
},
success: handleResponse
});

View File

@ -298,6 +298,13 @@ PMA_DROP_IMPORT = {
* @return void
*/
_dragenter : function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($(".noDragDrop").length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!PMA_DROP_IMPORT._hasFiles(event)) {
@ -333,6 +340,12 @@ PMA_DROP_IMPORT = {
* @return void
*/
_dragover: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($(".noDragDrop").length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!PMA_DROP_IMPORT._hasFiles(event)) {
@ -348,6 +361,11 @@ PMA_DROP_IMPORT = {
* @return void
*/
_dragleave: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($(".noDragDrop").length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
var $pma_drop_handler = $(".pma_drop_handler");
@ -408,6 +426,12 @@ PMA_DROP_IMPORT = {
* @return void
*/
_drop: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($(".noDragDrop").length !== 0) {
return;
}
var dbname = PMA_commonParams.get('db');
var server = PMA_commonParams.get('server');

View File

@ -588,8 +588,9 @@ function setTab(tab_id)
}
$this.find('li').removeClass('active').find('a[href=#' + tab_id + ']').parent().addClass('active');
$this.parent().find('div.tabs_contents fieldset').hide().filter('#' + tab_id).show();
location.hash = 'tab_' + tab_id;
$this.parent().find('input[name=tab_hash]').val(location.hash);
var hashValue = 'tab_' + tab_id;
location.hash = hashValue;
$this.parent().find('input[name=tab_hash]').val(hashValue);
});
}
@ -624,9 +625,9 @@ AJAX.registerOnload('config.js', function () {
var tab_check_fnc = function () {
if (location.hash != prev_hash) {
prev_hash = location.hash;
if (location.hash.match(/^#tab_[a-zA-Z0-9_]+/)) {
if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
var hash = location.hash.substr(5).split('&')[0];
var hash = prev_hash.substr(5).split('&')[0];
if ($('#' + hash).length) {
setTab(hash);
}

View File

@ -192,7 +192,7 @@ var PMA_console = {
});
$(document).ajaxComplete(function (event, xhr, ajaxOptions) {
if (ajaxOptions.dataType != 'json') {
if (ajaxOptions.dataType && ajaxOptions.dataType.indexOf('json') != -1) {
return;
}
try {
@ -1235,7 +1235,7 @@ PMA_consoleDebug = {
functionName += dbgStep.type;
}
functionName += dbgStep.function;
if (dbgStep.args.length) {
if (dbgStep.args && dbgStep.args.length) {
functionName += '(...)';
} else {
functionName += '()';
@ -1303,7 +1303,7 @@ PMA_consoleDebug = {
.append(
$('<span class="file">').text(this._formatFileName(step))
);
if (step.args.length) {
if (step.args && step.args.length) {
$stepElem
.append(
$('<span class="args">').html(this._formatFunctionArgs(step))

View File

@ -19,6 +19,8 @@
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('db_search.js', function () {
$('a.browse_results').unbind('click');
$('a.delete_results').unbind('click');
$('#buttonGo').unbind('click');
$('#togglesearchresultlink').unbind('click');
$("#togglequerybox").unbind('click');
@ -26,91 +28,6 @@ AJAX.registerTeardown('db_search.js', function () {
$(document).off('submit', "#db_search_form.ajax");
});
/**
* Loads the database search results
*
* @param result_path Url of the page to load
* @param table_name Name of table to browse
*
* @return nothing
*/
function loadResult(result_path, table_name, link)
{
$(function () {
/** Hides the results shown by the delete criteria */
var $msg = PMA_ajaxShowMessage(PMA_messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$("#table-info").show();
$('#table-link').attr({"href" : 'sql.php' + link }).text(table_name);
var url = result_path + "#searchresults";
$.get(url, {'ajax_request': true, 'is_js_confirmed': true}, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
PMA_ajaxRemoveMessage($msg);
$('.table_results').each(function () {
PMA_makegrid(this, true, true, true, true);
});
$('#browse-results').show();
PMA_highlightSQL($('#browse-results'));
$('html, body')
.animate({
scrollTop: $("#browse-results").offset().top
}, 1000);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
}
/**
* Delete the selected search results
*
* @param result_path Url of the page to load
* @param msg Text for the confirmation dialog
*
* @return nothing
*/
function deleteResult(result_path, msg)
{
$(function () {
/** Hides the results shown by the browse criteria */
$("#table-info").hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
if (confirm(msg)) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
$.post(result_path, {'ajax_request': true, 'is_js_confirmed': true},
function (data) {
if (typeof data === 'undefined' || !data.success) {
PMA_ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').click();
$('#togglequerybox').html(PMA_messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $("#browse-results").offset().top
}, 1000);
PMA_ajaxRemoveMessage($msg);
}
);
}
});
}
AJAX.registerOnload('db_search.js', function () {
/** Hide the table link in the initial search result */
var icon = PMA_getImage('s_tbl.png', '', {'id': 'table-image'}).toString();
@ -192,6 +109,95 @@ AJAX.registerOnload('db_search.js', function () {
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function(e){
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = PMA_ajaxShowMessage(PMA_messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$("#table-info").show();
var table_name = $(this).data('table-name');
$('#table-link').attr({"href" : $(this).attr('href')}).text(table_name);
var url = $(this).attr('href') + "#searchresults";
var browse_sql = $(this).data('browse-sql');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browse_sql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
PMA_ajaxRemoveMessage($msg);
$('.table_results').each(function () {
PMA_makegrid(this, true, true, true, true);
});
$('#browse-results').show();
PMA_highlightSQL($('#browse-results'));
$('html, body')
.animate({
scrollTop: $("#browse-results").offset().top
}, 1000);
} else {
PMA_ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function(e){
e.preventDefault();
/** Hides the results shown by the browse criteria */
$("#table-info").hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = PMA_sprintf(
PMA_messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
var $msg = PMA_ajaxShowMessage(PMA_messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
PMA_ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').click();
$('#togglequerybox').html(PMA_messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $("#browse-results").offset().top
}, 1000);
PMA_ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/

View File

@ -540,6 +540,16 @@ function toggle_table_select(row) {
}
}
function handleAddProcCheckbox() {
if ($('#table_structure_all').is(':checked') === true
&& $('#table_data_all').is(':checked') === true
) {
$('#checkbox_sql_procedure_function').prop('checked', true);
} else {
$('#checkbox_sql_procedure_function').prop('checked', false);
}
}
AJAX.registerOnload('export.js', function () {
/**
* For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options
@ -579,26 +589,31 @@ AJAX.registerOnload('export.js', function () {
$('input[name="table_select[]"]').on('change', function() {
toggle_table_select($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
});
$('input[name="table_structure[]"]').on('change', function() {
check_table_selected($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
});
$('input[name="table_data[]"]').on('change', function() {
check_table_selected($(this).closest('tr'));
check_table_select_all();
handleAddProcCheckbox();
});
$('#table_structure_all').on('change', function() {
toggle_table_select_all_str();
check_selected_tables();
handleAddProcCheckbox();
});
$('#table_data_all').on('change', function() {
toggle_table_select_all_data();
check_selected_tables();
handleAddProcCheckbox();
});
if ($("input[name='export_type']").val() == 'database') {
@ -805,6 +820,8 @@ AJAX.registerOnload('export.js', function () {
toggle_quick_or_custom();
toggle_structure_data_opts();
toggle_sql_include_comments();
check_table_select_all();
handleAddProcCheckbox();
/**
* Initially disables the "Dump some row(s)" sub-options

View File

@ -152,6 +152,8 @@ function PMA_addDatepicker($this_element, type, options)
}
else if (type == "time") {
$this_element.timepicker($.extend(defaultOptions, options));
// Add a tip regarding entering MySQL allowed-values for TIME data-type
PMA_tooltip($this_element, 'input', PMA_messages.strMysqlAllowedValuesTip);
}
}
@ -185,6 +187,14 @@ function addDateTimePicker() {
showMicrosec: showMicrosec,
timeFormat: timeFormat
});
// Add a tip regarding entering MySQL allowed-values
// for TIME and DATE data-type
if ($(this).hasClass('timefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipTime);
} else if ($(this).hasClass('datefield')) {
PMA_tooltip($(this), 'input', PMA_messages.strMysqlAllowedValuesTipDate);
}
});
}
}
@ -299,7 +309,7 @@ function PMA_clearSelection() {
*
* @param $elements jQuery object representing the elements
* @param item the item
* (see http://api.jqueryui.com/tooltip/#option-items)
* (see https://api.jqueryui.com/tooltip/#option-items)
* @param myContent content of the tooltip
* @param additionalOptions to override the default options
*
@ -505,9 +515,10 @@ function PMA_current_version(data)
if (data && data.version && data.date) {
var current = parseVersionString($('span.version').text());
var latest = parseVersionString(data.version);
var url = 'https://web.phpmyadmin.net/files/' + escapeHtml(data.version) + '/';
var version_information_message = '<span class="latest">' +
PMA_messages.strLatestAvailable +
' ' + escapeHtml(data.version) +
' <a href="' + url + '">' + escapeHtml(data.version) + '</a>' +
'</span>';
if (latest > current) {
var message = PMA_sprintf(
@ -521,7 +532,7 @@ function PMA_current_version(data)
htmlClass = 'error';
}
$('#newer_version_notice').remove();
$('#maincontainer').after('<div id="newer_version_notice" class="' + htmlClass + '">' + message + '</div>');
$('#maincontainer').after('<div id="newer_version_notice" class="' + htmlClass + '"><a href="' + url + '">' + message + '</a></div>');
}
if (latest === current) {
version_information_message = ' (' + PMA_messages.strUpToDate + ')';
@ -613,8 +624,12 @@ function confirmLink(theLink, theSqlQuery)
if (is_confirmed) {
if ($(theLink).hasClass('formLinkSubmit')) {
var name = 'is_js_confirmed';
if ($(theLink).attr('href').indexOf('usesubform') != -1) {
name = 'subform[' + $(theLink).attr('href').substr('#').match(/usesubform\[(\d+)\]/i)[1] + '][is_js_confirmed]';
var matches = $(theLink).attr('href').substr('#').match(/usesubform\[(\d+)\]/i);
if (matches != null) {
name = 'subform[' + matches[1] + '][is_js_confirmed]';
}
}
$(theLink).parents('form').append('<input type="hidden" name="' + name + '" value="1" />');
@ -629,8 +644,7 @@ function confirmLink(theLink, theSqlQuery)
} // end of the 'confirmLink()' function
/**
* Displays an error message if a "DROP DATABASE" statement is submitted
* while it isn't allowed, else confirms a "DROP/DELETE/ALTER" query before
* Confirms a "DROP/DELETE/ALTER" query before
* submitting it if required.
* This function is called by the 'checkSqlQuery()' js function.
*
@ -648,17 +662,6 @@ function confirmQuery(theForm1, sqlQuery1)
return true;
}
// "DROP DATABASE" statement isn't allowed
if (PMA_messages.strNoDropDatabases !== '') {
var drop_re = new RegExp('(^|;)\\s*DROP\\s+(IF EXISTS\\s+)?DATABASE\\s', 'i');
if (drop_re.test(sqlQuery1.value)) {
alert(PMA_messages.strNoDropDatabases);
theForm1.reset();
sqlQuery1.focus();
return false;
} // end if
} // end if
// Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement
//
// TODO: find a way (if possible) to use the parser-analyser
@ -666,7 +669,7 @@ function confirmQuery(theForm1, sqlQuery1)
// For now, I just added a ^ to check for the statement at
// beginning of expression
var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|DATABASE|PROCEDURE)\\s', 'i');
var do_confirm_re_0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|PROCEDURE)\\s', 'i');
var do_confirm_re_1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i');
var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
@ -911,13 +914,13 @@ AJAX.registerOnload('functions.js', function () {
data: params,
success: function (data) {
if (data.success) {
if (PMA_commonParams.get('LoginCookieValidity')-_idleSecondsCounter > 5) {
var interval = (PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter - 5) * 1000;
if (interval > Math.pow(2, 31) - 1) { // max value for setInterval() function
interval = Math.pow(2, 31) - 1;
}
var remaining = PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter;
if (remaining > 5) {
// max value for setInterval() function
var interval = Math.min(remaining * 1000, Math.pow(2, 31) - 1);
updateTimeout = window.setTimeout(UpdateIdleTime, interval);
} else {
} else if (remaining > 0) {
// We're close to session expiry
updateTimeout = window.setTimeout(UpdateIdleTime, 2000);
}
} else { //timeout occurred
@ -1164,7 +1167,9 @@ function insertQuery(queryType)
}
return;
} else if (queryType == "saved") {
if ($.cookie('auto_saved_sql')) {
if (isStorageSupported('localStorage') && typeof window.localStorage.auto_saved_sql != 'undefined') {
setQuery(window.localStorage.auto_saved_sql);
} else if ($.cookie('auto_saved_sql')) {
setQuery($.cookie('auto_saved_sql'));
} else {
PMA_ajaxShowMessage(PMA_messages.strNoAutoSavedQuery);
@ -4822,11 +4827,6 @@ function formatBytes(bytes, subdecimals, pointchar) {
}
AJAX.registerOnload('functions.js', function () {
/**
* Opens pma more themes link in themes browser, in new window instead of popup
* This way, we don't break HTML validity
*/
$("a._blank").prop("target", "_blank");
/**
* Reveal the login form to users with JS enabled
* and focus the appropriate input field
@ -4943,6 +4943,30 @@ function PMA_ignorePhpErrors(clearPrevErrors){
$pmaErrors.remove();
}
/**
* Toggle the Datetimepicker UI if the date value entered
* by the user in the 'text box' is not going to be accepted
* by the Datetimepicker plugin (but is accepted by MySQL)
*/
function toggleDatepickerIfInvalid($td, $input_field) {
// Regex allowed by the Datetimepicker UI
var dtexpDate = new RegExp(['^([0-9]{4})',
'-(((01|03|05|07|08|10|12)-((0[1-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)',
'-((0[1-9])|([1-2][0-9])|30)))$'].join(''));
var dtexpTime = new RegExp(['^(([0-1][0-9])|(2[0-3]))',
':((0[0-9])|([1-5][0-9]))',
':((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$'].join(''));
// If key-ed in Time or Date values are unsupported by the UI, close it
if ($td.attr('data-type') === 'date' && ! dtexpDate.test($input_field.val())) {
$input_field.datepicker('hide');
} else if ($td.attr('data-type') === 'time' && ! dtexpTime.test($input_field.val())) {
$input_field.datepicker('hide');
} else {
$input_field.datepicker('show');
}
}
/**
* Unbind all event handlers before tearing down a page
*/

View File

@ -15,6 +15,7 @@ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// Avoid loading the full common.inc.php because this would add many
// non-js-compatible stuff like DOCTYPE
define('PMA_MINIMUM_COMMON', true);
define('PMA_PATH_TO_BASEDIR', '../');
require_once './libraries/common.inc.php';
$buffer = PMA\libraries\OutputBuffering::getInstance();

View File

@ -24,6 +24,7 @@ $_GET['scripts'] = json_encode($_GET['scripts']);
// Avoid loading the full common.inc.php because this would add many
// non-js-compatible stuff like DOCTYPE
define('PMA_MINIMUM_COMMON', true);
define('PMA_PATH_TO_BASEDIR', '../');
require_once './libraries/common.inc.php';
$buffer = PMA\libraries\OutputBuffering::getInstance();

View File

@ -1051,7 +1051,21 @@ function PMA_makegrid(t, enableResize, enableReorder, enableVisib, enableGridEdi
timeFormat: timeFormat
});
$input_field.on('keyup', function (e) {
if (e.which == 13) {
// post on pressing "Enter"
e.preventDefault();
e.stopPropagation();
g.saveOrPostEditedCell();
} else if (e.which == 27) {
} else {
toggleDatepickerIfInvalid($td, $input_field);
}
});
$input_field.datepicker("show");
toggleDatepickerIfInvalid($td, $input_field);
// unbind the mousedown event to prevent the problem of
// datepicker getting closed, needs to be checked for any
// change in names when updating

View File

@ -36,11 +36,6 @@ register_shutdown_function(
}
);
$js_messages['strNoDropDatabases'] = __('"DROP DATABASE" statements are disabled.');
if ($cfg['AllowUserDropDatabase']) {
$js_messages['strNoDropDatabases'] = '';
}
/* For confirmations */
$js_messages['strConfirm'] = __('Confirm');
$js_messages['strDoYouReally'] = __('Do you really want to execute "%s"?');
@ -385,11 +380,14 @@ $js_messages['strHideSearchResults'] = __('Hide search results');
$js_messages['strShowSearchResults'] = __('Show search results');
$js_messages['strBrowsing'] = __('Browsing');
$js_messages['strDeleting'] = __('Deleting');
$js_messages['strConfirmDeleteResults'] = __('Delete the matches for the %s table?');
/* For db_routines.js */
$js_messages['MissingReturn']
= __('The definition of a stored function must contain a RETURN statement!');
$js_messages['strExport'] = __('Export');
$js_messages['NoExportable']
= __('No routine is exportable. Required privileges may be lacking.');
/* For ENUM/SET editor*/
$js_messages['enum_editor'] = __('ENUM/SET editor');
@ -520,6 +518,18 @@ $js_messages['strYes'] = __('Yes');
$js_messages['strCopyEncryptionKey'] = __('Do you want to copy encryption key?');
$js_messages['strEncryptionKey'] = __('Encryption key');
/* For Tip to be shown on Time field */
$js_messages['strMysqlAllowedValuesTipTime'] = __(
'MySQL accepts additional values not selectable by the slider;'
. ' key in those values directly if desired'
);
/* For Tip to be shown on Date field */
$js_messages['strMysqlAllowedValuesTipDate'] = __(
'MySQL accepts additional values not selectable by the datepicker;'
. ' key in those values directly if desired'
);
/* For Lock symbol Tooltip */
$js_messages['strLockToolTip'] = __(
'Indicates that you have made changes to this page;'

View File

@ -280,15 +280,16 @@ PMA_SetUrlHash = (function (jQuery, window) {
/**
* Start initialisation
*/
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) == '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
var colon_position = window.location.hash.indexOf(':');
var questionmark_position = window.location.hash.indexOf('?');
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
var hash_url = window.location.hash.substring(colon_position + 1, questionmark_position);
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
window.location = window.location.hash.substring(
window.location = urlhash.substring(
colon_position + 1
);
}
@ -328,4 +329,4 @@ PMA_SetUrlHash = (function (jQuery, window) {
* Publicly exposes a reference to the otherwise private setUrlHash function
*/
return setUrlHash;
})(jQuery, window);
})(jQuery, window);

View File

@ -552,12 +552,15 @@ $(function () {
if ($('#pma_navigation_tree_content').length &&
typeof storage.navTreePaths === 'undefined'
) {
navTreeStateUpdate();
PMA_reloadNavigation();
} else if (PMA_commonParams.get('server') === storage.server &&
PMA_commonParams.get('token') === storage.token
) {
// Reload the tree to the state before page refresh
PMA_reloadNavigation(null, JSON.parse(storage.navTreePaths));
} else {
// If the user is different
navTreeStateUpdate();
}
}
});

View File

@ -658,6 +658,10 @@ function query_from()
var key2;
var key3;
var parts1;
// the constraints that have been used in the LEFT JOIN
var constraints_added = [];
for (i = 0; i < history_array.length; i++) {
from_array.push(history_array[i].get_tab());
}
@ -666,6 +670,7 @@ function query_from()
temp = tab_left.shift();
quer = '`' + temp + '`';
tab_used.push(temp);
// if master table (key2) matches with tab used get all keys and check if tab_left matches
// after this check if master table (key2) matches with tab left then check if any foreign matches with master .
for (i = 0; i < 2; i++) {
@ -677,11 +682,18 @@ function query_from()
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split(".");
if (found(tab_left, parts1[1]) > 0) {
query += "\n" + 'LEFT JOIN ';
query += '`' + parts1[1] + '` ON ';
query += '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
t_tab_left.push(parts1[1]);
if (found(constraints_added, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += "\n" + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraints_added.push(key);
}
t_tab_left.push(parts[1]);
}
}
}
@ -701,10 +713,17 @@ function query_from()
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split(".");
if (found(tab_used, parts1[1]) > 0) {
query += "\n" + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
if (found(constraints_added, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += "\n" + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraints_added.push(key);
}
t_tab_left.push(parts[1]);
}
}

View File

@ -297,7 +297,6 @@ function setDefaultValuesFromSavedState()
function Main()
{
//alert( document.getElementById('osn_tab').offsetTop);
//---CROSS
document.getElementById("layer_menu").style.top = -1000 + 'px'; //fast scroll
@ -400,14 +399,10 @@ function Re_load()
x2 = x2_left - sm_s;
s_left = 1;
}
//alert(key2 + "." + key3);
var row_offset_top = 0;
//alert('id_tbody_' + key2);
//alert(document.getElementById('id_hide_tbody_' + key2));
var tab_hide_button = document.getElementById('id_hide_tbody_' + key2);
//alert(tab_hide_button.innerHTML);
if (tab_hide_button.innerHTML == 'v') {
var fromColumn = document.getElementById(key2 + "." + key3);
if (fromColumn) {
@ -681,6 +676,49 @@ function Save2(callback)
}
}
function submitSaveDialogAndClose(callback)
{
var $form = $("#save_page");
var name = $form.find('input[name="selected_value"]').val().trim();
if (name === '') {
PMA_ajaxShowMessage(PMA_messages.strEnterValidPageName, false);
return;
}
$('#page_save_dialog').dialog('close');
if (pmd_tables_enabled) {
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize() + Get_url_pos(), function (data) {
if (data.success === false) {
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
MarkSaved();
if (data.id) {
selected_page = data.id;
}
$('#page_name').text(name);
if (typeof callback !== 'undefined') {
callback();
}
}
});
} else {
Save_to_new_page(db, name, Get_url_pos(), function (page) {
MarkSaved();
if (page.pg_nr) {
selected_page = page.pg_nr;
}
$('#page_name').text(page.page_descr);
if (typeof callback !== 'undefined') {
callback();
}
});
}
}
function Save3(callback)
{
if (parseInt(selected_page) !== -1) {
@ -689,44 +727,8 @@ function Save3(callback)
var button_options = {};
button_options[PMA_messages.strGo] = function () {
var $form = $("#save_page");
var name = $form.find('input[name="selected_value"]').val().trim();
if (name === '') {
PMA_ajaxShowMessage(PMA_messages.strEnterValidPageName, false);
return;
}
$(this).dialog('close');
if (pmd_tables_enabled) {
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
PMA_prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize() + Get_url_pos(), function (data) {
if (data.success === false) {
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
MarkSaved();
if (data.id) {
selected_page = data.id;
}
$('#page_name').text(name);
if (typeof callback !== 'undefined') {
callback();
}
}
});
} else {
Save_to_new_page(db, name, Get_url_pos(), function (page) {
MarkSaved();
if (page.pg_nr) {
selected_page = page.pg_nr;
}
$('#page_name').text(page.page_descr);
if (typeof callback !== 'undefined') {
callback();
}
});
}
};
$form.submit();
}
button_options[PMA_messages.strCancel] = function () {
$(this).dialog('close');
};
@ -739,6 +741,10 @@ function Save3(callback)
.append('<input type="hidden" name="save_page" value="new" />')
.append('<label for="selected_value">' + PMA_messages.strPageName +
'</label>:<input type="text" name="selected_value" />');
$form.on('submit', function(e){
e.preventDefault();
submitSaveDialogAndClose(callback);
});
$('<div id="page_save_dialog"></div>')
.append($form)
.dialog({
@ -1095,7 +1101,7 @@ function Load_page(page) {
function Grid()
{
var value_sent = '';
var value_sent = '';
if (!ON_grid) {
ON_grid = 1;
value_sent = 'on';
@ -1189,18 +1195,12 @@ function Click_field(T, f, PK) // table field
if (ON_display_field) {
// if is display field
if (display_field[T] == f) {
//alert(T);
//s = '';for(k in display_field)s += k + ' = ' + display_field[k] + ',';alert(s);
old_class = 'tab_field';
//display_field.splice(T, 1);
delete display_field[T];
//s = '';for(k in display_field)s += k + ' = ' + display_field[k] + ', ';alert(s);
//n = 0;for(k in display_field)n++;alert(n);
} else {
old_class = 'tab_field_3';
if (display_field[T]) {
document.getElementById('id_tr_' + T + '.' + display_field[T]).className = 'tab_field';
//display_field.splice(T, 1);
delete display_field[T];
}
display_field[T] = f;
@ -1237,8 +1237,7 @@ function New_relation()
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
// Load_page(selected_page);
$("#designer_tab").click();
Load_page(selected_page);
}
}); // end $.post()
}
@ -1447,7 +1446,6 @@ function Canvas_click(id, event)
}
if (selected) {
// select relations
//alert(Key0+' - '+Key1+' - '+Key2+' - '+Key3);
var left = Glob_X - (document.getElementById('layer_upd_relation').offsetWidth>>1);
document.getElementById('layer_upd_relation').style.left = left + 'px';
var top = Glob_Y - document.getElementById('layer_upd_relation').offsetHeight - 10;
@ -1469,8 +1467,7 @@ function Upd_relation()
PMA_ajaxShowMessage(data.error, false);
} else {
PMA_ajaxRemoveMessage($msgbox);
// Load_page(selected_page);
$("#designer_tab").click();
Load_page(selected_page);
}
}); // end $.post()
}

View File

@ -128,6 +128,11 @@ RTE.COMMON = {
var count = export_anchors.length;
var returnCount = 0;
// No routine is exportable (due to privilege issues)
if (count === 0) {
PMA_ajaxShowMessage(PMA_messages.NoExportable);
}
export_anchors.each(function () {
$.get($(this).attr('href'), {'ajax_request': true}, function (data) {
returnCount++;
@ -149,6 +154,7 @@ RTE.COMMON = {
} else {
$.get($this.attr('href'), {'ajax_request': true}, showExport);
}
PMA_ajaxRemoveMessage($msg);
function showExport(data) {
if (data.success === true) {

View File

@ -36,6 +36,23 @@ function PMA_urlencode(str)
}
}
/**
* Saves SQL query in local storage or cooie
*
* @param string SQL query
* @return void
*/
function PMA_autosaveSQL(query)
{
if (query) {
if (isStorageSupported('localStorage')) {
window.localStorage.auto_saved_sql = query;
} else {
$.cookie('auto_saved_sql', query);
}
}
}
/**
* Get the field name for the current field. Required to construct the query
* for grid editing
@ -135,17 +152,11 @@ AJAX.registerOnload('sql.js', function () {
$(function () {
if (codemirror_editor) {
codemirror_editor.on('change', function () {
var query = codemirror_editor.getValue();
if (query) {
$.cookie('auto_saved_sql', query);
}
PMA_autosaveSQL(codemirror_editor.getValue());
});
} else {
$('#sqlquery').on('input propertychange', function () {
var query = $('#sqlquery').val();
if (query) {
$.cookie('auto_saved_sql', query);
}
PMA_autosaveSQL($('#sqlquery').val());
});
}
});

View File

@ -100,7 +100,7 @@ function isDate(val, tmstmp)
}
val = arrayVal.join("-");
var pos = 2;
var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[1-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[1-9])|([1-2][0-9])|30)))$/);
var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/);
if (val.length == 8) {
pos = 0;
}
@ -143,7 +143,7 @@ function isTime(val)
}
}
val = arrayVal.join(":");
var tmexp = new RegExp(/^(([0-1][0-9])|(2[0-3])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
return tmexp.test(val);
}
@ -551,8 +551,9 @@ AJAX.registerOnload('tbl_change.js', function () {
}
// handle input text fields and textareas
if ($this_element.is('.textfield') || $this_element.is('.char')) {
if ($this_element.is('.textfield') || $this_element.is('.char') || $this_element.is('textarea')) {
// do not remove the 'value' attribute for ENUM columns
// special handling for radio fields after updating ids to unique - see below
if ($this_element.closest('tr').find('span.column_type').html() != 'enum') {
$this_element.val($this_element.closest('tr').find('span.default_value').html());
}
@ -675,6 +676,15 @@ AJAX.registerOnload('tbl_change.js', function () {
$(this).attr('tabindex', tabindex);
// update the IDs of textfields to ensure that they are unique
$(this).attr('id', "field_" + tabindex + "_3");
// special handling for radio fields after updating ids to unique
if ($(this).closest('tr').find('span.column_type').html() === 'enum') {
if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) {
$(this).prop('checked', true);
} else {
$(this).prop('checked', false);
}
}
});
$('.control_at_footer')
.each(function () {

View File

@ -201,7 +201,7 @@ AJAX.registerOnload('tbl_structure.js', function () {
/**
* @var curr_column_name String containing name of the field referred to by {@link curr_row}
*/
var curr_column_name = $curr_row.children('th').children('label').text();
var curr_column_name = $curr_row.children('th').children('label').text().trim();
curr_column_name = escapeHtml(curr_column_name);
/**
* @var $after_field_item Corresponding entry in the 'After' field.
@ -233,8 +233,16 @@ AJAX.registerOnload('tbl_structure.js', function () {
}
$after_field_item.remove();
$curr_row.hide("medium").remove();
//by default select the last option to add new column (in case last column is dropped)
// Remove the dropped column from select menu for 'after field'
$("select[name=after_field]").find(
'[value="' + curr_column_name + '"]'
).remove();
// by default select the (new) last option to add new column
// (in case last column is dropped)
$("select[name=after_field] option:last").attr("selected","selected");
//refresh table stats
if (data.tableStat) {
$('#tablestatistics').html(data.tableStat);
@ -267,7 +275,7 @@ AJAX.registerOnload('tbl_structure.js', function () {
var $this = $(this);
var curr_table_name = $this.closest('form').find('input[name=table]').val();
var curr_column_name = $this.parents('tr').children('th').children('label').text();
var curr_column_name = $this.parents('tr').children('th').children('label').text().trim();
var add_clause = '';
if ($this.is('.add_primary_key_anchor')) {

View File

@ -18,6 +18,7 @@ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// Avoid loading the full common.inc.php because this would add many
// non-js-compatible stuff like DOCTYPE
define('PMA_MINIMUM_COMMON', true);
define('PMA_PATH_TO_BASEDIR', '../');
require_once './libraries/common.inc.php';
// Close session early as we won't write anything there
session_write_close();

View File

@ -352,7 +352,7 @@ class Advisor
*/
private function replaceLinkURL($matches)
{
return 'href="' . PMA_linkURL($matches[2]) . '" target="_blank"';
return 'href="' . PMA_linkURL($matches[2]) . '" target="_blank" rel="noopener noreferrer"';
}
/**
@ -455,10 +455,21 @@ class Advisor
*/
public static function parseRulesFile()
{
$file = file('libraries/advisory_rules.txt', FILE_IGNORE_NEW_LINES);
$filename = 'libraries/advisory_rules.txt';
$file = file($filename, FILE_IGNORE_NEW_LINES);
$errors = array();
$rules = array();
$lines = array();
if ($file === FALSE) {
$errors[] = sprintf(
__('Error in reading file: The file \'%s\' does not exist or is not readable!'),
$filename
);
return array('rules' => $rules, 'lines' => $lines, 'errors' => $errors);
}
$ruleSyntax = array(
'name', 'formula', 'test', 'issue', 'recommendation', 'justification'
);

View File

@ -101,7 +101,7 @@ class Config
*/
public function checkSystem()
{
$this->set('PMA_VERSION', '4.6.4');
$this->set('PMA_VERSION', '4.6.5');
/**
* @deprecated
*/
@ -193,20 +193,20 @@ class Config
// (must check everything else before Mozilla)
$is_mozilla = preg_match(
'@Mozilla/([0-9].[0-9]{1,2})@',
'@Mozilla/([0-9]\.[0-9]{1,2})@',
$HTTP_USER_AGENT,
$mozilla_version
);
if (preg_match(
'@Opera(/| )([0-9].[0-9]{1,2})@',
'@Opera(/| )([0-9]\.[0-9]{1,2})@',
$HTTP_USER_AGENT,
$log_version
)) {
$this->set('PMA_USR_BROWSER_VER', $log_version[2]);
$this->set('PMA_USR_BROWSER_AGENT', 'OPERA');
} elseif (preg_match(
'@(MS)?IE ([0-9]{1,2}.[0-9]{1,2})@',
'@(MS)?IE ([0-9]{1,2}\.[0-9]{1,2})@',
$HTTP_USER_AGENT,
$log_version
)) {
@ -220,7 +220,7 @@ class Config
$this->set('PMA_USR_BROWSER_VER', intval($log_version[1]) + 4);
$this->set('PMA_USR_BROWSER_AGENT', 'IE');
} elseif (preg_match(
'@OmniWeb/([0-9].[0-9]{1,2})@',
'@OmniWeb/([0-9]{1,3})@',
$HTTP_USER_AGENT,
$log_version
)) {
@ -265,7 +265,7 @@ class Config
'PMA_USR_BROWSER_VER', $log_version[1]
);
$this->set('PMA_USR_BROWSER_AGENT', 'FIREFOX');
} elseif (preg_match('@rv:1.9(.*)Gecko@', $HTTP_USER_AGENT)) {
} elseif (preg_match('@rv:1\.9(.*)Gecko@', $HTTP_USER_AGENT)) {
$this->set('PMA_USR_BROWSER_VER', '1.9');
$this->set('PMA_USR_BROWSER_AGENT', 'GECKO');
} elseif ($is_mozilla) {
@ -400,10 +400,11 @@ class Config
$branch = false;
// are we on any branch?
if (mb_strstr($ref_head, '/')) {
$ref_head = mb_substr(trim($ref_head), 5);
if (strstr($ref_head, '/')) {
// remove ref: prefix
$ref_head = substr(trim($ref_head), 5);
if (substr($ref_head, 0, 11) === 'refs/heads/') {
$branch = mb_substr($ref_head, 11);
$branch = substr($ref_head, 11);
} else {
$branch = basename($ref_head);
}
@ -450,7 +451,9 @@ class Config
}
$commit = false;
if (isset($_SESSION['PMA_VERSION_COMMITDATA_' . $hash])) {
if (! preg_match('/^[0-9a-f]{40}$/i', $hash)) {
$commit = false;
} elseif (isset($_SESSION['PMA_VERSION_COMMITDATA_' . $hash])) {
$commit = $_SESSION['PMA_VERSION_COMMITDATA_' . $hash];
} elseif (function_exists('gzuncompress')) {
$git_file_name = $git_folder . '/objects/'
@ -1357,8 +1360,12 @@ class Config
return $this->get('is_https');
}
$url = $this->get('PmaAbsoluteUri');
$is_https = false;
if (strtolower(PMA_getenv('HTTP_SCHEME')) == 'https') {
if (! empty($url) && parse_url($url, PHP_URL_SCHEME) === 'https') {
$is_https = true;
} elseif (strtolower(PMA_getenv('HTTP_SCHEME')) == 'https') {
$is_https = true;
} elseif (strtolower(PMA_getenv('HTTPS')) == 'on') {
$is_https = true;
@ -1381,11 +1388,11 @@ class Config
}
/**
* Get cookie path
* Get phpMyAdmin root path
*
* @return string
*/
public function getCookiePath()
public function getRootPath()
{
static $cookie_path = null;
@ -1393,6 +1400,18 @@ class Config
return $cookie_path;
}
$url = $this->get('PmaAbsoluteUri');
if (! empty($url)) {
$path = parse_url($url, PHP_URL_PATH);
if (! empty($path)) {
if (substr($path, -1) != '/') {
return $path . '/';
}
return $path;
}
}
$parsed_url = parse_url($GLOBALS['PMA_PHP_SELF']);
$parts = explode(
@ -1577,7 +1596,7 @@ class Config
$cookie,
'',
time() - 3600,
$this->getCookiePath(),
$this->getRootPath(),
'',
$this->isHttps()
);
@ -1631,7 +1650,7 @@ class Config
$cookie,
$value,
$validity,
$this->getCookiePath(),
$this->getRootPath(),
'',
$this->isHttps(),
$httponly

View File

@ -307,13 +307,13 @@ class DatabaseInterface
if (true === $tbl_is_group) {
$sql_where_table = 'AND t.`TABLE_NAME` LIKE \''
. Util::escapeMysqlWildcards(
Util::sqlAddSlashes($table)
$GLOBALS['dbi']->escapeString($table)
)
. '%\'';
} else {
$sql_where_table = 'AND t.`TABLE_NAME` '
. Util::getCollateForIS() . ' = \''
. Util::sqlAddSlashes($table) . '\'';
. $GLOBALS['dbi']->escapeString($table) . '\'';
}
} else {
$sql_where_table = '';
@ -428,7 +428,7 @@ class DatabaseInterface
// comparison (if we are looking for the db Aa we don't want
// to find the db aa)
$this_databases = array_map(
'PMA\libraries\Util::sqlAddSlashes',
array($this, 'escapeString'),
$databases
);
@ -490,7 +490,7 @@ class DatabaseInterface
if ($table || (true === $tbl_is_group)) {
$sql .= " `Name` LIKE '"
. Util::escapeMysqlWildcards(
Util::sqlAddSlashes($table, true)
$this->escapeString($table, $link)
)
. "%'";
$needAnd = true;
@ -851,7 +851,7 @@ class DatabaseInterface
// get table information from information_schema
if (! empty($database)) {
$sql_where_schema = 'WHERE `SCHEMA_NAME` LIKE \''
. Util::sqlAddSlashes($database) . '\'';
. $this->escapeString($database, $link) . '\'';
} else {
$sql_where_schema = '';
}
@ -1090,19 +1090,19 @@ class DatabaseInterface
// get columns information from information_schema
if (null !== $database) {
$sql_wheres[] = '`TABLE_SCHEMA` = \''
. Util::sqlAddSlashes($database) . '\' ';
. $this->escapeString($database, $link) . '\' ';
} else {
$array_keys[] = 'TABLE_SCHEMA';
}
if (null !== $table) {
$sql_wheres[] = '`TABLE_NAME` = \''
. Util::sqlAddSlashes($table) . '\' ';
. $this->escapeString($table, $link) . '\' ';
} else {
$array_keys[] = 'TABLE_NAME';
}
if (null !== $column) {
$sql_wheres[] = '`COLUMN_NAME` = \''
. Util::sqlAddSlashes($column) . '\' ';
. $this->escapeString($column, $link) . '\' ';
} else {
$array_keys[] = 'COLUMN_NAME';
}
@ -1147,7 +1147,7 @@ class DatabaseInterface
$sql = 'SHOW FULL COLUMNS FROM '
. Util::backquote($database) . '.' . Util::backquote($table);
if (null !== $column) {
$sql .= " LIKE '" . Util::sqlAddSlashes($column, true) . "'";
$sql .= " LIKE '" . $this->escapeString($column, $link) . "'";
}
$columns = $this->fetchResult($sql, 'Field', null, $link);
@ -1235,7 +1235,7 @@ class DatabaseInterface
$sql = 'SHOW ' . ($full ? 'FULL' : '') . ' COLUMNS FROM '
. Util::backquote($database) . '.' . Util::backquote($table)
. (($column !== null) ? "LIKE '"
. Util::sqlAddSlashes($column, true) . "'" : '');
. $GLOBALS['dbi']->escapeString($column) . "'" : '');
return $sql;
}
@ -1417,80 +1417,37 @@ class DatabaseInterface
public function postConnect($link)
{
if (! defined('PMA_MYSQL_INT_VERSION')) {
if (Util::cacheExists('PMA_MYSQL_INT_VERSION')) {
$version = $this->fetchSingleRow(
'SELECT @@version, @@version_comment',
'ASSOC',
$link
);
if ($version) {
$match = explode('.', $version['@@version']);
define('PMA_MYSQL_MAJOR_VERSION', (int)$match[0]);
define(
'PMA_MYSQL_INT_VERSION',
Util::cacheGet('PMA_MYSQL_INT_VERSION')
);
define(
'PMA_MYSQL_MAJOR_VERSION',
Util::cacheGet('PMA_MYSQL_MAJOR_VERSION')
);
define(
'PMA_MYSQL_STR_VERSION',
Util::cacheGet('PMA_MYSQL_STR_VERSION')
(int) sprintf(
'%d%02d%02d', $match[0], $match[1], intval($match[2])
)
);
define('PMA_MYSQL_STR_VERSION', $version['@@version']);
define(
'PMA_MYSQL_VERSION_COMMENT',
Util::cacheGet('PMA_MYSQL_VERSION_COMMENT')
);
define(
'PMA_MARIADB',
Util::cacheGet('PMA_MARIADB')
$version['@@version_comment']
);
} else {
$version = $this->fetchSingleRow(
'SELECT @@version, @@version_comment',
'ASSOC',
$link
);
if ($version) {
$match = explode('.', $version['@@version']);
define('PMA_MYSQL_MAJOR_VERSION', (int)$match[0]);
define(
'PMA_MYSQL_INT_VERSION',
(int) sprintf(
'%d%02d%02d', $match[0], $match[1], intval($match[2])
)
);
define('PMA_MYSQL_STR_VERSION', $version['@@version']);
define(
'PMA_MYSQL_VERSION_COMMENT',
$version['@@version_comment']
);
} else {
define('PMA_MYSQL_INT_VERSION', 50501);
define('PMA_MYSQL_MAJOR_VERSION', 5);
define('PMA_MYSQL_STR_VERSION', '5.05.01');
define('PMA_MYSQL_VERSION_COMMENT', '');
}
Util::cacheSet(
'PMA_MYSQL_INT_VERSION',
PMA_MYSQL_INT_VERSION
);
Util::cacheSet(
'PMA_MYSQL_MAJOR_VERSION',
PMA_MYSQL_MAJOR_VERSION
);
Util::cacheSet(
'PMA_MYSQL_STR_VERSION',
PMA_MYSQL_STR_VERSION
);
Util::cacheSet(
'PMA_MYSQL_VERSION_COMMENT',
PMA_MYSQL_VERSION_COMMENT
);
/* Detect MariaDB */
if (mb_strpos(PMA_MYSQL_STR_VERSION, 'MariaDB') !== false) {
define('PMA_MARIADB', true);
} else {
define('PMA_MARIADB', false);
}
Util::cacheSet(
'PMA_MARIADB',
PMA_MARIADB
);
define('PMA_MYSQL_INT_VERSION', 50501);
define('PMA_MYSQL_MAJOR_VERSION', 5);
define('PMA_MYSQL_STR_VERSION', '5.05.01');
define('PMA_MYSQL_VERSION_COMMENT', '');
}
/* Detect MariaDB */
if (mb_strpos(PMA_MYSQL_STR_VERSION, 'MariaDB') !== false) {
define('PMA_MARIADB', true);
} else {
define('PMA_MARIADB', false);
}
}
@ -1518,7 +1475,7 @@ class DatabaseInterface
}
$result = $this->tryQuery(
"SET collation_connection = '"
. Util::sqlAddSlashes($GLOBALS['collation_connection'])
. $this->escapeString($GLOBALS['collation_connection'], $link)
. "';",
$link,
self::QUERY_STORE
@ -1530,7 +1487,7 @@ class DatabaseInterface
);
$this->query(
"SET collation_connection = '"
. Util::sqlAddSlashes($default_collation)
. $this->escapeString($GLOBALS['collation_connection'], $link)
. "';",
$link,
self::QUERY_STORE
@ -1867,10 +1824,11 @@ class DatabaseInterface
* @param string $db db name
* @param string $which PROCEDURE | FUNCTION | EVENT | VIEW
* @param string $name the procedure|function|event|view name
* @param object $link MySQL link
*
* @return string the definition
*/
public function getDefinition($db, $which, $name)
public function getDefinition($db, $which, $name, $link = null)
{
$returned_field = array(
'PROCEDURE' => 'Create Procedure',
@ -1881,7 +1839,7 @@ class DatabaseInterface
$query = 'SHOW CREATE ' . $which . ' '
. Util::backquote($db) . '.'
. Util::backquote($name);
return($this->fetchValue($query, 0, $returned_field[$which]));
return($this->fetchValue($query, 0, $returned_field[$which], $link));
}
/**
@ -1913,13 +1871,13 @@ class DatabaseInterface
. " `DTD_IDENTIFIER`"
. " FROM `information_schema`.`ROUTINES`"
. " WHERE `ROUTINE_SCHEMA` " . Util::getCollateForIS()
. " = '" . Util::sqlAddSlashes($db) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($db) . "'";
if (PMA_isValid($which, array('FUNCTION','PROCEDURE'))) {
$query .= " AND `ROUTINE_TYPE` = '" . $which . "'";
}
if (! empty($name)) {
$query .= " AND `SPECIFIC_NAME`"
. " = '" . Util::sqlAddSlashes($name) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($name) . "'";
}
$result = $this->fetchResult($query);
if (!empty($result)) {
@ -1928,10 +1886,10 @@ class DatabaseInterface
} else {
if ($which == 'FUNCTION' || $which == null) {
$query = "SHOW FUNCTION STATUS"
. " WHERE `Db` = '" . Util::sqlAddSlashes($db) . "'";
. " WHERE `Db` = '" . $GLOBALS['dbi']->escapeString($db) . "'";
if (! empty($name)) {
$query .= " AND `Name` = '"
. Util::sqlAddSlashes($name) . "'";
. $GLOBALS['dbi']->escapeString($name) . "'";
}
$result = $this->fetchResult($query);
if (!empty($result)) {
@ -1940,10 +1898,10 @@ class DatabaseInterface
}
if ($which == 'PROCEDURE' || $which == null) {
$query = "SHOW PROCEDURE STATUS"
. " WHERE `Db` = '" . Util::sqlAddSlashes($db) . "'";
. " WHERE `Db` = '" . $GLOBALS['dbi']->escapeString($db) . "'";
if (! empty($name)) {
$query .= " AND `Name` = '"
. Util::sqlAddSlashes($name) . "'";
. $GLOBALS['dbi']->escapeString($name) . "'";
}
$result = $this->fetchResult($query);
if (!empty($result)) {
@ -2003,16 +1961,16 @@ class DatabaseInterface
. "`DATABASE_COLLATION` AS `Database Collation`"
. " FROM `information_schema`.`EVENTS`"
. " WHERE `EVENT_SCHEMA` " . Util::getCollateForIS()
. " = '" . Util::sqlAddSlashes($db) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($db) . "'";
if (! empty($name)) {
$query .= " AND `EVENT_NAME`"
. " = '" . Util::sqlAddSlashes($name) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($name) . "'";
}
} else {
$query = "SHOW EVENTS FROM " . Util::backquote($db);
if (! empty($name)) {
$query .= " AND `Name` = '"
. Util::sqlAddSlashes($name) . "'";
. $GLOBALS['dbi']->escapeString($name) . "'";
}
}
@ -2055,16 +2013,16 @@ class DatabaseInterface
. ', EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER'
. ' FROM information_schema.TRIGGERS'
. ' WHERE EVENT_OBJECT_SCHEMA ' . Util::getCollateForIS() . '='
. ' \'' . Util::sqlAddSlashes($db) . '\'';
. ' \'' . $GLOBALS['dbi']->escapeString($db) . '\'';
if (! empty($table)) {
$query .= " AND EVENT_OBJECT_TABLE " . Util::getCollateForIS()
. " = '" . Util::sqlAddSlashes($table) . "';";
. " = '" . $GLOBALS['dbi']->escapeString($table) . "';";
}
} else {
$query = "SHOW TRIGGERS FROM " . Util::backquote($db);
if (! empty($table)) {
$query .= " LIKE '" . Util::sqlAddSlashes($table, true) . "';";
$query .= " LIKE '" . $GLOBALS['dbi']->escapeString($table) . "';";
}
}
@ -2351,21 +2309,12 @@ class DatabaseInterface
$user, $password, $is_controluser = false, $server = null,
$auxiliary_connection = false
) {
$error_count = $GLOBALS['error_handler']->countErrors();
// Do not show location and backtrace for connection errors
$GLOBALS['error_handler']->setHideLocation(true);
$result = $this->_extension->connect(
$user, $password, $is_controluser, $server, $auxiliary_connection
);
/* Any errors from connection? */
if ($GLOBALS['error_handler']->countErrors() > $error_count) {
$errors = $GLOBALS['error_handler']->sliceErrors($error_count);
foreach ($errors as $error) {
trigger_error(
$error->getMessage(),
E_USER_ERROR
);
}
}
$GLOBALS['error_handler']->setHideLocation(false);
if ($result) {
if (! $auxiliary_connection && ! $is_controluser) {
@ -2700,6 +2649,27 @@ class DatabaseInterface
return $this->_extension->fieldFlags($result, $i);
}
/**
* returns properly escaped string for use in MySQL queries
*
* @param string $str string to be escaped
* @param mixed $link optional database link to use
*
* @return string a MySQL escaped string
*/
public function escapeString($str, $link = null)
{
if ($link === null) {
$link = $this->getLink();
}
if ($this->_extension === null) {
return $str;
}
return $this->_extension->escapeString($link, $str);
}
/**
* Gets server connection port
*

View File

@ -1940,7 +1940,10 @@ class DbQbe
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
$this->_criteria_row_count = min(
100,
max($rows + $criteriaRowAdd, 0)
);
return $criteriaColumnCount;
}

View File

@ -139,7 +139,7 @@ class DbSearch
) {
unset($this->_criteriaColumnName);
} else {
$this->_criteriaColumnName = Util::sqlAddSlashes(
$this->_criteriaColumnName = $GLOBALS['dbi']->escapeString(
$_REQUEST['criteriaColumnName'], true
);
}
@ -203,9 +203,8 @@ class DbSearch
// For "as regular expression" (search option 4), LIKE won't be used
// Usage example: If user is searching for a literal $ in a regexp search,
// he should enter \$ as the value.
$criteriaSearchStringEscaped = Util::sqlAddSlashes(
$this->_criteriaSearchString,
($this->_criteriaSearchType == 4 ? false : true)
$criteriaSearchStringEscaped = $GLOBALS['dbi']->escapeString(
$this->_criteriaSearchString
);
// Extract search words or pattern
$search_words = (($this->_criteriaSearchType > 2)
@ -335,29 +334,22 @@ class DbSearch
$html_output .= '</td>';
// Displays browse/delete link if result count > 0
if ($res_cnt > 0) {
$this_url_params['sql_query'] = $newsearchsqls['select_columns'];
$this_url_params['db'] = htmlspecialchars($GLOBALS['db']);
$this_url_params['table'] = htmlspecialchars($each_table);
$browse_result_path = 'sql.php' . PMA_URL_getCommon($this_url_params);
$html_output .= '<td><a name="browse_search" class="ajax" href="'
. $browse_result_path . '" onclick="loadResult(\''
. $browse_result_path . '\',\''
. PMA_escapeJsString(htmlspecialchars($each_table)) . '\',\''
. PMA_URL_getCommon(
array(
'db' => $GLOBALS['db'], 'table' => $each_table
)
) . '\''
. ');return false;" >'
$html_output .= '<td><a name="browse_search" '
. ' class="ajax browse_results" href="'
. $browse_result_path . '" '
. 'data-browse-sql="'
. htmlspecialchars($newsearchsqls['select_columns']). '" '
. 'data-table-name="' . htmlspecialchars($each_table) . '" >'
. __('Browse') . '</a></td>';
$this_url_params['sql_query'] = $newsearchsqls['delete'];
$delete_result_path = 'sql.php' . PMA_URL_getCommon($this_url_params);
$html_output .= '<td><a name="delete_search" class="ajax" href="'
. $delete_result_path . '" onclick="deleteResult(\''
. $delete_result_path . '\' , \''
. PMA_escapeJsString(sprintf(
__('Delete the matches for the %s table?'),
htmlspecialchars($each_table)
))
. '\');return false;">'
$delete_result_path = $browse_result_path;
$html_output .= '<td><a name="delete_search" class="ajax delete_results"'
. ' href="' . $delete_result_path . '"'
. ' data-delete-sql="' . htmlspecialchars($newsearchsqls['delete']) . '"'
. ' data-table-name="' . htmlspecialchars($each_table) . '" >'
. __('Delete') . '</a></td>';
} else {
$html_output .= '<td>&nbsp;</td>'

View File

@ -868,9 +868,10 @@ class DisplayResults
$endpos = $_SESSION['tmpval']['pos']
+ $_SESSION['tmpval']['max_rows'];
if (($endpos < $this->__get('unlim_num_rows'))
&& ($this->__get('num_rows') >= $_SESSION['tmpval']['max_rows'])
&& ($_SESSION['tmpval']['max_rows'] != self::ALL_ROWS)
if ($this->__get('unlim_num_rows') === false // view with unknown number of rows
|| ($endpos < $this->__get('unlim_num_rows')
&& $this->__get('num_rows') >= $_SESSION['tmpval']['max_rows']
&& $_SESSION['tmpval']['max_rows'] != self::ALL_ROWS)
) {
$table_navigation_html
@ -1076,12 +1077,12 @@ class DisplayResults
$maxRows = $_SESSION['tmpval']['max_rows'];
$onsubmit = 'onsubmit="return '
. ($_SESSION['tmpval']['pos']
. (($_SESSION['tmpval']['pos']
+ $maxRows
< $this->__get('unlim_num_rows')
&& $this->__get('num_rows') >= $maxRows)
? 'true'
: 'false' . '"';
: 'false') . '"';
// display the End button
$buttons_html .= $this->_getTableNavigationButton(
@ -3277,7 +3278,7 @@ class DisplayResults
$divider = strpos($link_relations['default_page'], '?') ? '&' : '?';
if (empty($link_relations['link_dependancy_params'])) {
return $link_relations['default_page']
. PMA_URL_getCommon($linking_url_params, 'html', $divider);
. PMA_URL_getCommon($linking_url_params, 'raw', $divider);
}
foreach ($link_relations['link_dependancy_params'] as $new_param) {
@ -3301,7 +3302,7 @@ class DisplayResults
}
return $link_relations['default_page']
. PMA_URL_getCommon($linking_url_params, 'html', $divider);
. PMA_URL_getCommon($linking_url_params, 'raw', $divider);
}
@ -4040,7 +4041,7 @@ class DisplayResults
|| $bool_nowrap) ? ' nowrap' : '';
$where_comparison = ' = \''
. Util::sqlAddSlashes($column)
. $GLOBALS['dbi']->escapeString($column)
. '\'';
$cell = $this->_getRowData(

View File

@ -83,6 +83,11 @@ class Error extends Message
*/
protected $backtrace = array();
/**
* Hide location of errors
*/
protected $hide_location = false;
/**
* Constructor
*
@ -146,6 +151,18 @@ class Error extends Message
return $result;
}
/**
* Toggles location hiding
*
* @param boolean $hide Whether to hide
*
* @return void
*/
public function setHideLocation($hide)
{
$this->hide_location = $hide;
}
/**
* sets PMA\libraries\Error::$_backtrace
*
@ -441,7 +458,8 @@ class Error extends Message
*/
public function isUserError()
{
return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
return $this->hide_location ||
($this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE));
}
/**
@ -460,7 +478,7 @@ class Error extends Message
/* Probably affected by open_basedir */
if ($dest === FALSE) {
return $path;
return basename($path);
}
$Ahere = explode(

View File

@ -23,6 +23,11 @@ class ErrorHandler
*/
protected $errors = array();
/**
* Hide location of errors
*/
protected $hide_location = false;
/**
* Constructor - set PHP error handler
*
@ -77,6 +82,18 @@ class ErrorHandler
}
}
/**
* Toggles location hiding
*
* @param boolean $hide Whether to hide
*
* @return void
*/
public function setHideLocation($hide)
{
$this->hide_location = $hide;
}
/**
* returns array with all errors
*
@ -170,21 +187,25 @@ class ErrorHandler
$errfile,
$errline
);
$error->setHideLocation($this->hide_location);
// do not repeat errors
$this->errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
case E_USER_NOTICE:
case E_USER_WARNING:
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
/* Avoid rendering BB code in PHP errors */
$error->setBBCode(false);
break;
case E_USER_NOTICE:
case E_USER_WARNING:
case E_USER_ERROR:
// just collect the error
// display is called from outside
break;

View File

@ -70,9 +70,9 @@ class Footer
include './revision-info.php';
$message .= sprintf(
__('Currently running Git revision %1$s from the %2$s branch.'),
'<a target="_blank" href="' . $repobase . $fullrevision . '">'
'<a target="_blank" rel="noopener noreferrer" href="' . $repobase . $fullrevision . '">'
. $revision . '</a>',
'<a target="_blank" href="' . $repobranchbase . $branch . '">'
'<a target="_blank" rel="noopener noreferrer" href="' . $repobranchbase . $branch . '">'
. $branch . '</a>'
);
} else {
@ -196,7 +196,7 @@ class Footer
$retval = '';
$retval .= '<div id="selflink" class="print_ignore">';
$retval .= '<a href="' . $url . '"'
. ' title="' . __('Open new phpMyAdmin window') . '" target="_blank">';
. ' title="' . __('Open new phpMyAdmin window') . '" target="_blank" rel="noopener noreferrer">';
if (Util::showIcons('TabsMode')) {
$retval .= Util::getImage(
'window-new.png',
@ -240,6 +240,10 @@ class Footer
if (! PMA_isValid($_REQUEST['no_history'])
&& empty($GLOBALS['error_message'])
&& ! empty($GLOBALS['sql_query'])
&& (isset($GLOBALS['dbi'])
&& ($GLOBALS['dbi']->getLink()
|| isset($GLOBALS['controllink'])
&& $GLOBALS['controllink']))
) {
PMA_setHistory(
PMA_ifSetOr($GLOBALS['db'], ''),

View File

@ -819,9 +819,8 @@ class LanguageManager
$langs = $this->availableLanguages();
// try to find out user's language by checking its HTTP_ACCEPT_LANGUAGE variable;
// prevent XSS
$accepted_languages = PMA_getenv('HTTP_ACCEPT_LANGUAGE');
if ($accepted_languages && false === mb_strpos($accepted_languages, '<')) {
if ($accepted_languages) {
foreach (explode(',', $accepted_languages) as $header) {
foreach ($langs as $language) {
if ($language->matchesAcceptLanguage($header)) {

View File

@ -51,7 +51,7 @@ class Linter
// (which is actually a new line) aren't going to be processed at
// all.
$len = ($str instanceof UtfString) ?
$str->length() : strlen($len);
$str->length() : strlen($str);
$lines = array(0);
for ($i = 0; $i < $len; ++$i) {

View File

@ -139,7 +139,7 @@ class Menu
. " AND `tab` LIKE '" . $level . "%'"
. " AND `usergroup` = (SELECT usergroup FROM "
. $userTable . " WHERE `username` = '"
. Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "')";
. $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "')";
$result = PMA_queryAsControlUser($sql_query, false);
if ($result) {

View File

@ -112,6 +112,14 @@ class Message
*/
protected $isDisplayed = false;
/**
* Whether to use BB code when displaying.
*
* @access protected
* @var boolean
*/
protected $useBBCode = true;
/**
* Unique id
*
@ -236,6 +244,7 @@ class Message
{
$r = new Message('', $type);
$r->setMessage($message);
$r->setBBCode(false);
return $r;
}
@ -392,6 +401,18 @@ class Message
return $this->getNumber() === Message::ERROR;
}
/**
* Set whether we should use BB Code when rendering.
*
* @param boolean $useBBCode Use BB Code?
*
* @return void
*/
public function setBBCode($useBBCode)
{
$this->useBBCode = $useBBCode;
}
/**
* set raw message (overrides string)
*
@ -647,7 +668,9 @@ class Message
$message = Message::format($message, $this->getParams());
}
$message = Message::decodeBB($message);
if ($this->useBBCode) {
$message = Message::decodeBB($message);
}
foreach ($this->getAddedMessages() as $add_message) {
$message .= $add_message;

View File

@ -153,8 +153,8 @@ class Partition extends SubPartition
if (Partition::havePartitioning()) {
$result = $GLOBALS['dbi']->fetchResult(
"SELECT * FROM `information_schema`.`PARTITIONS`"
. " WHERE `TABLE_SCHEMA` = '" . Util::sqlAddSlashes($db)
. "' AND `TABLE_NAME` = '" . Util::sqlAddSlashes($table) . "'"
. " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db)
. "' AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'"
);
if ($result) {
$partitionMap = array();
@ -193,9 +193,9 @@ class Partition extends SubPartition
{
if (Partition::havePartitioning()) {
return $GLOBALS['dbi']->fetchResult(
"SELECT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS`"
. " WHERE `TABLE_SCHEMA` = '" . Util::sqlAddSlashes($db)
. "' AND `TABLE_NAME` = '" . Util::sqlAddSlashes($table) . "'"
"SELECT DISTINCT `PARTITION_NAME` FROM `information_schema`.`PARTITIONS`"
. " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db)
. "' AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'"
);
} else {
return array();
@ -215,8 +215,9 @@ class Partition extends SubPartition
if (Partition::havePartitioning()) {
$partition_method = $GLOBALS['dbi']->fetchResult(
"SELECT `PARTITION_METHOD` FROM `information_schema`.`PARTITIONS`"
. " WHERE `TABLE_SCHEMA` = '" . Util::sqlAddSlashes($db) . "'"
. " AND `TABLE_NAME` = '" . Util::sqlAddSlashes($table) . "'"
. " WHERE `TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($db) . "'"
. " AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($table) . "'"
. " LIMIT 1"
);
if (! empty($partition_method)) {
return $partition_method[0];

View File

@ -96,7 +96,7 @@ class RecentFavoriteTable
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->_getPmaTable() .
" WHERE `username` = '" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'";
" WHERE `username` = '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'";
$return = array();
$result = PMA_queryAsControlUser($sql_query, false);
@ -119,8 +119,8 @@ class RecentFavoriteTable
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query
= " REPLACE INTO " . $this->_getPmaTable() . " (`username`, `tables`)" .
" VALUES ('" . Util::sqlAddSlashes($username) . "', '"
. Util::sqlAddSlashes(
" VALUES ('" . $GLOBALS['dbi']->escapeString($username) . "', '"
. $GLOBALS['dbi']->escapeString(
json_encode($this->_tables)
) . "')";

View File

@ -160,6 +160,16 @@ class SavedSearches
}
}
/* Limit amount of rows */
if (!isset($data['rows'])) {
$data['rows'] = 0;
} else {
$data['rows'] = min(
max(0, intval($data['rows'])),
100
);
}
for ($i = 0; $i <= $data['rows']; $i++) {
$data['Or' . $i] = $criterias['Or' . $i];
}
@ -273,7 +283,7 @@ class SavedSearches
//If it's an insert.
if (null === $this->getId()) {
$wheres = array(
"search_name = '" . Util::sqlAddSlashes($this->getSearchName())
"search_name = '" . $GLOBALS['dbi']->escapeString($this->getSearchName())
. "'"
);
$existingSearches = $this->getList($wheres);
@ -292,10 +302,10 @@ class SavedSearches
$sqlQuery = "INSERT INTO " . $savedSearchesTbl
. "(`username`, `db_name`, `search_name`, `search_data`)"
. " VALUES ("
. "'" . Util::sqlAddSlashes($this->getUsername()) . "',"
. "'" . Util::sqlAddSlashes($this->getDbname()) . "',"
. "'" . Util::sqlAddSlashes($this->getSearchName()) . "',"
. "'" . Util::sqlAddSlashes(json_encode($this->getCriterias()))
. "'" . $GLOBALS['dbi']->escapeString($this->getUsername()) . "',"
. "'" . $GLOBALS['dbi']->escapeString($this->getDbname()) . "',"
. "'" . $GLOBALS['dbi']->escapeString($this->getSearchName()) . "',"
. "'" . $GLOBALS['dbi']->escapeString(json_encode($this->getCriterias()))
. "')";
$result = (bool)PMA_queryAsControlUser($sqlQuery);
@ -311,7 +321,7 @@ class SavedSearches
//Else, it's an update.
$wheres = array(
"id != " . $this->getId(),
"search_name = '" . Util::sqlAddSlashes($this->getSearchName()) . "'"
"search_name = '" . $GLOBALS['dbi']->escapeString($this->getSearchName()) . "'"
);
$existingSearches = $this->getList($wheres);
@ -328,9 +338,9 @@ class SavedSearches
$sqlQuery = "UPDATE " . $savedSearchesTbl
. "SET `search_name` = '"
. Util::sqlAddSlashes($this->getSearchName()) . "', "
. $GLOBALS['dbi']->escapeString($this->getSearchName()) . "', "
. "`search_data` = '"
. Util::sqlAddSlashes(json_encode($this->getCriterias())) . "' "
. $GLOBALS['dbi']->escapeString(json_encode($this->getCriterias())) . "' "
. "WHERE id = " . $this->getId();
return (bool)PMA_queryAsControlUser($sqlQuery);
}
@ -358,7 +368,7 @@ class SavedSearches
. Util::backquote($this->_config['cfgRelation']['savedsearches']);
$sqlQuery = "DELETE FROM " . $savedSearchesTbl
. "WHERE id = '" . Util::sqlAddSlashes($this->getId()) . "'";
. "WHERE id = '" . $GLOBALS['dbi']->escapeString($this->getId()) . "'";
return (bool)PMA_queryAsControlUser($sqlQuery);
}
@ -386,7 +396,7 @@ class SavedSearches
. Util::backquote($this->_config['cfgRelation']['savedsearches']);
$sqlQuery = "SELECT id, search_name, search_data "
. "FROM " . $savedSearchesTbl . " "
. "WHERE id = '" . Util::sqlAddSlashes($this->getId()) . "' ";
. "WHERE id = '" . $GLOBALS['dbi']->escapeString($this->getId()) . "' ";
$resList = PMA_queryAsControlUser($sqlQuery);
@ -426,8 +436,8 @@ class SavedSearches
$sqlQuery = "SELECT id, search_name "
. "FROM " . $savedSearchesTbl . " "
. "WHERE "
. "username = '" . Util::sqlAddSlashes($this->getUsername()) . "' "
. "AND db_name = '" . Util::sqlAddSlashes($this->getDbname()) . "' ";
. "username = '" . $GLOBALS['dbi']->escapeString($this->getUsername()) . "' "
. "AND db_name = '" . $GLOBALS['dbi']->escapeString($this->getDbname()) . "' ";
foreach ($wheres as $where) {
$sqlQuery .= "AND " . $where . " ";

View File

@ -50,7 +50,7 @@ class SystemDatabase
"SELECT * FROM %s.%s WHERE `db_name` = '%s'",
Util::backquote($cfgRelation['db']),
Util::backquote($cfgRelation['column_info']),
Util::sqlAddSlashes($db)
$GLOBALS['dbi']->escapeString($db)
);
return $this->dbi->tryQuery($pma_transformation_sql);
@ -105,7 +105,7 @@ class SystemDatabase
$data_row['comment'],
$data_row['mimetype'],
$data_row['transformation'],
Util::sqlAddSlashes(
$GLOBALS['dbi']->escapeString(
$data_row['transformation_options']
)
);

View File

@ -190,8 +190,8 @@ class Table
$result = $this->_dbi->fetchResult(
"SELECT TABLE_NAME
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = '" . Util::sqlAddSlashes($db) . "'
AND TABLE_NAME = '" . Util::sqlAddSlashes($table) . "'"
WHERE TABLE_SCHEMA = '" . $GLOBALS['dbi']->escapeString($db) . "'
AND TABLE_NAME = '" . $GLOBALS['dbi']->escapeString($table) . "'"
);
return $result ? true : false;
}
@ -210,8 +210,8 @@ class Table
$result = $this->_dbi->fetchResult(
"SELECT TABLE_NAME
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = '" . Util::sqlAddSlashes($this->_db_name) . "'
AND TABLE_NAME = '" . Util::sqlAddSlashes($this->_name) . "'
WHERE TABLE_SCHEMA = '" . $GLOBALS['dbi']->escapeString($this->_db_name) . "'
AND TABLE_NAME = '" . $GLOBALS['dbi']->escapeString($this->_name) . "'
AND IS_UPDATABLE = 'YES'"
);
return $result ? true : false;
@ -240,8 +240,8 @@ class Table
$results = $this->_dbi->fetchResult(
"SELECT COLUMN_NAME, DATA_TYPE
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = '" . Util::sqlAddSlashes($this->_db_name)
. " AND TABLE_NAME = '" . Util::sqlAddSlashes($this->_name) . "'"
WHERE TABLE_SCHEMA = '" . $GLOBALS['dbi']->escapeString($this->_db_name)
. " AND TABLE_NAME = '" . $GLOBALS['dbi']->escapeString($this->_name) . "'"
);
foreach ($results as $result) {
@ -399,8 +399,11 @@ class Table
//
$pattern = '@^(DATE|TINYBLOB|TINYTEXT|BLOB|TEXT|'
. 'MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT|SERIAL|BOOLEAN|UUID)$@i';
if ($length != '' && ! preg_match($pattern, $type)) {
$query .= '(' . intval($length) . ')';
if (strlen($length) !== 0 && ! preg_match($pattern, $type)) {
// Note: The variable $length here can contain several other things
// besides length - ENUM/SET value or length of DECIMAL (eg. 12,3)
// so we can't just convert it to integer
$query .= '(' . $length . ')';
}
if ($virtuality) {
@ -408,6 +411,13 @@ class Table
} else {
if ($attribute != '') {
$query .= ' ' . $attribute;
if ($is_timestamp
&& preg_match('/TIMESTAMP/i', $attribute)
&& $length !== 0
) {
$query .= '(' . $length . ')';
}
}
$matches = preg_match(
@ -444,13 +454,13 @@ class Table
} else {
// Invalid BOOLEAN value
$query .= ' DEFAULT \''
. Util::sqlAddSlashes($default_value) . '\'';
. $GLOBALS['dbi']->escapeString($default_value) . '\'';
}
} elseif ($type == 'BINARY' || $type == 'VARBINARY') {
$query .= ' DEFAULT 0x' . $default_value;
} else {
$query .= ' DEFAULT \''
. Util::sqlAddSlashes($default_value) . '\'';
. $GLOBALS['dbi']->escapeString($default_value) . '\'';
}
break;
/** @noinspection PhpMissingBreakStatementInspection */
@ -463,6 +473,9 @@ class Table
// else fall-through intended, no break here
case 'CURRENT_TIMESTAMP' :
$query .= ' DEFAULT ' . $default_type;
if ($length !== 0 && $is_timestamp) {
$query .= '(' . $length . ')';
}
break;
case 'NONE' :
default :
@ -474,7 +487,7 @@ class Table
}
}
if (!empty($comment)) {
$query .= " COMMENT '" . Util::sqlAddSlashes($comment) . "'";
$query .= " COMMENT '" . $GLOBALS['dbi']->escapeString($comment) . "'";
}
// move column
@ -486,6 +499,49 @@ class Table
return $query;
} // end function
/**
* Checks if the number of records in a table is at least equal to
* $min_records
*
* @param int $min_records Number of records to check for in a table
*
* @return bool True, if at least $min_records exist, False otherwise.
*/
public function checkIfMinRecordsExist($min_records = 0)
{
$check_query = 'SELECT ';
$fieldsToSelect = '';
$uniqueFields = $this->getUniqueColumns(true, false);
if (count($uniqueFields) > 0) {
$fieldsToSelect = implode(', ', $uniqueFields);
} else {
$indexedCols = $this->getIndexedColumns(true, false);
if (count($indexedCols) > 0) {
$fieldsToSelect = implode(', ', $indexedCols);
} else {
$fieldsToSelect = '*';
}
}
$check_query .= $fieldsToSelect
. ' FROM ' . $this->getFullName(true)
. ' LIMIT ' . $min_records;
$res = $GLOBALS['dbi']->tryQuery(
$check_query
);
if ($res !== false) {
$num_records = $GLOBALS['dbi']->numRows($res);
if ($num_records >= $min_records) {
return true;
}
}
return false;
}
/**
* Counts and returns (or displays) the number of records in a table
*
@ -547,7 +603,7 @@ class Table
// completely the record counting for views
if ($GLOBALS['cfg']['MaxExactCountViews'] == 0) {
$row_count = 0;
$row_count = false;
} else {
// Counting all rows of a VIEW could be too long,
// so use a LIMIT clause.
@ -648,14 +704,14 @@ class Table
$where_parts = array();
foreach ($where_fields as $_where => $_value) {
$where_parts[] = Util::backquote($_where) . ' = \''
. Util::sqlAddSlashes($_value) . '\'';
. $GLOBALS['dbi']->escapeString($_value) . '\'';
}
$new_parts = array();
$new_value_parts = array();
foreach ($new_fields as $_where => $_value) {
$new_parts[] = Util::backquote($_where);
$new_value_parts[] = Util::sqlAddSlashes($_value);
$new_value_parts[] = $GLOBALS['dbi']->escapeString($_value);
}
$table_copy_query = '
@ -674,7 +730,7 @@ class Table
$value_parts = array();
foreach ($table_copy_row as $_key => $_val) {
if (isset($row_fields[$_key]) && $row_fields[$_key] == 'cc') {
$value_parts[] = Util::sqlAddSlashes($_val);
$value_parts[] = $GLOBALS['dbi']->escapeString($_val);
}
}
@ -1014,10 +1070,17 @@ class Table
$GLOBALS['dbi']->query($sql_set_mode);
$GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';';
$sql_insert_data = 'INSERT INTO ' . $target
. ' SELECT * FROM ' . $source;
$GLOBALS['dbi']->query($sql_insert_data);
$GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';';
$_old_table = new Table($source_table, $source_db);
$nonGeneratedCols = $_old_table->getNonGeneratedColumns(true);
if (count($nonGeneratedCols) > 0) {
$sql_insert_data = 'INSERT INTO ' . $target . '('
. implode(', ', $nonGeneratedCols)
. ') SELECT ' . implode(', ', $nonGeneratedCols)
. ' FROM ' . $source;
$GLOBALS['dbi']->query($sql_insert_data);
$GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';';
}
}
PMA_getRelationsParam();
@ -1068,10 +1131,10 @@ class Table
. Util::backquote($GLOBALS['cfgRelation']['column_info'])
. ' WHERE '
. ' db_name = \''
. Util::sqlAddSlashes($source_db) . '\''
. $GLOBALS['dbi']->escapeString($source_db) . '\''
. ' AND '
. ' table_name = \''
. Util::sqlAddSlashes($source_table) . '\''
. $GLOBALS['dbi']->escapeString($source_table) . '\''
);
// Write every comment as new copied entry. [MIME]
@ -1086,21 +1149,21 @@ class Table
. ($GLOBALS['cfgRelation']['mimework']
? ', mimetype, transformation, transformation_options'
: '')
. ') ' . ' VALUES(' . '\'' . Util::sqlAddSlashes($target_db)
. '\',\'' . Util::sqlAddSlashes($target_table) . '\',\''
. Util::sqlAddSlashes($comments_copy_row['column_name'])
. ') ' . ' VALUES(' . '\'' . $GLOBALS['dbi']->escapeString($target_db)
. '\',\'' . $GLOBALS['dbi']->escapeString($target_table) . '\',\''
. $GLOBALS['dbi']->escapeString($comments_copy_row['column_name'])
. '\''
. ($GLOBALS['cfgRelation']['mimework']
? ',\'' . Util::sqlAddSlashes(
? ',\'' . $GLOBALS['dbi']->escapeString(
$comments_copy_row['comment']
)
. '\',' . '\'' . Util::sqlAddSlashes(
. '\',' . '\'' . $GLOBALS['dbi']->escapeString(
$comments_copy_row['mimetype']
)
. '\',' . '\'' . Util::sqlAddSlashes(
. '\',' . '\'' . $GLOBALS['dbi']->escapeString(
$comments_copy_row['transformation']
)
. '\',' . '\'' . Util::sqlAddSlashes(
. '\',' . '\'' . $GLOBALS['dbi']->escapeString(
$comments_copy_row['transformation_options']
)
. '\''
@ -1225,17 +1288,18 @@ class Table
* checks if given name is a valid table name,
* currently if not empty, trailing spaces, '.', '/' and '\'
*
* @param string $table_name name to check
* @param string $table_name name to check
* @param boolean $is_backquoted whether this name is used inside backquotes or not
*
* @todo add check for valid chars in filename on current system/os
* @see https://dev.mysql.com/doc/refman/5.0/en/legal-names.html
*
* @return boolean whether the string is valid or not
*/
static function isValidName($table_name)
static function isValidName($table_name, $is_backquoted = false)
{
if ($table_name !== trim($table_name)) {
// trailing spaces
if ($table_name !== rtrim($table_name)) {
// trailing spaces not allowed even in backquotes
return false;
}
@ -1244,12 +1308,22 @@ class Table
return false;
}
if (preg_match('/[.\/\\\\]+/i', $table_name)) {
// illegal char . / \
if (! $is_backquoted && $table_name !== trim($table_name)) {
// spaces at the start or in between only allowed inside backquotes
return false;
}
return true;
if (! $is_backquoted && preg_match('/^[a-zA-Z0-9_$]+$/', $table_name)) {
// only allow the above regex in unquoted identifiers
// see : http://dev.mysql.com/doc/refman/5.7/en/identifiers.html
return true;
} else if ($is_backquoted) {
// If backquoted, all characters should be allowed (except w/ trailing spaces)
return true;
}
// If not backquoted and doesn't follow the above regex
return false;
}
/**
@ -1290,7 +1364,10 @@ class Table
return true;
}
if (! Table::isValidName($new_name)) {
// Allow whitespaces (not trailing) in $new_name,
// since we are using $backquoted in getting the fullName of table
// below to be used in the query
if (! Table::isValidName($new_name, true)) {
$this->errors[] = __('Invalid table name:') . ' '
. $new_table->getFullName();
return false;
@ -1481,6 +1558,40 @@ class Table
}
}
/**
* Get non-generated columns in table
*
* @param bool $backquoted whether to quote name with backticks ``
*
* @return array
*/
public function getNonGeneratedColumns($backquoted = true)
{
$columns_meta_query = 'SHOW COLUMNS FROM ' . $this->getFullName(true);
$ret = array();
$columns_meta_query_result = $this->_dbi->fetchResult(
$columns_meta_query
);
if ($columns_meta_query_result
&& $columns_meta_query_result !== false
) {
foreach ($columns_meta_query_result as $column) {
$value = $column['Field'];
if ($backquoted === true) {
$value = Util::backquote($value);
}
if (strpos($column['Extra'], 'GENERATED') === false) {
array_push($ret, $value);
}
}
}
return $ret;
}
/**
* Return UI preferences for this table from phpMyAdmin database.
*
@ -1494,9 +1605,9 @@ class Table
// Read from phpMyAdmin database
$sql_query = " SELECT `prefs` FROM " . $pma_table
. " WHERE `username` = '" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name` = '" . Util::sqlAddSlashes($this->_db_name) . "'"
. " AND `table_name` = '" . Util::sqlAddSlashes($this->_name) . "'";
. " WHERE `username` = '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name` = '" . $GLOBALS['dbi']->escapeString($this->_db_name) . "'"
. " AND `table_name` = '" . $GLOBALS['dbi']->escapeString($this->_name) . "'";
$row = $this->_dbi->fetchArray(PMA_queryAsControlUser($sql_query));
if (isset($row[0])) {
@ -1517,14 +1628,14 @@ class Table
$pma_table = Util::backquote($cfgRelation['db']) . "."
. Util::backquote($cfgRelation['table_uiprefs']);
$secureDbName = Util::sqlAddSlashes($this->_db_name);
$secureDbName = $GLOBALS['dbi']->escapeString($this->_db_name);
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query = " REPLACE INTO " . $pma_table
. " (username, db_name, table_name, prefs) VALUES ('"
. Util::sqlAddSlashes($username) . "', '" . $secureDbName
. "', '" . Util::sqlAddSlashes($this->_name) . "', '"
. Util::sqlAddSlashes(json_encode($this->uiprefs)) . "')";
. $GLOBALS['dbi']->escapeString($username) . "', '" . $secureDbName
. "', '" . $GLOBALS['dbi']->escapeString($this->_name) . "', '"
. $GLOBALS['dbi']->escapeString(json_encode($this->uiprefs)) . "')";
$success = $this->_dbi->tryQuery($sql_query, $GLOBALS['controllink']);
@ -1891,7 +2002,7 @@ class Table
if (! empty($keyBlockSizes)) {
$sql_query .= sprintf(
' KEY_BLOCK_SIZE = ',
Util::sqlAddSlashes($keyBlockSizes)
$GLOBALS['dbi']->escapeString($keyBlockSizes)
);
}
@ -1906,14 +2017,14 @@ class Table
$parser = $index->getParser();
if ($index->getChoice() == 'FULLTEXT' && ! empty($parser)) {
$sql_query .= ' WITH PARSER ' . Util::sqlAddSlashes($parser);
$sql_query .= ' WITH PARSER ' . $GLOBALS['dbi']->escapeString($parser);
}
$comment = $index->getComment();
if (! empty($comment)) {
$sql_query .= sprintf(
" COMMENT '%s'",
Util::sqlAddSlashes($comment)
$GLOBALS['dbi']->escapeString($comment)
);
}
@ -1940,28 +2051,28 @@ class Table
. Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . Util::backquote($cfgRelation['table_info'])
. ' WHERE db_name = \''
. Util::sqlAddSlashes($this->_db_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_db_name) . '\''
. ' AND table_name = \''
. Util::sqlAddSlashes($this->_name) . '\'';
. $GLOBALS['dbi']->escapeString($this->_name) . '\'';
} elseif ($disp != $display_field) {
$upd_query = 'UPDATE '
. Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . Util::backquote($cfgRelation['table_info'])
. ' SET display_field = \''
. Util::sqlAddSlashes($display_field) . '\''
. $GLOBALS['dbi']->escapeString($display_field) . '\''
. ' WHERE db_name = \''
. Util::sqlAddSlashes($this->_db_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_db_name) . '\''
. ' AND table_name = \''
. Util::sqlAddSlashes($this->_name) . '\'';
. $GLOBALS['dbi']->escapeString($this->_name) . '\'';
}
} elseif ($display_field != '') {
$upd_query = 'INSERT INTO '
. Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . Util::backquote($cfgRelation['table_info'])
. '(db_name, table_name, display_field) VALUES('
. '\'' . Util::sqlAddSlashes($this->_db_name) . '\','
. '\'' . Util::sqlAddSlashes($this->_name) . '\','
. '\'' . Util::sqlAddSlashes($display_field) . '\')';
. '\'' . $GLOBALS['dbi']->escapeString($this->_db_name) . '\','
. '\'' . $GLOBALS['dbi']->escapeString($this->_name) . '\','
. '\'' . $GLOBALS['dbi']->escapeString($display_field) . '\')';
}
if ($upd_query) {
@ -2010,12 +2121,12 @@ class Table
. '(master_db, master_table, master_field, foreign_db,'
. ' foreign_table, foreign_field)'
. ' values('
. '\'' . Util::sqlAddSlashes($this->_db_name) . '\', '
. '\'' . Util::sqlAddSlashes($this->_name) . '\', '
. '\'' . Util::sqlAddSlashes($master_field) . '\', '
. '\'' . Util::sqlAddSlashes($foreign_db) . '\', '
. '\'' . Util::sqlAddSlashes($foreign_table) . '\','
. '\'' . Util::sqlAddSlashes($foreign_field) . '\')';
. '\'' . $GLOBALS['dbi']->escapeString($this->_db_name) . '\', '
. '\'' . $GLOBALS['dbi']->escapeString($this->_name) . '\', '
. '\'' . $GLOBALS['dbi']->escapeString($master_field) . '\', '
. '\'' . $GLOBALS['dbi']->escapeString($foreign_db) . '\', '
. '\'' . $GLOBALS['dbi']->escapeString($foreign_table) . '\','
. '\'' . $GLOBALS['dbi']->escapeString($foreign_field) . '\')';
} elseif ($existrel[$master_field]['foreign_db'] != $foreign_db
|| $existrel[$master_field]['foreign_table'] != $foreign_table
@ -2025,28 +2136,28 @@ class Table
. Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . Util::backquote($cfgRelation['relation'])
. ' SET foreign_db = \''
. Util::sqlAddSlashes($foreign_db) . '\', '
. $GLOBALS['dbi']->escapeString($foreign_db) . '\', '
. ' foreign_table = \''
. Util::sqlAddSlashes($foreign_table) . '\', '
. $GLOBALS['dbi']->escapeString($foreign_table) . '\', '
. ' foreign_field = \''
. Util::sqlAddSlashes($foreign_field) . '\' '
. $GLOBALS['dbi']->escapeString($foreign_field) . '\' '
. ' WHERE master_db = \''
. Util::sqlAddSlashes($this->_db_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_db_name) . '\''
. ' AND master_table = \''
. Util::sqlAddSlashes($this->_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_name) . '\''
. ' AND master_field = \''
. Util::sqlAddSlashes($master_field) . '\'';
. $GLOBALS['dbi']->escapeString($master_field) . '\'';
} // end if... else....
} elseif (isset($existrel[$master_field])) {
$upd_query = 'DELETE FROM '
. Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . Util::backquote($cfgRelation['relation'])
. ' WHERE master_db = \''
. Util::sqlAddSlashes($this->_db_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_db_name) . '\''
. ' AND master_table = \''
. Util::sqlAddSlashes($this->_name) . '\''
. $GLOBALS['dbi']->escapeString($this->_name) . '\''
. ' AND master_field = \''
. Util::sqlAddSlashes($master_field) . '\'';
. $GLOBALS['dbi']->escapeString($master_field) . '\'';
} // end if... else....
if (isset($upd_query)) {
@ -2328,10 +2439,10 @@ class Table
FROM
`information_schema`.`COLUMNS`
WHERE
`TABLE_SCHEMA` = '" . Util::sqlAddSlashes($this->_db_name) . "'
AND `TABLE_NAME` = '" . Util::sqlAddSlashes($this->_name) . "'";
`TABLE_SCHEMA` = '" . $GLOBALS['dbi']->escapeString($this->_db_name) . "'
AND `TABLE_NAME` = '" . $GLOBALS['dbi']->escapeString($this->_name) . "'";
if ($column != null) {
$sql .= " AND `COLUMN_NAME` = '" . Util::sqlAddSlashes($column)
$sql .= " AND `COLUMN_NAME` = '" . $GLOBALS['dbi']->escapeString($column)
. "'";
}
$columns = $this->_dbi->fetchResult($sql, 'Field', 'Expression');

View File

@ -123,8 +123,8 @@ class Tracker
}
$sql_query = " SELECT tracking_active FROM " . self::_getTrackingTable() .
" WHERE db_name = '" . Util::sqlAddSlashes($dbname) . "' " .
" AND table_name = '" . Util::sqlAddSlashes($tablename) . "' " .
" WHERE db_name = '" . $GLOBALS['dbi']->escapeString($dbname) . "' " .
" AND table_name = '" . $GLOBALS['dbi']->escapeString($tablename) . "' " .
" ORDER BY version DESC";
$row = $GLOBALS['dbi']->fetchArray(PMA_queryAsControlUser($sql_query));
@ -144,8 +144,9 @@ class Tracker
static public function getLogComment()
{
$date = date('Y-m-d H:i:s');
$user = preg_replace('/\s+/', ' ', $GLOBALS['cfg']['Server']['user']);
return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
return "# log " . $date . " " . $user . "\n";
}
/**
@ -242,15 +243,15 @@ class Tracker
"tracking " .
") " .
"values (
'" . Util::sqlAddSlashes($dbname) . "',
'" . Util::sqlAddSlashes($tablename) . "',
'" . Util::sqlAddSlashes($version) . "',
'" . Util::sqlAddSlashes($date) . "',
'" . Util::sqlAddSlashes($date) . "',
'" . Util::sqlAddSlashes($snapshot) . "',
'" . Util::sqlAddSlashes($create_sql) . "',
'" . Util::sqlAddSlashes("\n") . "',
'" . Util::sqlAddSlashes($tracking_set)
'" . $GLOBALS['dbi']->escapeString($dbname) . "',
'" . $GLOBALS['dbi']->escapeString($tablename) . "',
'" . $GLOBALS['dbi']->escapeString($version) . "',
'" . $GLOBALS['dbi']->escapeString($date) . "',
'" . $GLOBALS['dbi']->escapeString($date) . "',
'" . $GLOBALS['dbi']->escapeString($snapshot) . "',
'" . $GLOBALS['dbi']->escapeString($create_sql) . "',
'" . $GLOBALS['dbi']->escapeString("\n") . "',
'" . $GLOBALS['dbi']->escapeString($tracking_set)
. "' )";
$result = PMA_queryAsControlUser($sql_query);
@ -280,12 +281,12 @@ class Tracker
$sql_query = "/*NOTRACK*/\n"
. "DELETE FROM " . self::_getTrackingTable()
. " WHERE `db_name` = '"
. Util::sqlAddSlashes($dbname) . "'"
. $GLOBALS['dbi']->escapeString($dbname) . "'"
. " AND `table_name` = '"
. Util::sqlAddSlashes($tablename) . "'";
. $GLOBALS['dbi']->escapeString($tablename) . "'";
if ($version) {
$sql_query .= " AND `version` = '"
. Util::sqlAddSlashes($version) . "'";
. $GLOBALS['dbi']->escapeString($version) . "'";
}
$result = PMA_queryAsControlUser($sql_query);
@ -338,15 +339,15 @@ class Tracker
"tracking " .
") " .
"values (
'" . Util::sqlAddSlashes($dbname) . "',
'" . Util::sqlAddSlashes('') . "',
'" . Util::sqlAddSlashes($version) . "',
'" . Util::sqlAddSlashes($date) . "',
'" . Util::sqlAddSlashes($date) . "',
'" . Util::sqlAddSlashes('') . "',
'" . Util::sqlAddSlashes($create_sql) . "',
'" . Util::sqlAddSlashes("\n") . "',
'" . Util::sqlAddSlashes($tracking_set)
'" . $GLOBALS['dbi']->escapeString($dbname) . "',
'" . $GLOBALS['dbi']->escapeString('') . "',
'" . $GLOBALS['dbi']->escapeString($version) . "',
'" . $GLOBALS['dbi']->escapeString($date) . "',
'" . $GLOBALS['dbi']->escapeString($date) . "',
'" . $GLOBALS['dbi']->escapeString('') . "',
'" . $GLOBALS['dbi']->escapeString($create_sql) . "',
'" . $GLOBALS['dbi']->escapeString("\n") . "',
'" . $GLOBALS['dbi']->escapeString($tracking_set)
. "' )";
$result = PMA_queryAsControlUser($sql_query);
@ -374,9 +375,9 @@ class Tracker
$sql_query = " UPDATE " . self::_getTrackingTable() .
" SET `tracking_active` = '" . $new_state . "' " .
" WHERE `db_name` = '" . Util::sqlAddSlashes($dbname) . "' " .
" AND `table_name` = '" . Util::sqlAddSlashes($tablename) . "' " .
" AND `version` = '" . Util::sqlAddSlashes($version) . "' ";
" WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($dbname) . "' " .
" AND `table_name` = '" . $GLOBALS['dbi']->escapeString($tablename) . "' " .
" AND `version` = '" . $GLOBALS['dbi']->escapeString($version) . "' ";
$result = PMA_queryAsControlUser($sql_query);
@ -412,7 +413,7 @@ class Tracker
if (is_array($new_data)) {
foreach ($new_data as $data) {
$new_data_processed .= '# log ' . $date . ' ' . $data['username']
. Util::sqlAddSlashes($data['statement']) . "\n";
. $GLOBALS['dbi']->escapeString($data['statement']) . "\n";
}
} else {
$new_data_processed = $new_data;
@ -420,9 +421,9 @@ class Tracker
$sql_query = " UPDATE " . self::_getTrackingTable() .
" SET `" . $save_to . "` = '" . $new_data_processed . "' " .
" WHERE `db_name` = '" . Util::sqlAddSlashes($dbname) . "' " .
" AND `table_name` = '" . Util::sqlAddSlashes($tablename) . "' " .
" AND `version` = '" . Util::sqlAddSlashes($version) . "' ";
" WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($dbname) . "' " .
" AND `table_name` = '" . $GLOBALS['dbi']->escapeString($tablename) . "' " .
" AND `version` = '" . $GLOBALS['dbi']->escapeString($version) . "' ";
$result = PMA_queryAsControlUser($sql_query);
@ -478,8 +479,8 @@ class Tracker
static public function getVersion($dbname, $tablename, $statement = null)
{
$sql_query = " SELECT MAX(version) FROM " . self::_getTrackingTable() .
" WHERE `db_name` = '" . Util::sqlAddSlashes($dbname) . "' " .
" AND `table_name` = '" . Util::sqlAddSlashes($tablename) . "' ";
" WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($dbname) . "' " .
" AND `table_name` = '" . $GLOBALS['dbi']->escapeString($tablename) . "' ";
if ($statement != "") {
$sql_query .= " AND FIND_IN_SET('"
@ -507,12 +508,12 @@ class Tracker
static public function getTrackedData($dbname, $tablename, $version)
{
$sql_query = " SELECT * FROM " . self::_getTrackingTable() .
" WHERE `db_name` = '" . Util::sqlAddSlashes($dbname) . "' ";
" WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($dbname) . "' ";
if (! empty($tablename)) {
$sql_query .= " AND `table_name` = '"
. Util::sqlAddSlashes($tablename) . "' ";
. $GLOBALS['dbi']->escapeString($tablename) . "' ";
}
$sql_query .= " AND `version` = '" . Util::sqlAddSlashes($version)
$sql_query .= " AND `version` = '" . $GLOBALS['dbi']->escapeString($version)
. "' " . " ORDER BY `version` DESC LIMIT 1";
$mixed = $GLOBALS['dbi']->fetchAssoc(PMA_queryAsControlUser($sql_query));
@ -916,14 +917,14 @@ class Tracker
. " UPDATE " . self::_getTrackingTable()
. " SET " . Util::backquote($save_to)
. " = CONCAT( " . Util::backquote($save_to) . ",'\n"
. Util::sqlAddSlashes($query) . "') ,"
. $GLOBALS['dbi']->escapeString($query) . "') ,"
. " `date_updated` = '" . $date . "' ";
// If table was renamed we have to change
// the tablename attribute in pma_tracking too
if ($result['identifier'] == 'RENAME TABLE') {
$sql_query .= ', `table_name` = \''
. Util::sqlAddSlashes($result['tablename_after_rename'])
. $GLOBALS['dbi']->escapeString($result['tablename_after_rename'])
. '\' ';
}
@ -934,10 +935,10 @@ class Tracker
// we want to track
$sql_query .=
" WHERE FIND_IN_SET('" . $result['identifier'] . "',tracking) > 0" .
" AND `db_name` = '" . Util::sqlAddSlashes($dbname) . "' " .
" AND `db_name` = '" . $GLOBALS['dbi']->escapeString($dbname) . "' " .
" AND `table_name` = '"
. Util::sqlAddSlashes($result['tablename']) . "' " .
" AND `version` = '" . Util::sqlAddSlashes($version) . "' ";
. $GLOBALS['dbi']->escapeString($result['tablename']) . "' " .
" AND `version` = '" . $GLOBALS['dbi']->escapeString($version) . "' ";
PMA_queryAsControlUser($sql_query);
}

View File

@ -285,50 +285,6 @@ class Util
. $max_size . '" />';
}
/**
* Add slashes before "'" and "\" characters so a value containing them can
* be used in a sql comparison.
*
* @param string $a_string the string to slash
* @param bool $is_like whether the string will be used in a 'LIKE' clause
* (it then requires two more escaped sequences) or not
* @param bool $crlf whether to treat cr/lfs as escape-worthy entities
* (converts \n to \\n, \r to \\r)
* @param bool $php_code whether this function is used as part of the
* "Create PHP code" dialog
*
* @return string the slashed string
*
* @access public
*/
public static function sqlAddSlashes(
$a_string = '',
$is_like = false,
$crlf = false,
$php_code = false
) {
if ($is_like) {
$a_string = str_replace('\\', '\\\\\\\\', $a_string);
} else {
$a_string = str_replace('\\', '\\\\', $a_string);
}
if ($crlf) {
$a_string = strtr(
$a_string,
array("\n" => '\n', "\r" => '\r', "\t" => '\t')
);
}
if ($php_code) {
$a_string = str_replace('\'', '\\\'', $a_string);
} else {
$a_string = str_replace('\'', '\\\'', $a_string);
}
return $a_string;
} // end of the 'sqlAddSlashes()' function
/**
* Add slashes before "_" and "%" characters for using them in MySQL
* database, table and field names.
@ -1167,7 +1123,9 @@ class Util
}
if (! empty($GLOBALS['show_as_php'])) {
$query_base = '$sql = "' . $query_base;
$query_base = '$sql = \'' . $query_base;
$query_base = '<code class="php"><pre>' . "\n"
. $query_base;
} elseif (isset($query_base)) {
$query_base = self::formatSql($query_base);
}
@ -1238,7 +1196,9 @@ class Util
// even if the query is big and was truncated, offer the chance
// to edit it (unless it's enormous, see linkOrButton() )
if (! empty($cfg['SQLQuery']['Edit'])) {
if (! empty($cfg['SQLQuery']['Edit'])
&& empty($GLOBALS['show_as_php'])
) {
$edit_link .= PMA_URL_getCommon($url_params) . '#querybox';
$edit_link = ' ['
. self::linkOrButton($edit_link, __('Edit'))
@ -1311,7 +1271,8 @@ class Util
//Clean up the end of the PHP
if (! empty($GLOBALS['show_as_php'])) {
$retval .= '";';
$retval .= '\';' . "\n"
. '</pre></code>';
}
$retval .= '</div>';
@ -1337,7 +1298,10 @@ class Util
/**
* TODO: Should we have $cfg['SQLQuery']['InlineEdit']?
*/
if (! empty($cfg['SQLQuery']['Edit']) && ! $query_too_big) {
if (! empty($cfg['SQLQuery']['Edit'])
&& ! $query_too_big
&& empty($GLOBALS['show_as_php'])
) {
$inline_edit_link = ' ['
. self::linkOrButton(
'#',
@ -1604,17 +1568,13 @@ class Util
$value = round($value / (self::pow(1000, $d, 'pow') / $dh)) /$dh;
$unit = $units[$d];
// If we don't want any zeros after the comma just add the thousand separator
if ($noTrailingZero) {
$localizedValue = self::localizeNumber(
preg_replace('/(?<=\d)(?=(\d{3})+(?!\d))/', ',', $value)
);
} else {
//number_format is not multibyte safe, str_replace is safe
$localizedValue = self::localizeNumber(
number_format($value, $digits_right)
);
// number_format is not multibyte safe, str_replace is safe
$formattedValue = number_format($value, $digits_right);
// If we don't want any zeros, remove them now
if ($noTrailingZero && strpos($formattedValue, '.') !== false) {
$formattedValue = preg_replace('/\.?0+$/', '', $formattedValue);
}
$localizedValue = self::localizeNumber($formattedValue);
if ($originalValue != 0 && floatval($value) == 0) {
return ' <' . self::localizeNumber((1 / self::pow(10, $digits_right)))
@ -1916,6 +1876,9 @@ class Util
}
if (! empty($target)) {
$tag_params['target'] = htmlentities($target);
if ($target === '_blank' && strncmp($url, 'url.php?', 8) == 0) {
$tag_params['rel'] = 'noopener noreferrer';
}
}
$displayed_message = '';
@ -2334,7 +2297,7 @@ class Util
. self::printableBitValue($row[$i], $meta->length) . "'";
} else {
$con_val = '= \''
. self::sqlAddSlashes($row[$i], false, true) . '\'';
. $GLOBALS['dbi']->escapeString($row[$i]) . '\'';
}
}
@ -4049,7 +4012,7 @@ class Util
* @return string An HTML snippet of a dropdown list with function
* names appropriate for the requested column.
*/
public static function getFunctionsForField($field, $insert_mode)
public static function getFunctionsForField($field, $insert_mode, $foreignData)
{
$default_function = self::getDefaultFunctionForField($field, $insert_mode);
$dropdown_built = array();
@ -4061,7 +4024,7 @@ class Util
$functions = $GLOBALS['PMA_Types']->getFunctions($field['True_Type']);
foreach ($functions as $function) {
$retval .= '<option';
if ($default_function === $function) {
if (isset($foreignData['foreign_link']) && $foreignData['foreign_link'] !== false && $default_function === $function) {
$retval .= ' selected="selected"';
}
$retval .= '>' . $function . '</option>' . "\n";
@ -4158,7 +4121,7 @@ class Util
'SCHEMA_PRIVILEGES',
$username,
$priv,
self::sqlAddSlashes($db)
$GLOBALS['dbi']->escapeString($db)
)
);
if ($schema_privileges) {
@ -4181,8 +4144,8 @@ class Util
'TABLE_PRIVILEGES',
$username,
$priv,
self::sqlAddSlashes($db),
self::sqlAddSlashes($tbl)
$GLOBALS['dbi']->escapeString($db),
$GLOBALS['dbi']->escapeString($tbl)
)
);
if ($table_privileges) {
@ -4669,7 +4632,7 @@ class Util
->render(
array(
'pos' => $pos,
'unlim_num_rows' => $_REQUEST['unlim_num_rows'],
'unlim_num_rows' => intval($_REQUEST['unlim_num_rows']),
'rows' => $rows,
'sql_query' => $sql_query,
)
@ -4939,7 +4902,7 @@ class Util
if (! isset($sot_cache[$tmp[0]])) {
$sts_result = $GLOBALS['dbi']->query(
"SHOW TABLE STATUS FROM " . Util::backquote($db)
. " LIKE '" . Util::sqlAddSlashes($tmp[0], true)
. " LIKE '" . $GLOBALS['dbi']->escapeString($tmp[0])
. "';"
);
$sts_tmp = $GLOBALS['dbi']->fetchAssoc($sts_result);

View File

@ -72,7 +72,7 @@ class VersionInformation
CURLOPT_TIMEOUT,
$connection_timeout
);
$response = curl_exec($curl_handle);
$response = @curl_exec($curl_handle);
} else if (ini_get('allow_url_fopen')) {
$context = array(
'http' => array(
@ -81,12 +81,16 @@ class VersionInformation
)
);
$context = Util::handleContext($context);
$response = file_get_contents(
$response = @file_get_contents(
$file,
false,
stream_context_create($context)
);
}
// Check possible failure of getting data
if ($response === false) {
$response = '{}';
}
}
/* Parse response */
@ -269,6 +273,6 @@ class VersionInformation
*/
protected function getMySQLVersion()
{
return Util::cacheGet('PMA_MYSQL_STR_VERSION');
return PMA_MYSQL_STR_VERSION;
}
}

View File

@ -64,8 +64,8 @@ function PMA_Bookmark_getList($db = false)
$query = 'SELECT query, label, id FROM ' . PMA\libraries\Util::backquote(
$cfgBookmark['db']
) . '.' . PMA\libraries\Util::backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA\libraries\Util::sqlAddSlashes($db) . '\''
. ' AND user = \'' . PMA\libraries\Util::sqlAddSlashes($cfgBookmark['user'])
. ' WHERE dbase = \'' . $GLOBALS['dbi']->escapeString($db) . '\''
. ' AND user = \'' . $GLOBALS['dbi']->escapeString($cfgBookmark['user'])
. '\''
. ' ORDER BY label';
$per_user = $GLOBALS['dbi']->fetchResult(
@ -79,7 +79,7 @@ function PMA_Bookmark_getList($db = false)
$query = 'SELECT query, label, id FROM ' . PMA\libraries\Util::backquote(
$cfgBookmark['db']
) . '.' . PMA\libraries\Util::backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA\libraries\Util::sqlAddSlashes($db) . '\''
. ' WHERE dbase = \'' . $GLOBALS['dbi']->escapeString($db) . '\''
. ' AND user = \'\''
. ' ORDER BY label';
$global = $GLOBALS['dbi']->fetchResult(
@ -103,7 +103,7 @@ function PMA_Bookmark_getList($db = false)
. " FROM " . PMA\libraries\Util::backquote($cfgBookmark['db'])
. "." . PMA\libraries\Util::backquote($cfgBookmark['table'])
. " WHERE `user` = '' OR"
. " `user` = '" . PMA\libraries\Util::sqlAddSlashes($cfgBookmark['user'])
. " `user` = '" . $GLOBALS['dbi']->escapeString($cfgBookmark['user'])
. "'";
$ret = $GLOBALS['dbi']->fetchResult(
@ -149,11 +149,11 @@ function PMA_Bookmark_get($db, $id, $id_field = 'id', $action_bookmark_all = fal
$query = 'SELECT query FROM ' . PMA\libraries\Util::backquote($cfgBookmark['db'])
. '.' . PMA\libraries\Util::backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA\libraries\Util::sqlAddSlashes($db) . '\'';
. ' WHERE dbase = \'' . $GLOBALS['dbi']->escapeString($db) . '\'';
if (! $action_bookmark_all) {
$query .= ' AND (user = \''
. PMA\libraries\Util::sqlAddSlashes($cfgBookmark['user']) . '\'';
. $GLOBALS['dbi']->escapeString($cfgBookmark['user']) . '\'';
if (! $exact_user_match) {
$query .= ' OR user = \'\'';
}
@ -195,18 +195,18 @@ function PMA_Bookmark_save($bkm_fields, $all_users = false)
. '.' . PMA\libraries\Util::backquote($cfgBookmark['table'])
. ' (id, dbase, user, query, label)'
. ' VALUES (NULL, \''
. PMA\libraries\Util::sqlAddSlashes($bkm_fields['bkm_database']) . '\', '
. $GLOBALS['dbi']->escapeString($bkm_fields['bkm_database']) . '\', '
. '\''
. ($all_users
? ''
: PMA\libraries\Util::sqlAddSlashes(
: $GLOBALS['dbi']->escapeString(
$bkm_fields['bkm_user']
))
. '\', '
. '\''
. PMA\libraries\Util::sqlAddSlashes($bkm_fields['bkm_sql_query'])
. $GLOBALS['dbi']->escapeString($bkm_fields['bkm_sql_query'])
. '\', '
. '\'' . PMA\libraries\Util::sqlAddSlashes($bkm_fields['bkm_label']) . '\')';
. '\'' . $GLOBALS['dbi']->escapeString($bkm_fields['bkm_label']) . '\')';
return $GLOBALS['dbi']->query($query, $controllink);
} // end of the 'PMA_Bookmark_save()' function
@ -235,7 +235,7 @@ function PMA_Bookmark_delete($id)
$query = 'DELETE FROM ' . PMA\libraries\Util::backquote($cfgBookmark['db'])
. '.' . PMA\libraries\Util::backquote($cfgBookmark['table'])
. ' WHERE (user = \''
. PMA\libraries\Util::sqlAddSlashes($cfgBookmark['user']) . '\''
. $GLOBALS['dbi']->escapeString($cfgBookmark['user']) . '\''
. ' OR user = \'\')'
. ' AND id = ' . $id;
return $GLOBALS['dbi']->tryQuery($query, $controllink);
@ -275,7 +275,7 @@ function PMA_Bookmark_applyVariables($query)
for ($i = 1; $i <= $number_of_variables; $i++) {
$var = '';
if (! empty($_REQUEST['bookmark_variable'][$i])) {
$var = PMA\libraries\Util::sqlAddSlashes(
$var = $GLOBALS['dbi']->escapeString(
$_REQUEST['bookmark_variable'][$i]
);
}

View File

@ -60,10 +60,10 @@ function PMA_getColumnsList($db, $from=0, $num=25)
//get current values of $db from central column list
if ($num == 0) {
$query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\';';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
} else {
$query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\' '
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' '
. 'LIMIT ' . $from . ', ' . $num . ';';
}
$has_list = (array) $GLOBALS['dbi']->fetchResult(
@ -91,7 +91,7 @@ function PMA_getCentralColumnsCount($db)
$central_list_table = $cfgCentralColumns['table'];
$query = 'SELECT count(db_name) FROM ' .
Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\';';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
$res = $GLOBALS['dbi']->fetchResult(
$query, null, null, $GLOBALS['controllink']
);
@ -122,7 +122,7 @@ function PMA_findExistingColNames($db, $cols, $allFields=false)
$central_list_table = $cfgCentralColumns['table'];
if ($allFields) {
$query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\' AND col_name IN (' . $cols . ');';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
$has_list = (array) $GLOBALS['dbi']->fetchResult(
$query, null, null, $GLOBALS['controllink']
);
@ -130,7 +130,7 @@ function PMA_findExistingColNames($db, $cols, $allFields=false)
} else {
$query = 'SELECT col_name FROM '
. Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\' AND col_name IN (' . $cols . ');';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
$has_list = (array) $GLOBALS['dbi']->fetchResult(
$query, null, null, $GLOBALS['controllink']
);
@ -187,14 +187,14 @@ function PMA_getInsertQuery($column, $def, $db, $central_list_table)
$default = isset($def['Default'])?$def['Default']:"";
$insQuery = 'INSERT INTO '
. Util::backquote($central_list_table) . ' '
. 'VALUES ( \'' . Util::sqlAddSlashes($db) . '\' ,'
. '\'' . Util::sqlAddSlashes($column) . '\',\''
. Util::sqlAddSlashes($type) . '\','
. '\'' . Util::sqlAddSlashes($length) . '\',\''
. Util::sqlAddSlashes($collation) . '\','
. '\'' . Util::sqlAddSlashes($isNull) . '\','
. 'VALUES ( \'' . $GLOBALS['dbi']->escapeString($db) . '\' ,'
. '\'' . $GLOBALS['dbi']->escapeString($column) . '\',\''
. $GLOBALS['dbi']->escapeString($type) . '\','
. '\'' . $GLOBALS['dbi']->escapeString($length) . '\',\''
. $GLOBALS['dbi']->escapeString($collation) . '\','
. '\'' . $GLOBALS['dbi']->escapeString($isNull) . '\','
. '\'' . implode(',', array($extra, $attribute))
. '\',\'' . Util::sqlAddSlashes($default) . '\');';
. '\',\'' . $GLOBALS['dbi']->escapeString($default) . '\');';
return $insQuery;
}
@ -232,7 +232,7 @@ function PMA_syncUniqueColumns($field_select, $isTable=true, $table=null)
$db, $table, null, true, $GLOBALS['userlink']
);
foreach ($fields[$table] as $field => $def) {
$cols .= "'" . Util::sqlAddSlashes($field) . "',";
$cols .= "'" . $GLOBALS['dbi']->escapeString($field) . "',";
}
}
@ -254,7 +254,7 @@ function PMA_syncUniqueColumns($field_select, $isTable=true, $table=null)
$table = $_REQUEST['table'];
}
foreach ($field_select as $column) {
$cols .= "'" . Util::sqlAddSlashes($column) . "',";
$cols .= "'" . $GLOBALS['dbi']->escapeString($column) . "',";
}
$has_list = PMA_findExistingColNames($db, trim($cols, ','));
foreach ($field_select as $column) {
@ -336,7 +336,7 @@ function PMA_deleteColumnsFromList($field_select, $isTable=true)
$db, $table, $GLOBALS['userlink']
);
foreach ($fields[$table] as $col_select) {
$cols .= '\'' . Util::sqlAddSlashes($col_select) . '\',';
$cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
}
}
$cols = trim($cols, ',');
@ -352,7 +352,7 @@ function PMA_deleteColumnsFromList($field_select, $isTable=true)
} else {
$cols = '';
foreach ($field_select as $col_select) {
$cols .= '\'' . Util::sqlAddSlashes($col_select) . '\',';
$cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
}
$cols = trim($cols, ',');
$has_list = PMA_findExistingColNames($db, $cols);
@ -376,7 +376,7 @@ function PMA_deleteColumnsFromList($field_select, $isTable=true)
$GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
$query = 'DELETE FROM ' . Util::backquote($central_list_table) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\' AND col_name IN (' . $cols . ');';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
$message = Message::error(__('Could not remove columns!'));
@ -414,7 +414,7 @@ function PMA_makeConsistentWithList($db, $selected_tables)
//it is not referenced by another column
if ($column_status['isEditable']) {
$query .= ' MODIFY ' . Util::backquote($column['col_name']) . ' '
. Util::sqlAddSlashes($column['col_type']);
. $GLOBALS['dbi']->escapeString($column['col_type']);
if ($column['col_length']) {
$query .= '(' . $column['col_length'] . ')';
}
@ -429,11 +429,11 @@ function PMA_makeConsistentWithList($db, $selected_tables)
$query .= ' ' . $column['col_extra'];
if ($column['col_default']) {
if ($column['col_default'] != 'CURRENT_TIMESTAMP') {
$query .= ' DEFAULT \'' . Util::sqlAddSlashes(
$query .= ' DEFAULT \'' . $GLOBALS['dbi']->escapeString(
$column['col_default']
) . '\'';
} else {
$query .= ' DEFAULT ' . Util::sqlAddSlashes(
$query .= ' DEFAULT ' . $GLOBALS['dbi']->escapeString(
$column['col_default']
);
}
@ -481,7 +481,7 @@ function PMA_getCentralColumnsFromTable($db, $table, $allFields=false)
);
$cols = '';
foreach ($fields as $col_select) {
$cols .= '\'' . Util::sqlAddSlashes($col_select) . '\',';
$cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
}
$cols = trim($cols, ',');
$has_list = PMA_findExistingColNames($db, $cols, $allFields);
@ -531,16 +531,16 @@ function PMA_updateOneColumn($db, $orig_col_name, $col_name, $col_type,
$query = PMA_getInsertQuery($col_name, $def, $db, $centralTable);
} else {
$query = 'UPDATE ' . Util::backquote($centralTable)
. ' SET col_type = \'' . Util::sqlAddSlashes($col_type) . '\''
. ', col_name = \'' . Util::sqlAddSlashes($col_name) . '\''
. ', col_length = \'' . Util::sqlAddSlashes($col_length) . '\''
. ' SET col_type = \'' . $GLOBALS['dbi']->escapeString($col_type) . '\''
. ', col_name = \'' . $GLOBALS['dbi']->escapeString($col_name) . '\''
. ', col_length = \'' . $GLOBALS['dbi']->escapeString($col_length) . '\''
. ', col_isNull = ' . $col_isNull
. ', col_collation = \'' . Util::sqlAddSlashes($collation) . '\''
. ', col_collation = \'' . $GLOBALS['dbi']->escapeString($collation) . '\''
. ', col_extra = \''
. implode(',', array($col_extra, $col_attribute)) . '\''
. ', col_default = \'' . Util::sqlAddSlashes($col_default) . '\''
. ' WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\' '
. 'AND col_name = \'' . Util::sqlAddSlashes($orig_col_name)
. ', col_default = \'' . $GLOBALS['dbi']->escapeString($col_default) . '\''
. ' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' '
. 'AND col_name = \'' . $GLOBALS['dbi']->escapeString($orig_col_name)
. '\'';
}
if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
@ -1147,7 +1147,7 @@ function PMA_getCentralColumnsListRaw($db, $table)
$centralTable = $cfgCentralColumns['table'];
if (empty($table) || $table == '') {
$query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\';';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
} else {
$GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
$columns = (array) $GLOBALS['dbi']->getColumnNames(
@ -1155,11 +1155,11 @@ function PMA_getCentralColumnsListRaw($db, $table)
);
$cols = '';
foreach ($columns as $col_select) {
$cols .= '\'' . Util::sqlAddSlashes($col_select) . '\',';
$cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
}
$cols = trim($cols, ',');
$query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
. 'WHERE db_name = \'' . Util::sqlAddSlashes($db) . '\'';
. 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\'';
if ($cols) {
$query .= ' AND col_name NOT IN (' . $cols . ')';
}
@ -1383,7 +1383,7 @@ function PMA_getHTMLforEditingPage($selected_fld,$selected_db)
$html .= PMA_getCentralColumnsEditTableHeader($header_cells);
$selected_fld_safe = array();
foreach ($selected_fld as $key) {
$selected_fld_safe[] = Util::sqlAddSlashes($key);
$selected_fld_safe[] = $GLOBALS['dbi']->escapeString($key);
}
$columns_list = implode("','", $selected_fld_safe);
$columns_list = "'" . $columns_list . "'";

View File

@ -107,6 +107,13 @@ PMA_checkExtensions();
ini_set('default_charset', 'utf-8');
mb_internal_encoding('utf-8');
/**
* Set precision to sane value, with higher values
* things behave slightly unexpectedly, for example
* round(1.2, 2) returns 1.199999999999999956.
*/
ini_set('precision', 14);
/**
* the relation lib, tracker needs it
*/
@ -455,9 +462,15 @@ PMA_setGlobalDbOrTable('table');
*/
if (PMA_isValid($_REQUEST['selected_recent_table'])) {
$recent_table = json_decode($_REQUEST['selected_recent_table'], true);
$GLOBALS['db'] = $recent_table['db'];
$GLOBALS['db']
= (array_key_exists('db', $recent_table) && is_string($recent_table['db'])) ?
$recent_table['db'] : '';
$GLOBALS['url_params']['db'] = $GLOBALS['db'];
$GLOBALS['table'] = $recent_table['table'];
$GLOBALS['table']
= (array_key_exists('table', $recent_table) && is_string($recent_table['table'])) ?
$recent_table['table'] : '';
$GLOBALS['url_params']['table'] = $GLOBALS['table'];
}
@ -517,6 +530,20 @@ if ($GLOBALS['PMA_Config']->error_config_default_file) {
trigger_error($error, E_USER_ERROR);
}
/**
* As we try to handle charsets by ourself, mbstring overloads just
* break it, see bug 1063821.
*/
if (@extension_loaded('mbstring') && @ini_get('mbstring.func_overload') != '0') {
PMA_fatalError(
__(
'You have enabled mbstring.func_overload in your PHP '
. 'configuration. This option is incompatible with phpMyAdmin '
. 'and might cause some data to be corrupted!'
)
);
}
/******************************************************************************/
/* setup servers LABEL_setup_servers */
@ -850,7 +877,7 @@ if (! defined('PMA_MINIMUM_COMMON')) {
if ($cfg['Server']['SessionTimeZone'] != '') {
$sql_query_tz = 'SET ' . Util::backquote('time_zone') . ' = '
. '\''
. Util::sqlAddSlashes($cfg['Server']['SessionTimeZone'])
. $GLOBALS['dbi']->escapeString($cfg['Server']['SessionTimeZone'])
. '\'';
if (! $userlink->query($sql_query_tz)) {

View File

@ -19,6 +19,25 @@
* @package PhpMyAdmin
*/
/**
* Your phpMyAdmin URL.
*
* Complete the variable below with the full URL ie
* https://example.com/path_to_your_phpMyAdmin_directory/
*
* It must contain characters that are valid for a URL, and the path is
* case sensitive on some Web servers, for example Unix-based servers.
*
* In most cases you can leave this variable empty, as the correct value
* will be detected automatically. However, we recommend that you do
* test to see that the auto-detection code works in your system. A good
* test is to browse a table, then edit a row and save it. There will be
* an error message if phpMyAdmin cannot auto-detect the correct value.
*
* @global string $cfg['PmaAbsoluteUri']
*/
$cfg['PmaAbsoluteUri'] = '';
/**
* Disable the default warning that is displayed on the DB Details Structure page if
* any of the required Tables for the configuration storage could not be found

View File

@ -416,7 +416,9 @@ class ConfigFile
$dsn = 'mysqli://';
if ($this->getValue("$path/auth_type") == 'config') {
$dsn .= $this->getValue("$path/user");
if (! $this->getValue("$path/nopassword")) {
if (! $this->getValue("$path/nopassword")
|| ! empty($this->getValue("$path/password"))
) {
$dsn .= ':***';
}
$dsn .= '@';

View File

@ -271,8 +271,10 @@ class Validator
}
if (! $error && $values['Servers/1/auth_type'] == 'config') {
$password = !empty($values['Servers/1/nopassword']) && $values['Servers/1/nopassword'] ? null
: (empty($values['Servers/1/password']) ? '' : $values['Servers/1/password']);
$password = '';
if (! empty($values['Servers/1/password'])) {
$password = $values['Servers/1/password'];
}
$test = static::testDBConnection(
empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
empty($values['Servers/1/host']) ? '' : $values['Servers/1/host'],
@ -282,6 +284,24 @@ class Validator
$password,
'Server'
);
// If failed 'with' password, try 'without' password
if ($test !== true
&& !empty($values['Servers/1/nopassword'])
&& $values['Servers/1/nopassword']
) {
$password = '';
$test = static::testDBConnection(
empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
empty($values['Servers/1/host']) ? '' : $values['Servers/1/host'],
empty($values['Servers/1/port']) ? '' : $values['Servers/1/port'],
empty($values['Servers/1/socket']) ? '' : $values['Servers/1/socket'],
empty($values['Servers/1/user']) ? '' : $values['Servers/1/user'],
$password,
'Server'
);
}
if ($test !== true) {
$result = array_merge($result, $test);
}

View File

@ -134,7 +134,7 @@ class ServerVariablesController extends Controller
// when server is running in ANSI_QUOTES sql_mode
$varValue = $this->dbi->fetchSingleRow(
'SHOW GLOBAL VARIABLES WHERE Variable_name=\''
. Util::sqlAddSlashes($_REQUEST['varName']) . '\';',
. $GLOBALS['dbi']->escapeString($_REQUEST['varName']) . '\';',
'NUM'
);
@ -186,7 +186,7 @@ class ServerVariablesController extends Controller
$exp[mb_strtolower($matches[3])]
);
} else {
$value = Util::sqlAddSlashes($value);
$value = $GLOBALS['dbi']->escapeString($value);
}
if (! is_numeric($value)) {
@ -201,7 +201,7 @@ class ServerVariablesController extends Controller
// Some values are rounded down etc.
$varValue = $this->dbi->fetchSingleRow(
'SHOW GLOBAL VARIABLES WHERE Variable_name="'
. Util::sqlAddSlashes($_REQUEST['varName'])
. $GLOBALS['dbi']->escapeString($_REQUEST['varName'])
. '";', 'NUM'
);
$this->response->addJSON(

View File

@ -460,10 +460,10 @@ class TableSearchController extends TableController
return;
}
$key = array_search($field, $this->_columnNames);
$search_index = 0;
if (PMA_isValid($_REQUEST['it'], 'integer')) {
$search_index = $_REQUEST['it'];
}
$search_index
= ((isset($_REQUEST['it']) && is_numeric($_REQUEST['it']))
? intval($_REQUEST['it']) : 0);
$properties = $this->getColumnProperties($search_index, $key);
$this->response->addJSON(
'field_type', htmlspecialchars($properties['type'])
@ -716,7 +716,7 @@ class TableSearchController extends TableController
. " FROM " . Util::backquote($this->db)
. "." . Util::backquote($this->table)
. " WHERE " . Util::backquote($column)
. " RLIKE '" . Util::sqlAddSlashes($find) . "' COLLATE "
. " RLIKE '" . $GLOBALS['dbi']->escapeString($find) . "' COLLATE "
. $charSet . "_bin"; // here we
// change the collation of the 2nd operand to a case sensitive
// binary collation to make sure that the comparison is case sensitive
@ -774,13 +774,13 @@ class TableSearchController extends TableController
if (is_array($toReplace)) {
foreach ($toReplace as $row) {
$sql_query .= "\n WHEN " . Util::backquote($column)
. " = '" . Util::sqlAddSlashes($row[0])
. "' THEN '" . Util::sqlAddSlashes($row[1]) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($row[0])
. "' THEN '" . $GLOBALS['dbi']->escapeString($row[1]) . "'";
}
}
$sql_query .= " END"
. " WHERE " . Util::backquote($column)
. " RLIKE '" . Util::sqlAddSlashes($find) . "' COLLATE "
. " RLIKE '" . $GLOBALS['dbi']->escapeString($find) . "' COLLATE "
. $charSet . "_bin"; // here we
// change the collation of the 2nd operand to a case sensitive
// binary collation to make sure that the comparison
@ -1034,10 +1034,10 @@ class TableSearchController extends TableController
$parens_close = '';
}
$enum_where = '\''
. Util::sqlAddSlashes($criteriaValues[0]) . '\'';
. $GLOBALS['dbi']->escapeString($criteriaValues[0]) . '\'';
for ($e = 1; $e < $enum_selected_count; $e++) {
$enum_where .= ', \''
. Util::sqlAddSlashes($criteriaValues[$e]) . '\'';
. $GLOBALS['dbi']->escapeString($criteriaValues[$e]) . '\'';
}
return ' ' . $func_type . ' ' . $parens_open
@ -1163,7 +1163,7 @@ class TableSearchController extends TableController
&& 'NOT BETWEEN' != $func_type
) {
return $backquoted_name . ' ' . $func_type . ' ' . $quot
. Util::sqlAddSlashes($criteriaValues) . $quot;
. $GLOBALS['dbi']->escapeString($criteriaValues) . $quot;
}
$func_type = str_replace(' (...)', '', $func_type);
@ -1182,7 +1182,7 @@ class TableSearchController extends TableController
$value = 'NULL';
continue;
}
$value = $quot . Util::sqlAddSlashes(trim($value))
$value = $quot . $GLOBALS['dbi']->escapeString(trim($value))
. $quot;
}

View File

@ -602,12 +602,16 @@ class TableStructureController extends TableController
$partitionDetails['can_have_subpartitions']
= $partitionDetails['partition_count'] > 1
&& ($partitionDetails['partition_by'] == 'RANGE'
|| $partitionDetails['partition_by'] == 'LIST');
|| $partitionDetails['partition_by'] == 'RANGE COLUMNS'
|| $partitionDetails['partition_by'] == 'LIST'
|| $partitionDetails['partition_by'] == 'LIST COLUMNS');
// Values are specified only for LIST and RANGE type partitions
$partitionDetails['value_enabled'] = isset($partitionDetails['partition_by'])
&& ($partitionDetails['partition_by'] == 'RANGE'
|| $partitionDetails['partition_by'] == 'LIST');
|| $partitionDetails['partition_by'] == 'RANGE COLUMNS'
|| $partitionDetails['partition_by'] == 'LIST'
|| $partitionDetails['partition_by'] == 'LIST COLUMNS');
$partitionDetails['partitions'] = array();
@ -615,6 +619,7 @@ class TableStructureController extends TableController
if (! isset($stmt->partitions[$i])) {
$partitionDetails['partitions'][$i] = array(
'name' => 'p' . $i,
'value_type' => '',
'value' => '',
'engine' => '',
@ -635,6 +640,7 @@ class TableStructureController extends TableController
$expr = '';
}
$partitionDetails['partitions'][$i] = array(
'name' => $p->name,
'value_type' => $type,
'value' => $expr,
'engine' => $p->options->has('ENGINE', true),
@ -649,7 +655,6 @@ class TableStructureController extends TableController
}
$partition =& $partitionDetails['partitions'][$i];
$partition['name'] = 'p' . $i;
$partition['prefix'] = 'partitions[' . $i . ']';
if ($partitionDetails['subpartition_count'] > 1) {
@ -659,6 +664,7 @@ class TableStructureController extends TableController
for ($j = 0; $j < intval($partitionDetails['subpartition_count']); $j++) {
if (! isset($stmt->partitions[$i]->subpartitions[$j])) {
$partition['subpartitions'][$j] = array(
'name' => $partition['name'] . '_s' . $j,
'engine' => '',
'comment' => '',
'data_directory' => '',
@ -671,6 +677,7 @@ class TableStructureController extends TableController
} else {
$sp = $stmt->partitions[$i]->subpartitions[$j];
$partition['subpartitions'][$j] = array(
'name' => $sp->name,
'engine' => $sp->options->has('ENGINE', true),
'comment' => trim($sp->options->has('COMMENT', true), "'"),
'data_directory' => trim($sp->options->has('DATA DIRECTORY', true), "'"),
@ -683,7 +690,6 @@ class TableStructureController extends TableController
}
$subpartition =& $partition['subpartitions'][$j];
$subpartition['name'] = 'p' . $i . 's' . $j;
$subpartition['prefix'] = 'partitions[' . $i . ']'
. '[subpartitions][' . $j . ']';
}
@ -1205,8 +1211,8 @@ class TableStructureController extends TableController
FROM `INFORMATION_SCHEMA`.`VIEWS`
WHERE TABLE_SCHEMA='%s'
AND TABLE_NAME='%s';",
Util::sqlAddSlashes($this->db),
Util::sqlAddSlashes($this->table)
$GLOBALS['dbi']->escapeString($this->db),
$GLOBALS['dbi']->escapeString($this->table)
)
);

View File

@ -356,7 +356,7 @@ function PMA_getTableCount($db)
/**
* Converts numbers like 10M into bytes
* Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
* Used with permission from Moodle (https://moodle.org) by Martin Dougiamas
* (renamed with PMA prefix to avoid double definition when embedded
* in Moodle)
*
@ -503,7 +503,7 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
* like /phpmyadmin/index.php/ which some web servers happily accept.
*/
if ($uri[0] == '.') {
$uri = $GLOBALS['PMA_Config']->getCookiePath() . substr($uri, 2);
$uri = $GLOBALS['PMA_Config']->getRootPath() . substr($uri, 2);
}
$response = PMA\libraries\Response::getInstance();
@ -556,7 +556,7 @@ function PMA_noCacheHeader()
return;
}
// rfc2616 - Section 14.21
header('Expires: ' . date(DATE_RFC1123));
header('Expires: ' . gmdate(DATE_RFC1123));
// HTTP/1.1
header(
'Cache-Control: no-store, no-cache, must-revalidate,'
@ -579,7 +579,7 @@ function PMA_noCacheHeader()
// test case: exporting a database into a .gz file with Safari
// would produce files not having the current time
// (added this header for Safari but should not harm other browsers)
header('Last-Modified: ' . date(DATE_RFC1123));
header('Last-Modified: ' . gmdate(DATE_RFC1123));
}
@ -754,10 +754,17 @@ function PMA_linkURL($url)
function PMA_isAllowedDomain($url)
{
$arr = parse_url($url);
// Avoid URLs without hostname or with credentials
if (empty($arr['host']) || ! empty($arr['user']) || ! empty($arr['pass'])) {
// We need host to be set
if (! isset($arr['host']) || strlen($arr['host']) == 0) {
return false;
}
// We do not want these to be present
$blocked = array('user', 'pass', 'port');
foreach ($blocked as $part) {
if (isset($arr[$part]) && strlen($arr[$part]) != 0) {
return false;
}
}
$domain = $arr["host"];
$domainWhiteList = array(
/* Include current domain */
@ -766,6 +773,7 @@ function PMA_isAllowedDomain($url)
'wiki.phpmyadmin.net', 'www.phpmyadmin.net', 'phpmyadmin.net',
'demo.phpmyadmin.net',
'docs.phpmyadmin.net',
'demo.phpmyadmin.net',
/* mysql.com domains */
'dev.mysql.com','bugs.mysql.com',
/* mariadb domains */
@ -781,7 +789,7 @@ function PMA_isAllowedDomain($url)
/* Following are doubtful ones. */
'mysqldatabaseadministration.blogspot.com',
);
if (in_array(mb_strtolower($domain), $domainWhiteList)) {
if (in_array($domain, $domainWhiteList)) {
return true;
}
@ -1014,7 +1022,7 @@ if (! function_exists('hash_hmac')) {
/**
* Sanitizes MySQL hostname
*
* * strips p: prefix
* * strips p: prefix(es)
*
* @param string $name User given hostname
*
@ -1022,13 +1030,31 @@ if (! function_exists('hash_hmac')) {
*/
function PMA_sanitizeMySQLHost($name)
{
if (strtolower(substr($name, 0, 2)) == 'p:') {
return substr($name, 2);
while (strtolower(substr($name, 0, 2)) == 'p:') {
$name = substr($name, 2);
}
return $name;
}
/**
* Sanitizes MySQL username
*
* * strips part behind null byte
*
* @param string $name User given username
*
* @return string
*/
function PMA_sanitizeMySQLUser($name)
{
$position = strpos($name, chr(0));
if ($position !== false) {
return substr($name, 0, $position);
}
return $name;
}
/**
* Safe unserializer wrapper
*
@ -1062,7 +1088,7 @@ function PMA_safeUnserialize($data)
case 's':
/* string */
// parse sting length
$strlen = intval($data[$i + 2]);
$strlen = intval(substr($data, $i + 2));
// string start
$i = strpos($data, ':', $i + 2);
if ($i === false) {

View File

@ -166,7 +166,7 @@ function PMA_buildIndexStatements($index, $index_choice,
$keyBlockSizes = $index['Key_block_size'];
if (! empty($keyBlockSizes)) {
$sql_query .= " KEY_BLOCK_SIZE = "
. PMA\libraries\Util::sqlAddSlashes($keyBlockSizes);
. $GLOBALS['dbi']->escapeString($keyBlockSizes);
}
// specifying index type is allowed only for primary, unique and index only
@ -180,12 +180,12 @@ function PMA_buildIndexStatements($index, $index_choice,
$parser = $index['Parser'];
if ($index['Index_choice'] == 'FULLTEXT' && ! empty($parser)) {
$sql_query .= " WITH PARSER " . PMA\libraries\Util::sqlAddSlashes($parser);
$sql_query .= " WITH PARSER " . $GLOBALS['dbi']->escapeString($parser);
}
$comment = $index['Index_comment'];
if (! empty($comment)) {
$sql_query .= " COMMENT '" . PMA\libraries\Util::sqlAddSlashes($comment)
$sql_query .= " COMMENT '" . $GLOBALS['dbi']->escapeString($comment)
. "'";
}
@ -322,7 +322,7 @@ function PMA_getPartitionsDefinition()
$i = 0;
$partitions = array();
foreach ($_REQUEST['partitions'] as $partition) {
$partitions[] = PMA_getPartitionDefinition('p' . $i, $partition);
$partitions[] = PMA_getPartitionDefinition($partition);
$i++;
}
$sql_query .= " (" . implode(", ", $partitions) . ")";
@ -334,15 +334,15 @@ function PMA_getPartitionsDefinition()
/**
* Returns the definition of a partition/subpartition
*
* @param string $name name of the partition/subpartition
* @param array $partition array of partition/subpartition detiails
* @param boolean $isSubPartition whether a subpartition
*
* @return string partition/subpartition definition
*/
function PMA_getPartitionDefinition($name, $partition, $isSubPartition = false)
function PMA_getPartitionDefinition($partition, $isSubPartition = false)
{
$sql_query = " " . ($isSubPartition ? "SUB" : "") . "PARTITION " . $name;
$sql_query = " " . ($isSubPartition ? "SUB" : "") . "PARTITION ";
$sql_query .= $partition['name'];
if (! empty($partition['value_type'])) {
$sql_query .= " VALUES " . $partition['value_type'];
@ -382,7 +382,6 @@ function PMA_getPartitionDefinition($name, $partition, $isSubPartition = false)
$subpartitions = array();
foreach ($partition['subpartitions'] as $subpartition) {
$subpartitions[] = PMA_getPartitionDefinition(
$name . 's' . $j,
$subpartition,
true
);
@ -425,11 +424,11 @@ function PMA_getTableCreationQuery($db, $table)
&& $_REQUEST['tbl_storage_engine'] == 'FEDERATED'
) {
$sql_query .= " CONNECTION = '"
. PMA\libraries\Util::sqlAddSlashes($_REQUEST['connection']) . "'";
. $GLOBALS['dbi']->escapeString($_REQUEST['connection']) . "'";
}
if (!empty($_REQUEST['comment'])) {
$sql_query .= ' COMMENT = \''
. PMA\libraries\Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
. $GLOBALS['dbi']->escapeString($_REQUEST['comment']) . '\'';
}
$sql_query .= PMA_getPartitionsDefinition();
$sql_query .= ';';

View File

@ -82,7 +82,7 @@ function PMA_getPageIdsAndNames($db)
$page_query = "SELECT `page_nr`, `page_descr` FROM "
. PMA\libraries\Util::backquote($cfgRelation['db']) . "."
. PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. " WHERE db_name = '" . PMA\libraries\Util::sqlAddSlashes($db) . "'"
. " WHERE db_name = '" . $GLOBALS['dbi']->escapeString($db) . "'"
. " ORDER BY `page_descr`";
$page_rs = PMA_queryAsControlUser(
$page_query, false, PMA\libraries\DatabaseInterface::QUERY_STORE

View File

@ -62,7 +62,7 @@ if (empty($is_table)
if (! $is_table) {
$_result = $GLOBALS['dbi']->tryQuery(
'SHOW TABLES LIKE \''
. PMA\libraries\Util::sqlAddSlashes($table, true) . '\';',
. $GLOBALS['dbi']->escapeString($table) . '\';',
null, PMA\libraries\DatabaseInterface::QUERY_STORE
);
$is_table = @$GLOBALS['dbi']->numRows($_result);

View File

@ -696,7 +696,7 @@ $GLOBALS['dummy_queries'] = array(
array(
'query' => "SELECT `PARTITION_METHOD` "
. "FROM `information_schema`.`PARTITIONS` "
. "WHERE `TABLE_SCHEMA` = 'db' AND `TABLE_NAME` = 'table'",
. "WHERE `TABLE_SCHEMA` = 'db' AND `TABLE_NAME` = 'table' LIMIT 1",
'result' => array(),
),
array(
@ -1256,4 +1256,17 @@ class DBIDummy implements DBIExtension
{
return '';
}
/**
* returns properly escaped string for use in MySQL queries
*
* @param mixed $link database link
* @param string $str string to be escaped
*
* @return string a MySQL escaped string
*/
public function escapeString($link, $str)
{
return $str;
}
}

View File

@ -235,4 +235,14 @@ interface DBIExtension
* @return string field flags
*/
public function fieldFlags($result, $i);
/**
* returns properly escaped string for use in MySQL queries
*
* @param mixed $link database link
* @param string $str string to be escaped
*
* @return string a MySQL escaped string
*/
public function escapeString($link, $str);
}

View File

@ -471,4 +471,17 @@ class DBIMysql implements DBIExtension
{
return false;
}
/**
* returns properly escaped string for use in MySQL queries
*
* @param mixed $link database link
* @param string $str string to be escaped
*
* @return string a MySQL escaped string
*/
public function escapeString($link, $str)
{
return mysql_real_escape_string($str, $link);
}
}

View File

@ -64,7 +64,6 @@ class DBIMysqli implements DBIExtension
* @param string $host mysql hostname
* @param string $user mysql user name
* @param string $password mysql user password
* @param string $dbname database name
* @param int $server_port server port
* @param string $server_socket server socket
* @param int $client_flags client flags of connection
@ -73,7 +72,7 @@ class DBIMysqli implements DBIExtension
* @return bool
*/
private function _realConnect(
$link, $host, $user, $password, $dbname, $server_port,
$link, $host, $user, $password, $server_port,
$server_socket, $client_flags = null, $persistent = false
) {
global $cfg;
@ -89,7 +88,7 @@ class DBIMysqli implements DBIExtension
$host,
$user,
$password,
$dbname,
'',
$server_port,
$server_socket
);
@ -99,7 +98,7 @@ class DBIMysqli implements DBIExtension
$host,
$user,
$password,
$dbname,
'',
$server_port,
$server_socket,
$client_flags
@ -185,7 +184,6 @@ class DBIMysqli implements DBIExtension
$cfg['Server']['host'],
$user,
$password,
false,
$server_port,
$server_socket,
$client_flags
@ -201,7 +199,6 @@ class DBIMysqli implements DBIExtension
$cfg['Server']['host'],
$user,
'',
false,
$server_port,
$server_socket,
$client_flags
@ -213,7 +210,6 @@ class DBIMysqli implements DBIExtension
$server['host'],
$user,
$password,
false,
$server_port,
$server_socket
);
@ -619,4 +615,17 @@ class DBIMysqli implements DBIExtension
}
return implode(' ', $flags);
}
/**
* returns properly escaped string for use in MySQL queries
*
* @param mixed $link database link
* @param string $str string to be escaped
*
* @return string a MySQL escaped string
*/
public function escapeString($link, $str)
{
return mysqli_real_escape_string($link, $str);
}
}

View File

@ -249,8 +249,8 @@ function PMA_getOptionsForExportTemplates($export_type)
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['export_templates'])
. " WHERE `username` = "
. "'" . PMA\libraries\Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user'])
. "' AND `export_type` = '" . PMA\libraries\Util::sqlAddSlashes($export_type) . "'"
. "'" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user'])
. "' AND `export_type` = '" . $GLOBALS['dbi']->escapeString($export_type) . "'"
. " ORDER BY `template_name`;";
$result = PMA_queryAsControlUser($query);
@ -1113,14 +1113,14 @@ function PMA_getExportDisplay(
function PMA_handleExportTemplateActions($cfgRelation)
{
if (isset($_REQUEST['templateId'])) {
$id = PMA\libraries\Util::sqlAddSlashes($_REQUEST['templateId']);
$id = $GLOBALS['dbi']->escapeString($_REQUEST['templateId']);
} else {
$id = '';
}
$templateTable = PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['export_templates']);
$user = PMA\libraries\Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']);
$user = $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']);
switch ($_REQUEST['templateAction']) {
case 'create':
@ -1129,9 +1129,9 @@ function PMA_handleExportTemplateActions($cfgRelation)
. " `template_name`, `template_data`"
. ") VALUES ("
. "'" . $user . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['exportType'])
. "', '" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['templateName'])
. "', '" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['templateData'])
. "'" . $GLOBALS['dbi']->escapeString($_REQUEST['exportType'])
. "', '" . $GLOBALS['dbi']->escapeString($_REQUEST['templateName'])
. "', '" . $GLOBALS['dbi']->escapeString($_REQUEST['templateData'])
. "');";
break;
case 'load':
@ -1140,7 +1140,7 @@ function PMA_handleExportTemplateActions($cfgRelation)
break;
case 'update':
$query = "UPDATE " . $templateTable . " SET `template_data` = "
. "'" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['templateData']) . "'"
. "'" . $GLOBALS['dbi']->escapeString($_REQUEST['templateData']) . "'"
. " WHERE `id` = " . $id . " AND `username` = '" . $user . "'";
break;
case 'delete':

View File

@ -18,12 +18,10 @@ use PMA\libraries\ZipFile;
*/
function PMA_shutdownDuringExport()
{
$a = error_get_last();
if ($a != null && mb_strpos($a['message'], "execution time")) {
//write in partially downloaded file for future reference of user
print_r($a);
$error = error_get_last();
if ($error != null && mb_strpos($error['message'], "execution time")) {
//set session variable to check if there was error while exporting
$_SESSION['pma_export_error'] = $a['message'];
$_SESSION['pma_export_error'] = $error['message'];
}
}
@ -655,8 +653,8 @@ function PMA_exportDatabase(
// This obtains the current table's size
$query = 'SELECT data_length + index_length
from information_schema.TABLES
WHERE table_schema = "' . PMA\libraries\Util::sqlAddSlashes($db) . '"
AND table_name = "' . PMA\libraries\Util::sqlAddSlashes($table) . '"';
WHERE table_schema = "' . $GLOBALS['dbi']->escapeString($db) . '"
AND table_name = "' . $GLOBALS['dbi']->escapeString($table) . '"';
$size = $GLOBALS['dbi']->fetchValue($query);
//Converting the size to MB
@ -682,8 +680,13 @@ function PMA_exportDatabase(
&& in_array($table, $table_data)
&& ! ($is_view)
) {
$local_query = 'SELECT * FROM ' . PMA\libraries\Util::backquote($db)
$tableObj = new PMA\libraries\Table($table, $db);
$nonGeneratedCols = $tableObj->getNonGeneratedColumns(true);
$local_query = 'SELECT ' . implode(', ', $nonGeneratedCols)
. ' FROM ' . PMA\libraries\Util::backquote($db)
. '.' . PMA\libraries\Util::backquote($table);
if (! $export_plugin->exportData(
$db, $table, $crlf, $err_url, $local_query, $aliases
)) {
@ -862,7 +865,12 @@ function PMA_exportTable(
$local_query = $sql_query . $add_query;
$GLOBALS['dbi']->selectDb($db);
} else {
$local_query = 'SELECT * FROM ' . PMA\libraries\Util::backquote($db)
// Data is exported only for Non-generated columns
$tableObj = new PMA\libraries\Table($table, $db);
$nonGeneratedCols = $tableObj->getNonGeneratedColumns(true);
$local_query = 'SELECT ' . implode(', ', $nonGeneratedCols)
. ' FROM ' . PMA\libraries\Util::backquote($db)
. '.' . PMA\libraries\Util::backquote($table) . $add_query;
}
if (! $export_plugin->exportData(

View File

@ -18,11 +18,6 @@ if (! defined('PHPMYADMIN')) {
*/
require_once './libraries/check_user_privileges.lib.php';
/**
* We do this check, DROP DATABASE does not need to be confirmed elsewhere
*/
define('PMA_CHK_DROP', 1);
/**
* Checks whether timeout is getting close
*
@ -189,7 +184,6 @@ function PMA_importRunQuery($sql = '', $full = '', &$sql_data = array())
if (! empty($import_run_buffer['sql'])
&& trim($import_run_buffer['sql']) != ''
) {
$max_sql_len = max(
$max_sql_len,
mb_strlen($import_run_buffer['sql'])
@ -197,63 +191,53 @@ function PMA_importRunQuery($sql = '', $full = '', &$sql_data = array())
if (! $sql_query_disabled) {
$sql_query .= $import_run_buffer['full'];
}
$pattern = '@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?'
. 'DATABASE @i';
if (! $cfg['AllowUserDropDatabase']
&& ! $is_superuser
&& preg_match($pattern, $import_run_buffer['sql'])
) {
$GLOBALS['message'] = Message::error(
__('"DROP DATABASE" statements are disabled.')
$executed_queries++;
if ($run_query && $executed_queries < 50) {
$go_sql = true;
if (! $sql_query_disabled) {
$complete_query = $sql_query;
$display_query = $sql_query;
} else {
$complete_query = '';
$display_query = '';
}
$sql_query = $import_run_buffer['sql'];
$sql_data['valid_sql'][] = $import_run_buffer['sql'];
$sql_data['valid_full'][] = $import_run_buffer['full'];
if (! isset($sql_data['valid_queries'])) {
$sql_data['valid_queries'] = 0;
}
$sql_data['valid_queries']++;
} elseif ($run_query) {
/* Handle rollback from go_sql */
if ($go_sql && isset($sql_data['valid_full'])) {
$queries = $sql_data['valid_sql'];
$fulls = $sql_data['valid_full'];
$count = $sql_data['valid_queries'];
$go_sql = false;
$sql_data['valid_sql'] = array();
$sql_data['valid_queries'] = 0;
unset($sql_data['valid_full']);
for ($i = 0; $i < $count; $i++) {
PMA_executeQuery(
$queries[$i],
$fulls[$i],
$sql_data
);
}
}
PMA_executeQuery(
$import_run_buffer['sql'],
$import_run_buffer['full'],
$sql_data
);
$error = true;
} else {
$executed_queries++;
if ($run_query && $executed_queries < 50) {
$go_sql = true;
if (! $sql_query_disabled) {
$complete_query = $sql_query;
$display_query = $sql_query;
} else {
$complete_query = '';
$display_query = '';
}
$sql_query = $import_run_buffer['sql'];
$sql_data['valid_sql'][] = $import_run_buffer['sql'];
$sql_data['valid_full'][] = $import_run_buffer['full'];
if (! isset($sql_data['valid_queries'])) {
$sql_data['valid_queries'] = 0;
}
$sql_data['valid_queries']++;
} elseif ($run_query) {
/* Handle rollback from go_sql */
if ($go_sql && isset($sql_data['valid_full'])) {
$queries = $sql_data['valid_sql'];
$fulls = $sql_data['valid_full'];
$count = $sql_data['valid_queries'];
$go_sql = false;
$sql_data['valid_sql'] = array();
$sql_data['valid_queries'] = 0;
unset($sql_data['valid_full']);
for ($i = 0; $i < $count; $i++) {
PMA_executeQuery(
$queries[$i],
$fulls[$i],
$sql_data
);
}
}
PMA_executeQuery(
$import_run_buffer['sql'],
$import_run_buffer['full'],
$sql_data
);
} // end run query
} // end if not DROP DATABASE
} // end run query
// end non empty query
} elseif (! empty($import_run_buffer['full'])) {
if ($go_sql) {
@ -1160,7 +1144,7 @@ function PMA_buildSQL($db_name, &$tables, &$analyses = null,
}
$tempSQLStr .= (($is_varchar) ? "'" : "");
$tempSQLStr .= PMA\libraries\Util::sqlAddSlashes(
$tempSQLStr .= $GLOBALS['dbi']->escapeString(
(string) $tables[$i][ROWS][$j][$k]
);
$tempSQLStr .= (($is_varchar) ? "'" : "");

View File

@ -379,12 +379,14 @@ function PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen)
* @param integer $tabindex tab index
* @param integer $idindex id index
* @param boolean $insert_mode insert mode or edit mode
* @param boolean $readOnly is column read only or not
* @param array $foreignData foreign key data
*
* @return string an html snippet
*/
function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
$onChangeClause, $no_support_types, $tabindex_for_function,
$tabindex, $idindex, $insert_mode
$tabindex, $idindex, $insert_mode, $readOnly, $foreignData
) {
$html_output = '';
if (($GLOBALS['cfg']['ProtectBinary'] === 'blob'
@ -395,7 +397,8 @@ function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
&& $column['is_binary'])
) {
$html_output .= '<td class="center">' . __('Binary') . '</td>' . "\n";
} elseif (mb_strstr($column['True_Type'], 'enum')
} elseif ($readOnly
|| mb_strstr($column['True_Type'], 'enum')
|| mb_strstr($column['True_Type'], 'set')
|| in_array($column['pma_type'], $no_support_types)
) {
@ -409,7 +412,8 @@ function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
. ' id="field_' . $idindex . '_1">';
$html_output .= PMA\libraries\Util::getFunctionsForField(
$column,
$insert_mode
$insert_mode,
$foreignData
) . "\n";
$html_output .= '</select>' . "\n";
@ -430,13 +434,15 @@ function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
* @param string $vkey [multi_edit]['row_id']
* @param array $foreigners keys into foreign fields
* @param array $foreignData data about the foreign keys
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getNullColumn($column, $column_name_appendix, $real_null_value,
$tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData
$tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData,
$readOnly
) {
if ($column['Null'] != 'YES') {
if ($column['Null'] != 'YES' || $readOnly) {
return "<td></td>\n";
}
$html_output = '';
@ -544,6 +550,7 @@ function PMA_getNullifyCodeForNullColumn($column, $foreigners, $foreignData)
* @param array $extracted_columnspec associative array containing type,
* spec_in_brackets and possibly
* enum_set_values (another array)
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
@ -552,7 +559,8 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$special_chars, $foreignData, $odd_row, $paramTableDbArray, $rownumber,
$titles, $text_dir, $special_chars_encoded, $vkey,
$is_upload, $biggest_max_file_size,
$default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec
$default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec,
$readOnly
) {
// HTML5 data-* attribute data-type
$data_type = $GLOBALS['PMA_Types']->getTypeClass($column['True_Type']);
@ -562,14 +570,14 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$html_output .= PMA_getForeignLink(
$column, $backup_field, $column_name_appendix,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data,
$paramTableDbArray, $rownumber, $titles
$paramTableDbArray, $rownumber, $titles, $readOnly
);
} elseif (is_array($foreignData['disp_row'])) {
$html_output .= PMA_dispRowForeignData(
$backup_field, $column_name_appendix,
$onChangeClause, $tabindex, $tabindex_for_value,
$idindex, $data, $foreignData
$idindex, $data, $foreignData, $readOnly
);
} elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
@ -582,7 +590,7 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$html_output .= PMA_getTextarea(
$column, $backup_field, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $text_dir,
$special_chars_encoded, $data_type
$special_chars_encoded, $data_type, $readOnly
);
} elseif (mb_strstr($column['pma_type'], 'text')) {
@ -590,7 +598,7 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$html_output .= PMA_getTextarea(
$column, $backup_field, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $text_dir,
$special_chars_encoded, $data_type
$special_chars_encoded, $data_type, $readOnly
);
$html_output .= "\n";
if (mb_strlen($special_chars) > 32000) {
@ -603,14 +611,15 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
} elseif ($column['pma_type'] == 'enum') {
$html_output .= PMA_getPmaTypeEnum(
$column, $backup_field, $column_name_appendix, $extracted_columnspec,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data,
$readOnly
);
} elseif ($column['pma_type'] == 'set') {
$html_output .= PMA_getPmaTypeSet(
$column, $extracted_columnspec, $backup_field,
$column_name_appendix, $onChangeClause, $tabindex,
$tabindex_for_value, $idindex, $data
$tabindex_for_value, $idindex, $data, $readOnly
);
} elseif ($column['is_binary'] || $column['is_blob']) {
@ -618,7 +627,7 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$column, $data, $special_chars, $biggest_max_file_size,
$backup_field, $column_name_appendix, $onChangeClause, $tabindex,
$tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
$vkey, $is_upload
$vkey, $is_upload, $readOnly
);
} elseif (! in_array($column['pma_type'], $no_support_types)) {
@ -626,7 +635,7 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
$column, $default_char_editing, $backup_field,
$column_name_appendix, $onChangeClause, $tabindex, $special_chars,
$tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
$data, $extracted_columnspec
$data, $extracted_columnspec, $readOnly
);
}
@ -653,12 +662,13 @@ function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
* @param array $titles An HTML IMG tag for a particular icon from
* a theme, which may be an actual file or
* an icon from a sprite
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data,
$paramTableDbArray, $rownumber, $titles
$paramTableDbArray, $rownumber, $titles, $readOnly
) {
list($table, $db) = $paramTableDbArray;
$html_output = '';
@ -670,6 +680,7 @@ function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
$html_output .= '<input type="text" name="fields' . $column_name_appendix . '" '
. 'class="textfield" '
. $onChangeClause . ' '
. ($readOnly ? 'readonly="readonly" ' : '')
. 'tabindex="' . ($tabindex + $tabindex_for_value) . '" '
. 'id="field_' . ($idindex) . '_3" '
. 'value="' . htmlspecialchars($data) . '" />';
@ -699,12 +710,13 @@ function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
* @param integer $idindex id index
* @param string $data data to edit
* @param array $foreignData data about the foreign keys
* @param boolean $readOnly is display read only or not
*
* @return string an html snippet
*/
function PMA_dispRowForeignData($backup_field, $column_name_appendix,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data,
$foreignData
$foreignData, $readOnly
) {
$html_output = '';
$html_output .= $backup_field . "\n";
@ -715,6 +727,7 @@ function PMA_dispRowForeignData($backup_field, $column_name_appendix,
$html_output .= '<select name="fields' . $column_name_appendix . '"'
. ' ' . $onChangeClause
. ' class="textfield"'
. ($readOnly ? ' disabled' : '')
. ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
. ' id="field_' . $idindex . '_3">';
$html_output .= PMA_foreignDropdown(
@ -724,6 +737,12 @@ function PMA_dispRowForeignData($backup_field, $column_name_appendix,
);
$html_output .= '</select>';
//Add hidden input, as disabled <select> input does not included in POST.
if ($readOnly) {
$html_output .= '<input name="fields' . $column_name_appendix . '"'
. ' type="hidden" value="' . htmlspecialchars($data) . '">';
}
return $html_output;
}
@ -741,12 +760,13 @@ function PMA_dispRowForeignData($backup_field, $column_name_appendix,
* @param string $special_chars_encoded replaced char if the string starts
* with a \r\n pair (0x0d0a) add an extra \n
* @param string $data_type the html5 data-* attribute type
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getTextarea($column, $backup_field, $column_name_appendix,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex,
$text_dir, $special_chars_encoded, $data_type
$text_dir, $special_chars_encoded, $data_type, $readOnly
) {
$the_class = '';
$textAreaRows = $GLOBALS['cfg']['TextareaRows'];
@ -773,6 +793,7 @@ function PMA_getTextarea($column, $backup_field, $column_name_appendix,
$html_output = $backup_field . "\n"
. '<textarea name="fields' . $column_name_appendix . '"'
. ' class="' . $the_class . '"'
. ($readOnly ? ' readonly="readonly"' : '')
. (isset($maxlength) ? ' data-maxlength="' . $maxlength . '"' : '')
. ' rows="' . $textAreaRows . '"'
. ' cols="' . $textareaCols . '"'
@ -801,12 +822,13 @@ function PMA_getTextarea($column, $backup_field, $column_name_appendix,
* @param integer $tabindex_for_value offset for the values tabindex
* @param integer $idindex id index
* @param mixed $data data to edit
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getPmaTypeEnum($column, $backup_field, $column_name_appendix,
$extracted_columnspec, $onChangeClause, $tabindex, $tabindex_for_value,
$idindex, $data
$idindex, $data, $readOnly
) {
$html_output = '';
if (! isset($column['values'])) {
@ -821,13 +843,14 @@ function PMA_getPmaTypeEnum($column, $backup_field, $column_name_appendix,
if (mb_strlen($column['Type']) > 20) {
$html_output .= PMA_getDropDownDependingOnLength(
$column, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
$tabindex, $tabindex_for_value,
$idindex, $data, $column_enum_values, $readOnly
);
} else {
$html_output .= PMA_getRadioButtonDependingOnLength(
$column_name_appendix, $onChangeClause,
$tabindex, $column, $tabindex_for_value,
$idindex, $data, $column_enum_values
$idindex, $data, $column_enum_values, $readOnly
);
}
return $html_output;
@ -871,15 +894,18 @@ function PMA_getColumnEnumValues($column, $extracted_columnspec)
*/
function PMA_getDropDownDependingOnLength(
$column, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
$tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values,
$readOnly
) {
$html_output = '<select name="fields' . $column_name_appendix . '"'
. ' ' . $onChangeClause
. ' class="textfield"'
. ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
. ($readOnly ? ' disabled' : '')
. ' id="field_' . ($idindex) . '_3">';
$html_output .= '<option value="">&nbsp;</option>' . "\n";
$selected_html = '';
foreach ($column_enum_values as $enum_value) {
$html_output .= '<option value="' . $enum_value['html'] . '"';
if ($data == $enum_value['plain']
@ -889,10 +915,17 @@ function PMA_getDropDownDependingOnLength(
&& $enum_value['plain'] == $column['Default'])
) {
$html_output .= ' selected="selected"';
$selected_html = $enum_value['html'];
}
$html_output .= '>' . $enum_value['html'] . '</option>' . "\n";
}
$html_output .= '</select>';
//Add hidden input, as disabled <select> input does not included in POST.
if ($readOnly) {
$html_output .= '<input name="fields' . $column_name_appendix . '"'
. ' type="hidden" value="' . $selected_html . '">';
}
return $html_output;
}
@ -912,7 +945,8 @@ function PMA_getDropDownDependingOnLength(
*/
function PMA_getRadioButtonDependingOnLength(
$column_name_appendix, $onChangeClause,
$tabindex, $column, $tabindex_for_value, $idindex, $data, $column_enum_values
$tabindex, $column, $tabindex_for_value, $idindex, $data,
$column_enum_values, $readOnly
) {
$j = 0;
$html_output = '';
@ -931,6 +965,9 @@ function PMA_getRadioButtonDependingOnLength(
) {
$html_output .= ' checked="checked"';
}
elseif ($readOnly) {
$html_output .= ' disabled';
}
$html_output .= ' tabindex="' . ($tabindex + $tabindex_for_value) . '" />';
$html_output .= '<label for="field_' . $idindex . '_3_' . $j . '">'
. $enum_value['html'] . '</label>' . "\n";
@ -953,13 +990,14 @@ function PMA_getRadioButtonDependingOnLength(
* @param integer $tabindex_for_value offset for the values tabindex
* @param integer $idindex id index
* @param string $data description of the column field
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getPmaTypeSet(
$column, $extracted_columnspec, $backup_field,
$column_name_appendix, $onChangeClause, $tabindex,
$tabindex_for_value, $idindex, $data
$tabindex_for_value, $idindex, $data, $readOnly
) {
list($column_set_values, $select_size) = PMA_getColumnSetValueAndSelectSize(
$column, $extracted_columnspec
@ -970,19 +1008,29 @@ function PMA_getPmaTypeSet(
. $column_name_appendix . '" value="set" />';
$html_output .= '<select name="fields' . $column_name_appendix . '[]' . '"'
. ' class="textfield"'
. ($readOnly ? ' disabled' : '')
. ' size="' . $select_size . '"'
. ' multiple="multiple"'
. ' ' . $onChangeClause
. ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
. ' id="field_' . ($idindex) . '_3">';
$selected_html = '';
foreach ($column_set_values as $column_set_value) {
$html_output .= '<option value="' . $column_set_value['html'] . '"';
if (isset($vset[$column_set_value['plain']])) {
$html_output .= ' selected="selected"';
$selected_html = $column_set_value['html'];
}
$html_output .= '>' . $column_set_value['html'] . '</option>' . "\n";
}
$html_output .= '</select>';
//Add hidden input, as disabled <select> input does not included in POST.
if ($readOnly) {
$html_output .= '<input name="fields' . $column_name_appendix . '[]' . '"'
. ' type="hidden" value="' . $selected_html . '">';
}
return $html_output;
}
@ -1029,6 +1077,7 @@ function PMA_getColumnSetValueAndSelectSize($column, $extracted_columnspec)
* with a \r\n pair (0x0d0a) add an extra \n
* @param string $vkey [multi_edit]['row_id']
* @param boolean $is_upload is upload or not
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
@ -1036,7 +1085,7 @@ function PMA_getBinaryAndBlobColumn(
$column, $data, $special_chars, $biggest_max_file_size,
$backup_field, $column_name_appendix, $onChangeClause, $tabindex,
$tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
$vkey, $is_upload
$vkey, $is_upload, $readOnly
) {
$html_output = '';
// Add field type : Protected or Hexadecimal
@ -1065,23 +1114,27 @@ function PMA_getBinaryAndBlobColumn(
$html_output .= "\n" . PMA_getTextarea(
$column, $backup_field, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $text_dir,
$special_chars_encoded, 'HEX'
$special_chars_encoded, 'HEX', $readOnly
);
} else {
// field size should be at least 4 and max $GLOBALS['cfg']['LimitChars']
$fieldsize = min(max($column['len'], 4), $GLOBALS['cfg']['LimitChars']);
$html_output .= "\n" . $backup_field . "\n" . PMA_getHTMLinput(
$column, $column_name_appendix, $special_chars, $fieldsize,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, 'HEX'
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, 'HEX',
$readOnly
);
}
$html_output .= sprintf($fields_type_html, $fields_type_val);
if ($is_upload && $column['is_blob']) {
if ($is_upload && $column['is_blob'] && !$readOnly) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s),
// so we add noDragDrop class to the input
$html_output .= '<br />'
. '<input type="file"'
. ' name="fields_upload' . $vkey . '[' . $column['Field_md5'] . ']"'
. ' class="textfield" id="field_' . $idindex . '_3" size="10"'
. ' class="textfield noDragDrop" id="field_' . $idindex . '_3" size="10"'
. ' ' . $onChangeClause . '/>&nbsp;';
list($html_out,) = PMA_getMaxUploadSize(
$column, $biggest_max_file_size
@ -1089,7 +1142,7 @@ function PMA_getBinaryAndBlobColumn(
$html_output .= $html_out;
}
if (!empty($GLOBALS['cfg']['UploadDir'])) {
if (!empty($GLOBALS['cfg']['UploadDir']) && !$readOnly) {
$html_output .= PMA_getSelectOptionForUpload($vkey, $column);
}
@ -1108,12 +1161,13 @@ function PMA_getBinaryAndBlobColumn(
* @param integer $tabindex_for_value offset for the values tabindex
* @param integer $idindex id index
* @param string $data_type the html5 data-* attribute type
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
function PMA_getHTMLinput(
$column, $column_name_appendix, $special_chars, $fieldsize, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $data_type
$tabindex, $tabindex_for_value, $idindex, $data_type, $readOnly
) {
$input_type = 'text';
// do not use the 'date' or 'time' types here; they have no effect on some
@ -1121,7 +1175,9 @@ function PMA_getHTMLinput(
$the_class = 'textfield';
// verify True_Type which does not contain the parentheses and length
if ($column['True_Type'] === 'date') {
if ($readOnly) {
//NOOP. Disable date/timepicker
} else if ($column['True_Type'] === 'date') {
$the_class .= ' datefield';
} else if ($column['True_Type'] === 'time') {
$the_class .= ' timefield';
@ -1149,6 +1205,7 @@ function PMA_getHTMLinput(
. ((isset($column['is_char']) && $column['is_char'])
? ' data-maxlength="' . $fieldsize . '"'
: '')
. ($readOnly ? ' readonly="readonly"' : '')
. ($input_min_max !== false ? ' ' . $input_min_max : '')
. ' data-type="' . $data_type . '"'
. ($input_type === 'time' ? ' step="1"' : '')
@ -1248,6 +1305,7 @@ function PMA_getMaxUploadSize($column, $biggest_max_file_size)
* @param array $extracted_columnspec associative array containing type,
* spec_in_brackets and possibly
* enum_set_values (another array)
* @param boolean $readOnly is column read only or not
*
* @return string an html snippet
*/
@ -1255,7 +1313,7 @@ function PMA_getValueColumnForOtherDatatypes($column, $default_char_editing,
$backup_field,
$column_name_appendix, $onChangeClause, $tabindex, $special_chars,
$tabindex_for_value, $idindex, $text_dir, $special_chars_encoded, $data,
$extracted_columnspec
$extracted_columnspec, $readOnly
) {
// HTML5 data-* attribute data-type
$data_type = $GLOBALS['PMA_Types']->getTypeClass($column['True_Type']);
@ -1270,12 +1328,13 @@ function PMA_getValueColumnForOtherDatatypes($column, $default_char_editing,
$html_output .= PMA_getTextarea(
$column, $backup_field, $column_name_appendix, $onChangeClause,
$tabindex, $tabindex_for_value, $idindex, $text_dir,
$special_chars_encoded, $data_type
$special_chars_encoded, $data_type, $readOnly
);
} else {
$html_output .= PMA_getHTMLinput(
$column, $column_name_appendix, $special_chars, $fieldsize,
$onChangeClause, $tabindex, $tabindex_for_value, $idindex, $data_type
$onChangeClause, $tabindex, $tabindex_for_value, $idindex,
$data_type, $readOnly
);
$virtual = array(
@ -2198,7 +2257,7 @@ function PMA_getCurrentValueAsAnArrayForMultipleEdit( $multi_edit_funcs,
|| $multi_edit_funcs[$key] == "ENCRYPT"))
) {
return $multi_edit_funcs[$key] . '(' . $current_value . ",'"
. PMA\libraries\Util::sqlAddSlashes($multi_edit_salt[$key]) . "')";
. $GLOBALS['dbi']->escapeString($multi_edit_salt[$key]) . "')";
} else {
return $multi_edit_funcs[$key] . '(' . $current_value . ')';
}
@ -2257,7 +2316,7 @@ function PMA_getQueryValuesForInsertAndUpdateInMultipleEdit($multi_edit_columns_
. ' = ' . $current_value_as_an_array;
} elseif (empty($multi_edit_funcs[$key])
&& isset($multi_edit_columns_prev[$key])
&& (("'" . PMA\libraries\Util::sqlAddSlashes($multi_edit_columns_prev[$key]) . "'" === $current_value)
&& (("'" . $GLOBALS['dbi']->escapeString($multi_edit_columns_prev[$key]) . "'" === $current_value)
|| ('0x' . $multi_edit_columns_prev[$key] === $current_value))
) {
// No change for this column and no MySQL function is used -> next column
@ -2316,7 +2375,7 @@ function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
if (false !== $possibly_uploaded_val) {
$current_value = $possibly_uploaded_val;
} else if (! empty($multi_edit_funcs[$key])) {
$current_value = "'" . PMA\libraries\Util::sqlAddSlashes($current_value)
$current_value = "'" . $GLOBALS['dbi']->escapeString($current_value)
. "'";
} else {
// c o l u m n v a l u e i n t h e f o r m
@ -2344,7 +2403,7 @@ function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
',', $_REQUEST['fields']['multi_edit'][$rownumber][$key]
);
$current_value = "'"
. PMA\libraries\Util::sqlAddSlashes($current_value) . "'";
. $GLOBALS['dbi']->escapeString($current_value) . "'";
} else {
$current_value = "''";
}
@ -2367,12 +2426,12 @@ function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
$current_value = '0x' . $current_value;
} elseif ($type == 'bit') {
$current_value = preg_replace('/[^01]/', '0', $current_value);
$current_value = "b'" . PMA\libraries\Util::sqlAddSlashes($current_value)
$current_value = "b'" . $GLOBALS['dbi']->escapeString($current_value)
. "'";
} elseif (! ($type == 'datetime' || $type == 'timestamp')
|| $current_value != 'CURRENT_TIMESTAMP'
) {
$current_value = "'" . PMA\libraries\Util::sqlAddSlashes($current_value)
$current_value = "'" . $GLOBALS['dbi']->escapeString($current_value)
. "'";
}
@ -2700,6 +2759,11 @@ function PMA_getHtmlForInsertEditFormColumn($table_columns, $column_number,
$text_dir, $repopulate, $column_mime, $where_clause
) {
$column = $table_columns[$column_number];
$readOnly = false;
if (! PMA_userHasColumnPrivileges($column, $insert_mode)) {
$readOnly = true;
}
if (! isset($column['processed'])) {
$column = PMA_analyzeTableColumnsArray(
$column, $comments_map, $timestamp_seen
@ -2790,23 +2854,23 @@ function PMA_getHtmlForInsertEditFormColumn($table_columns, $column_number,
// The function column
// -------------------
$foreignData = PMA_getForeignData(
$foreigners, $column['Field'], false, '', ''
);
if ($GLOBALS['cfg']['ShowFunctionFields']) {
$html_output .= PMA_getFunctionColumn(
$column, $is_upload, $column_name_appendix,
$onChangeClause, $no_support_types, $tabindex_for_function,
$tabindex, $idindex, $insert_mode
$tabindex, $idindex, $insert_mode, $readOnly, $foreignData
);
}
// The null column
// ---------------
$foreignData = PMA_getForeignData(
$foreigners, $column['Field'], false, '', ''
);
$html_output .= PMA_getNullColumn(
$column, $column_name_appendix, $real_null_value,
$tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners,
$foreignData
$foreignData, $readOnly
);
// The value column (depends on type)
@ -2875,7 +2939,7 @@ function PMA_getHtmlForInsertEditFormColumn($table_columns, $column_number,
$foreignData, $odd_row, array($table, $db), $row_id, $titles,
$text_dir, $special_chars_encoded, $vkey, $is_upload,
$biggest_max_file_size, $default_char_editing,
$no_support_types, $gis_data_types, $extracted_columnspec
$no_support_types, $gis_data_types, $extracted_columnspec, $readOnly
);
}
$html_output .= '</td>'
@ -2936,10 +3000,6 @@ function PMA_getHtmlForInsertEditRow($url_params, $table_columns,
}
for ($column_number = 0; $column_number < $columns_cnt; $column_number++) {
$table_column = $table_columns[$column_number];
// skip this column if user does not have necessary column privilges
if (! PMA_userHasColumnPrivileges($table_column, $insert_mode)) {
continue;
}
$column_mime = array();
if (isset($mime_map[$table_column['Field']])) {
$column_mime = $mime_map[$table_column['Field']];

View File

@ -194,7 +194,7 @@ function PMA_ipv6MaskTest($test_range, $ip_to_test)
if ($is_single) {
$range_hex = bin2hex(inet_pton($test_range));
$result = $ip_hex === $range_hex;
$result = hash_equals($ip_hex, $range_hex);
return $result;
}
@ -321,7 +321,7 @@ function PMA_allowDeny($type)
// check for username
if (($rule_data[1] != '%') //wildcarded first
&& ($rule_data[1] != $username)
&& (! hash_equals($rule_data[1], $username))
) {
continue;
}

View File

@ -117,7 +117,7 @@ function PMA_getDbCollation($db)
if (! $GLOBALS['cfg']['Server']['DisableIS']) {
// this is slow with thousands of databases
$sql = 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA'
. ' WHERE SCHEMA_NAME = \'' . Util::sqlAddSlashes($db)
. ' WHERE SCHEMA_NAME = \'' . $GLOBALS['dbi']->escapeString($db)
. '\' LIMIT 1';
return $GLOBALS['dbi']->fetchValue($sql);
} else {

View File

@ -90,11 +90,11 @@ class Navigation
$sqlQuery = "INSERT INTO " . $navTable
. "(`username`, `item_name`, `item_type`, `db_name`, `table_name`)"
. " VALUES ("
. "'" . Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "',"
. "'" . Util::sqlAddSlashes($itemName) . "',"
. "'" . Util::sqlAddSlashes($itemType) . "',"
. "'" . Util::sqlAddSlashes($dbName) . "',"
. "'" . (! empty($tableName)? Util::sqlAddSlashes($tableName) : "" )
. "'" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "',"
. "'" . $GLOBALS['dbi']->escapeString($itemName) . "',"
. "'" . $GLOBALS['dbi']->escapeString($itemType) . "',"
. "'" . $GLOBALS['dbi']->escapeString($dbName) . "',"
. "'" . (! empty($tableName)? $GLOBALS['dbi']->escapeString($tableName) : "" )
. "')";
PMA_queryAsControlUser($sqlQuery, false);
}
@ -139,12 +139,12 @@ class Navigation
$sqlQuery = "DELETE FROM " . $navTable
. " WHERE"
. " `username`='"
. Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `item_name`='" . Util::sqlAddSlashes($itemName) . "'"
. " AND `item_type`='" . Util::sqlAddSlashes($itemType) . "'"
. " AND `db_name`='" . Util::sqlAddSlashes($dbName) . "'"
. $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `item_name`='" . $GLOBALS['dbi']->escapeString($itemName) . "'"
. " AND `item_type`='" . $GLOBALS['dbi']->escapeString($itemType) . "'"
. " AND `db_name`='" . $GLOBALS['dbi']->escapeString($dbName) . "'"
. (! empty($tableName)
? " AND `table_name`='" . Util::sqlAddSlashes($tableName) . "'"
? " AND `table_name`='" . $GLOBALS['dbi']->escapeString($tableName) . "'"
: ""
);
PMA_queryAsControlUser($sqlQuery, false);
@ -169,10 +169,10 @@ class Navigation
. "." . Util::backquote($GLOBALS['cfgRelation']['navigationhiding']);
$sqlQuery = "SELECT `item_name`, `item_type` FROM " . $navTable
. " WHERE `username`='"
. Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name`='" . Util::sqlAddSlashes($dbName) . "'"
. $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name`='" . $GLOBALS['dbi']->escapeString($dbName) . "'"
. " AND `table_name`='"
. (! empty($tableName) ? Util::sqlAddSlashes($tableName) : '') . "'";
. (! empty($tableName) ? $GLOBALS['dbi']->escapeString($tableName) : '') . "'";
$result = PMA_queryAsControlUser($sqlQuery, false);
$hidden = array();

View File

@ -108,14 +108,12 @@ class NavigationHeader
);
// prevent XSS, see PMASA-2013-9
// if link has protocol, allow only http and https
if (preg_match('/^[a-z]+:/i', $logoLink)
&& !preg_match('/^https?:/i', $logoLink)
) {
if (! PMA_checkLink($logoLink, true)) {
$logoLink = 'index.php';
}
switch ($GLOBALS['cfg']['NavigationLogoLinkWindow']) {
case 'new':
$linkAttriks = 'target="_blank"';
$linkAttriks = 'target="_blank" rel="noopener noreferrer"';
break;
case 'main':
// do not add our parameters for an external link
@ -126,7 +124,7 @@ class NavigationHeader
if (empty($host)) {
$logoLink .= PMA_URL_getCommon();
} else {
$linkAttriks = 'target="_blank"';
$linkAttriks = 'target="_blank" rel="noopener noreferrer"';
}
}

View File

@ -174,7 +174,7 @@ class NavigationTree
$query = "SELECT (COUNT(DB_first_level) DIV %d) * %d ";
$query .= "from ( ";
$query .= " SELECT distinct SUBSTRING_INDEX(SCHEMA_NAME, ";
$query .= " '" . Util::sqlAddSlashes($GLOBALS['cfg']['NavigationTreeDbSeparator']) . "', 1) ";
$query .= " '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['NavigationTreeDbSeparator']) . "', 1) ";
$query .= " DB_first_level ";
$query .= " FROM INFORMATION_SCHEMA.SCHEMATA ";
$query .= " WHERE `SCHEMA_NAME` < '%s' ";
@ -185,7 +185,7 @@ class NavigationTree
$query,
(int)$GLOBALS['cfg']['FirstLevelNavigationItems'],
(int)$GLOBALS['cfg']['FirstLevelNavigationItems'],
Util::sqlAddSlashes($GLOBALS['db'])
$GLOBALS['dbi']->escapeString($GLOBALS['db'])
)
);

View File

@ -434,7 +434,7 @@ class Node
$query .= "SELECT DB_first_level ";
$query .= "FROM ( ";
$query .= "SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "', 1) ";
$query .= "'" . $GLOBALS['dbi']->escapeString($dbSeparator) . "', 1) ";
$query .= "DB_first_level ";
$query .= "FROM INFORMATION_SCHEMA.SCHEMATA ";
$query .= $this->_getWhereClause('SCHEMA_NAME', $searchClause);
@ -444,9 +444,9 @@ class Node
$query .= ") t2 ";
$query .= $this->_getWhereClause('SCHEMA_NAME', $searchClause);
$query .= "AND 1 = LOCATE(CONCAT(DB_first_level, ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "'), ";
$query .= "'" . $GLOBALS['dbi']->escapeString($dbSeparator) . "'), ";
$query .= "CONCAT(SCHEMA_NAME, ";
$query .= "'" . Util::sqlAddSlashes($dbSeparator) . "')) ";
$query .= "'" . $GLOBALS['dbi']->escapeString($dbSeparator) . "')) ";
$query .= "ORDER BY SCHEMA_NAME ASC";
$retval = $GLOBALS['dbi']->fetchResult($query);
@ -480,7 +480,7 @@ class Node
$subClauses = array();
foreach ($prefixes as $prefix) {
$subClauses[] = " LOCATE('"
. Util::sqlAddSlashes($prefix) . $dbSeparator
. $GLOBALS['dbi']->escapeString($prefix) . $dbSeparator
. "', "
. "CONCAT(`Database`, '" . $dbSeparator . "')) = 1 ";
}
@ -685,7 +685,7 @@ class Node
{
if (!empty($searchClause)) {
$databases = array(
"%" . Util::sqlAddSlashes($searchClause, true) . "%",
"%" . $GLOBALS['dbi']->escapeString($searchClause, true) . "%",
);
} elseif (!empty($GLOBALS['cfg']['Server']['only_db'])) {
$databases = $GLOBALS['cfg']['Server']['only_db'];
@ -712,7 +712,7 @@ class Node
if (!empty($searchClause)) {
$whereClause .= "AND " . Util::backquote($columnName)
. " LIKE '%";
$whereClause .= Util::sqlAddSlashes(
$whereClause .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -721,7 +721,9 @@ class Node
if (!empty($GLOBALS['cfg']['Server']['hide_db'])) {
$whereClause .= "AND " . Util::backquote($columnName)
. " NOT REGEXP '" . $GLOBALS['cfg']['Server']['hide_db'] . "' ";
. " NOT REGEXP '"
. $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['hide_db'], true)
. "' ";
}
if (!empty($GLOBALS['cfg']['Server']['only_db'])) {
@ -735,7 +737,7 @@ class Node
foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
$subClauses[] = " " . Util::backquote($columnName)
. " LIKE '"
. $each_only_db . "' ";
. $GLOBALS['dbi']->escapeString($each_only_db, true) . "' ";
}
$whereClause .= implode("OR", $subClauses) . ") ";
}
@ -815,7 +817,7 @@ class Node
);
$sqlQuery = "SELECT `db_name`, COUNT(*) AS `count` FROM " . $navTable
. " WHERE `username`='"
. Util::sqlAddSlashes(
. $GLOBALS['dbi']->escapeString(
$GLOBALS['cfg']['Server']['user']
) . "'"
. " GROUP BY `db_name`";

View File

@ -115,7 +115,7 @@ class NodeDatabase extends Node
}
if (! $GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
$query .= "WHERE `TABLE_SCHEMA`='$db' ";
@ -199,7 +199,7 @@ class NodeDatabase extends Node
{
$db = $this->real_name;
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
$query .= "WHERE `ROUTINE_SCHEMA` "
@ -214,7 +214,7 @@ class NodeDatabase extends Node
}
$retval = (int)$GLOBALS['dbi']->fetchValue($query);
} else {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SHOW PROCEDURE STATUS WHERE `Db`='$db' ";
if (!empty($searchClause)) {
$query .= "AND " . $this->_getWhereClauseForSearch(
@ -245,7 +245,7 @@ class NodeDatabase extends Node
{
$db = $this->real_name;
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
$query .= "WHERE `ROUTINE_SCHEMA` "
@ -260,7 +260,7 @@ class NodeDatabase extends Node
}
$retval = (int)$GLOBALS['dbi']->fetchValue($query);
} else {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SHOW FUNCTION STATUS WHERE `Db`='$db' ";
if (!empty($searchClause)) {
$query .= "AND " . $this->_getWhereClauseForSearch(
@ -291,7 +291,7 @@ class NodeDatabase extends Node
{
$db = $this->real_name;
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$db = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
$query .= "WHERE `EVENT_SCHEMA` "
@ -339,10 +339,10 @@ class NodeDatabase extends Node
$query = '';
if ($singleItem) {
$query .= Util::backquote($columnName) . " = ";
$query .= "'" . Util::sqlAddSlashes($searchClause) . "'";
$query .= "'" . $GLOBALS['dbi']->escapeString($searchClause) . "'";
} else {
$query .= Util::backquote($columnName) . " LIKE ";
$query .= "'%" . Util::sqlAddSlashes($searchClause, true)
$query .= "'%" . $GLOBALS['dbi']->escapeString($searchClause, true)
. "%'";
}
@ -418,7 +418,7 @@ class NodeDatabase extends Node
$sqlQuery = "SELECT `item_name` FROM " . $navTable
. " WHERE `username`='" . $cfgRelation['user'] . "'"
. " AND `item_type`='" . $type
. "'" . " AND `db_name`='" . Util::sqlAddSlashes($db)
. "'" . " AND `db_name`='" . $GLOBALS['dbi']->escapeString($db)
. "'";
$result = PMA_queryAsControlUser($sqlQuery, false);
$hiddenItems = array();
@ -452,14 +452,14 @@ class NodeDatabase extends Node
$retval = array();
$db = $this->real_name;
if (! $GLOBALS['cfg']['Server']['DisableIS']) {
$escdDb = Util::sqlAddSlashes($db);
$escdDb = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT `TABLE_NAME` AS `name` ";
$query .= "FROM `INFORMATION_SCHEMA`.`TABLES` ";
$query .= "WHERE `TABLE_SCHEMA`='$escdDb' ";
$query .= "AND `TABLE_TYPE`" . $condition . "'BASE TABLE' ";
if (! empty($searchClause)) {
$query .= "AND `TABLE_NAME` LIKE '%";
$query .= Util::sqlAddSlashes(
$query .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -476,7 +476,7 @@ class NodeDatabase extends Node
$query .= "AND " . Util::backquote(
"Tables_in_" . $db
);
$query .= " LIKE '%" . Util::sqlAddSlashes(
$query .= " LIKE '%" . $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -542,7 +542,7 @@ class NodeDatabase extends Node
$retval = array();
$db = $this->real_name;
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$escdDb = Util::sqlAddSlashes($db);
$escdDb = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT `ROUTINE_NAME` AS `name` ";
$query .= "FROM `INFORMATION_SCHEMA`.`ROUTINES` ";
$query .= "WHERE `ROUTINE_SCHEMA` "
@ -550,7 +550,7 @@ class NodeDatabase extends Node
$query .= "AND `ROUTINE_TYPE`='" . $routineType . "' ";
if (!empty($searchClause)) {
$query .= "AND `ROUTINE_NAME` LIKE '%";
$query .= Util::sqlAddSlashes(
$query .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -560,11 +560,11 @@ class NodeDatabase extends Node
$query .= "LIMIT " . intval($pos) . ", $maxItems";
$retval = $GLOBALS['dbi']->fetchResult($query);
} else {
$escdDb = Util::sqlAddSlashes($db);
$escdDb = $GLOBALS['dbi']->escapeString($db);
$query = "SHOW " . $routineType . " STATUS WHERE `Db`='$escdDb' ";
if (!empty($searchClause)) {
$query .= "AND `Name` LIKE '%";
$query .= Util::sqlAddSlashes(
$query .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -629,14 +629,14 @@ class NodeDatabase extends Node
$retval = array();
$db = $this->real_name;
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$escdDb = Util::sqlAddSlashes($db);
$escdDb = $GLOBALS['dbi']->escapeString($db);
$query = "SELECT `EVENT_NAME` AS `name` ";
$query .= "FROM `INFORMATION_SCHEMA`.`EVENTS` ";
$query .= "WHERE `EVENT_SCHEMA` "
. Util::getCollateForIS() . "='$escdDb' ";
if (!empty($searchClause)) {
$query .= "AND `EVENT_NAME` LIKE '%";
$query .= Util::sqlAddSlashes(
$query .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);
@ -650,7 +650,7 @@ class NodeDatabase extends Node
$query = "SHOW EVENTS FROM $escdDb ";
if (!empty($searchClause)) {
$query .= "WHERE `Name` LIKE '%";
$query .= Util::sqlAddSlashes(
$query .= $GLOBALS['dbi']->escapeString(
$searchClause,
true
);

View File

@ -94,8 +94,8 @@ class NodeTable extends NodeDatabaseChild
switch ($type) {
case 'columns':
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$table = Util::sqlAddSlashes($table);
$db = $GLOBALS['dbi']->escapeString($db);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
$query .= "WHERE `TABLE_NAME`='$table' ";
@ -120,8 +120,8 @@ class NodeTable extends NodeDatabaseChild
break;
case 'triggers':
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$table = Util::sqlAddSlashes($table);
$db = $GLOBALS['dbi']->escapeString($db);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SELECT COUNT(*) ";
$query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
$query .= "WHERE `EVENT_OBJECT_SCHEMA` "
@ -131,7 +131,7 @@ class NodeTable extends NodeDatabaseChild
$retval = (int)$GLOBALS['dbi']->fetchValue($query);
} else {
$db = Util::backquote($db);
$table = Util::sqlAddSlashes($table);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
$retval = (int)$GLOBALS['dbi']->numRows(
$GLOBALS['dbi']->tryQuery($query)
@ -166,8 +166,8 @@ class NodeTable extends NodeDatabaseChild
switch ($type) {
case 'columns':
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$table = Util::sqlAddSlashes($table);
$db = $GLOBALS['dbi']->escapeString($db);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SELECT `COLUMN_NAME` AS `name` ";
$query .= "FROM `INFORMATION_SCHEMA`.`COLUMNS` ";
$query .= "WHERE `TABLE_NAME`='$table' ";
@ -221,8 +221,8 @@ class NodeTable extends NodeDatabaseChild
break;
case 'triggers':
if (!$GLOBALS['cfg']['Server']['DisableIS']) {
$db = Util::sqlAddSlashes($db);
$table = Util::sqlAddSlashes($table);
$db = $GLOBALS['dbi']->escapeString($db);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SELECT `TRIGGER_NAME` AS `name` ";
$query .= "FROM `INFORMATION_SCHEMA`.`TRIGGERS` ";
$query .= "WHERE `EVENT_OBJECT_SCHEMA` "
@ -236,7 +236,7 @@ class NodeTable extends NodeDatabaseChild
}
$db = Util::backquote($db);
$table = Util::sqlAddSlashes($table);
$table = $GLOBALS['dbi']->escapeString($table);
$query = "SHOW TRIGGERS FROM $db WHERE `Table` = '$table'";
$handle = $GLOBALS['dbi']->tryQuery($query);
if ($handle === false) {

View File

@ -515,7 +515,7 @@ function PMA_runEventDefinitionsForDb($db)
{
$event_names = $GLOBALS['dbi']->fetchResult(
'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \''
. PMA\libraries\Util::sqlAddSlashes($db, true) . '\';'
. $GLOBALS['dbi']->escapeString($db) . '\';'
);
if ($event_names) {
foreach ($event_names as $event_name) {
@ -585,26 +585,26 @@ function PMA_AdjustPrivileges_moveDB($oldDb, $newname)
// For Db specific privileges
$query_db_specific = 'UPDATE ' . Util::backquote('db')
. 'SET Db = \'' . Util::sqlAddSlashes($newname)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\';';
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newname)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\';';
$GLOBALS['dbi']->query($query_db_specific);
// For table specific privileges
$query_table_specific = 'UPDATE ' . Util::backquote('tables_priv')
. 'SET Db = \'' . Util::sqlAddSlashes($newname)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\';';
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newname)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\';';
$GLOBALS['dbi']->query($query_table_specific);
// For column specific privileges
$query_col_specific = 'UPDATE ' . Util::backquote('columns_priv')
. 'SET Db = \'' . Util::sqlAddSlashes($newname)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\';';
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newname)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\';';
$GLOBALS['dbi']->query($query_col_specific);
// For procedures specific privileges
$query_proc_specific = 'UPDATE ' . Util::backquote('procs_priv')
. 'SET Db = \'' . Util::sqlAddSlashes($newname)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\';';
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newname)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\';';
$GLOBALS['dbi']->query($query_proc_specific);
// Finally FLUSH the new privileges
@ -1588,7 +1588,11 @@ function PMA_getHtmlForPartitionMaintenance($partition_names, $url_params)
$GLOBALS['db'], $GLOBALS['table']
);
// add COALESCE or DROP option to choices array depeding on Partition method
if ($partition_method == 'RANGE' || $partition_method == 'LIST') {
if ($partition_method == 'RANGE'
|| $partition_method == 'RANGE COLUMNS'
|| $partition_method == 'LIST'
|| $partition_method == 'LIST COLUMNS'
) {
$choices['DROP'] = __('Drop');
} else {
$choices['COALESCE'] = __('Coalesce');
@ -1767,7 +1771,7 @@ function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys,
&& urldecode($_REQUEST['prev_comment']) !== $_REQUEST['comment']
) {
$table_alters[] = 'COMMENT = \''
. PMA\libraries\Util::sqlAddSlashes($_REQUEST['comment']) . '\'';
. $GLOBALS['dbi']->escapeString($_REQUEST['comment']) . '\'';
}
if (! empty($newTblStorageEngine)
@ -1826,7 +1830,7 @@ function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys,
|| $_REQUEST['new_auto_increment'] !== $auto_increment)
) {
$table_alters[] = 'auto_increment = '
. PMA\libraries\Util::sqlAddSlashes($_REQUEST['new_auto_increment']);
. $GLOBALS['dbi']->escapeString($_REQUEST['new_auto_increment']);
}
if (! empty($_REQUEST['new_row_format'])) {
@ -1837,7 +1841,7 @@ function PMA_getTableAltersArray($is_myisam_or_aria, $is_isam, $pack_keys,
|| $newRowFormatLower !== mb_strtolower($row_format))
) {
$table_alters[] = 'ROW_FORMAT = '
. PMA\libraries\Util::sqlAddSlashes($newRowFormat);
. $GLOBALS['dbi']->escapeString($newRowFormat);
}
}
@ -1941,15 +1945,15 @@ function PMA_AdjustPrivileges_renameOrMoveTable($oldDb, $oldTable, $newDb, $newT
// For table specific privileges
$query_table_specific = 'UPDATE ' . Util::backquote('tables_priv')
. 'SET Db = \'' . Util::sqlAddSlashes($newDb) . '\', Table_name = \'' . Util::sqlAddSlashes($newTable)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\' AND Table_name = \'' . Util::sqlAddSlashes($oldTable)
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newDb) . '\', Table_name = \'' . $GLOBALS['dbi']->escapeString($newTable)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\' AND Table_name = \'' . $GLOBALS['dbi']->escapeString($oldTable)
. '\';';
$GLOBALS['dbi']->query($query_table_specific);
// For column specific privileges
$query_col_specific = 'UPDATE ' . Util::backquote('columns_priv')
. 'SET Db = \'' . Util::sqlAddSlashes($newDb) . '\', Table_name = \'' . Util::sqlAddSlashes($newTable)
. '\' where Db = \'' . Util::sqlAddSlashes($oldDb) . '\' AND Table_name = \'' . Util::sqlAddSlashes($oldTable)
. 'SET Db = \'' . $GLOBALS['dbi']->escapeString($newDb) . '\', Table_name = \'' . $GLOBALS['dbi']->escapeString($newTable)
. '\' where Db = \'' . $GLOBALS['dbi']->escapeString($oldDb) . '\' AND Table_name = \'' . $GLOBALS['dbi']->escapeString($oldTable)
. '\';';
$GLOBALS['dbi']->query($query_col_specific);

View File

@ -62,7 +62,6 @@ function PMA_getPlugins($plugin_type, $plugins_dir, $plugin_param)
/* Scan for plugins */
$plugin_list = array();
if (!($handle = @opendir($plugins_dir))) {
ksort($plugin_list);
return $plugin_list;
}

View File

@ -114,7 +114,7 @@ abstract class AuthenticationPlugin
} else {
$dbi_error = $GLOBALS['dbi']->getError();
if (!empty($dbi_error)) {
return PMA_sanitize($dbi_error);
return htmlspecialchars($dbi_error);
} elseif (isset($GLOBALS['errno'])) {
return '#' . $GLOBALS['errno'] . ' '
. __('Cannot log in to the MySQL server');
@ -134,4 +134,26 @@ abstract class AuthenticationPlugin
public function handlePasswordChange($password)
{
}
/**
* Store session access time in session.
*
* Tries to workaround PHP 5 session garbage collection which
* looks at the session file's last modified time
*
* @return void
*/
public function setSessionAccessTime()
{
if (isset($_REQUEST['access_time'])) {
// Ensure access_time is in range <0, LoginCookieValidity + 1>
// to avoid excessive extension of validity.
//
// Negative values can cause session expiry extension
// Too big values can cause overflow and lead to same
$_SESSION['last_access_time'] = time() - min(max(0, intval($_REQUEST['access_time'])), $GLOBALS['cfg']['LoginCookieValidity'] + 1);
} else {
$_SESSION['last_access_time'] = time();
}
}
}

View File

@ -61,13 +61,7 @@ class AuthenticationConfig extends AuthenticationPlugin
*/
public function authSetUser()
{
// try to workaround PHP 5 session garbage collection which
// looks at the session file's last modified time
if (isset($_REQUEST['access_time'])) {
$_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
} else {
$_SESSION['last_access_time'] = time();
}
$this->setSessionAccessTime();
return true;
}

View File

@ -93,7 +93,7 @@ class AuthenticationCookie extends AuthenticationPlugin
<div class="container">
<a href="';
echo PMA_linkURL('https://www.phpmyadmin.net/');
echo '" target="_blank" class="logo">';
echo '" target="_blank" rel="noopener noreferrer" class="logo">';
$logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
if (@file_exists($logo_image)) {
echo '<img src="' , $logo_image
@ -301,7 +301,7 @@ class AuthenticationCookie extends AuthenticationPlugin
}
// The user just logged in
$GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
$GLOBALS['PHP_AUTH_USER'] = PMA_sanitizeMySQLUser($_REQUEST['pma_username']);
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password'])
? ''
: $_REQUEST['pma_password'];
@ -408,14 +408,14 @@ class AuthenticationCookie extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
if (! hash_equals($cfg['Server']['user'], $GLOBALS['PHP_AUTH_USER'])) {
foreach ($cfg['Servers'] as $idx => $current) {
if ($current['host'] == $cfg['Server']['host']
&& $current['port'] == $cfg['Server']['port']
&& $current['socket'] == $cfg['Server']['socket']
&& $current['ssl'] == $cfg['Server']['ssl']
&& $current['connect_type'] == $cfg['Server']['connect_type']
&& $current['user'] == $GLOBALS['PHP_AUTH_USER']
&& hash_equals($current['user'], $GLOBALS['PHP_AUTH_USER'])
) {
$GLOBALS['server'] = $idx;
$cfg['Server'] = $current;
@ -450,11 +450,7 @@ class AuthenticationCookie extends AuthenticationPlugin
// Avoid showing the password in phpinfo()'s output
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
if (isset($_REQUEST['access_time'])) {
$_SESSION['last_access_time'] = time() - $_REQUEST['access_time'];
} else {
$_SESSION['last_access_time'] = time();
}
$this->setSessionAccessTime();
}
/**

View File

@ -128,10 +128,8 @@ class AuthenticationHttp extends AuthenticationPlugin
} elseif (PMA_getenv('AUTH_USER')) {
// WebSite Professional
$PHP_AUTH_USER = PMA_getenv('AUTH_USER');
} elseif (PMA_getenv('HTTP_AUTHORIZATION')
&& false === strpos(PMA_getenv('HTTP_AUTHORIZATION'), '<')
) {
// IIS, might be encoded, see below; also prevent XSS
} elseif (PMA_getenv('HTTP_AUTHORIZATION')) {
// IIS, might be encoded, see below
$PHP_AUTH_USER = PMA_getenv('HTTP_AUTHORIZATION');
} elseif (PMA_getenv('Authorization')) {
// FastCGI, might be encoded, see below
@ -167,10 +165,13 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($usr_pass);
}
// sanitize username
$PHP_AUTH_USER = PMA_sanitizeMySQLUser($PHP_AUTH_USER);
// User logged out -> ensure the new username is not the same
$old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
if (!empty($old_usr)
&& (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
if (! empty($old_usr)
&& (isset($PHP_AUTH_USER) && hash_equals($old_usr, $PHP_AUTH_USER))
) {
$PHP_AUTH_USER = '';
// -> delete user's choices that were stored in session
@ -204,12 +205,12 @@ class AuthenticationHttp extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
if (! hash_equals($cfg['Server']['user'], $PHP_AUTH_USER)) {
$servers_cnt = count($cfg['Servers']);
for ($i = 1; $i <= $servers_cnt; $i++) {
if (isset($cfg['Servers'][$i])
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
&& $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
&& hash_equals($cfg['Servers'][$i]['user'], $PHP_AUTH_USER))
) {
$server = $i;
$cfg['Server'] = $cfg['Servers'][$i];
@ -225,9 +226,7 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
// try to workaround PHP 5 session garbage collection which
// looks at the session file's last modified time
$_SESSION['last_access_time'] = time();
$this->setSessionAccessTime();
return true;
}

View File

@ -236,7 +236,7 @@ class ExportSql extends ExportPlugin
if ($plugin_param['export_type'] == 'server') {
$leaf = new BoolPropertyItem(
"drop_database",
sprintf(__('Add %s statement'), '<code>DROP DATABASE</code>')
sprintf(__('Add %s statement'), '<code>DROP DATABASE IF EXISTS</code>')
);
$subgroup->addProperty($leaf);
}
@ -796,7 +796,7 @@ class ExportSql extends ExportPlugin
}
if (isset($GLOBALS['sql_drop_database'])) {
if (!PMA_exportOutputHandler(
'DROP DATABASE '
'DROP DATABASE IF EXISTS '
. Util::backquoteCompat(
$db_alias,
$compat,
@ -949,7 +949,7 @@ class ExportSql extends ExportPlugin
$event_names = $GLOBALS['dbi']->fetchResult(
"SELECT EVENT_NAME FROM information_schema.EVENTS WHERE"
. " EVENT_SCHEMA= '" . Util::sqlAddSlashes($db, true)
. " EVENT_SCHEMA= '" . $GLOBALS['dbi']->escapeString($db)
. "';"
);
@ -1102,7 +1102,7 @@ class ExportSql extends ExportPlugin
. Util::backquote($cfgRelation['db'])
. "." . Util::backquote($cfgRelation[$type])
. " WHERE " . Util::backquote($dbNameColumn)
. " = '" . Util::sqlAddSlashes($db) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($db) . "'";
$result = $GLOBALS['dbi']->fetchResult(
$sql_query,
@ -1120,7 +1120,7 @@ class ExportSql extends ExportPlugin
. " WHERE " . Util::backquote(
$dbNameColumn
)
. " = '" . Util::sqlAddSlashes($db) . "'"
. " = '" . $GLOBALS['dbi']->escapeString($db) . "'"
. " AND `page_nr` = '" . intval($page) . "'";
if (!$this->exportData(
@ -1186,10 +1186,10 @@ class ExportSql extends ExportPlugin
$sql_query .= Util::backquote($cfgRelation['db'])
. '.' . Util::backquote($cfgRelation[$type])
. " WHERE " . Util::backquote($dbNameColumn)
. " = '" . Util::sqlAddSlashes($db) . "'";
. " = '" . $GLOBALS['dbi']->escapeString($db) . "'";
if (isset($table)) {
$sql_query .= " AND `table_name` = '"
. Util::sqlAddSlashes($table) . "'";
. $GLOBALS['dbi']->escapeString($table) . "'";
}
if (!$this->exportData(
@ -1309,7 +1309,7 @@ class ExportSql extends ExportPlugin
}
if (isset($column['Default'])) {
$create_query .= " DEFAULT '"
. Util::sqlAddSlashes($column['Default']) . "'";
. $GLOBALS['dbi']->escapeString($column['Default']) . "'";
} else {
if ($column['Null'] == 'YES') {
$create_query .= " DEFAULT NULL";
@ -1317,7 +1317,7 @@ class ExportSql extends ExportPlugin
}
if (!empty($column['Comment'])) {
$create_query .= " COMMENT '"
. Util::sqlAddSlashes($column['Comment']) . "'";
. $GLOBALS['dbi']->escapeString($column['Comment']) . "'";
}
$firstCol = false;
}
@ -1389,7 +1389,7 @@ class ExportSql extends ExportPlugin
// with $GLOBALS['dbi']->numRows() in mysqli
$result = $GLOBALS['dbi']->query(
'SHOW TABLE STATUS FROM ' . Util::backquote($db)
. ' WHERE Name = \'' . Util::sqlAddSlashes($table) . '\'',
. ' WHERE Name = \'' . $GLOBALS['dbi']->escapeString($table) . '\'',
null,
DatabaseInterface::QUERY_STORE
);
@ -2397,7 +2397,7 @@ class ExportSql extends ExportPlugin
}
} elseif ($fields_meta[$j]->type == 'bit') {
// detection of 'bit' works only on mysqli extension
$values[] = "b'" . Util::sqlAddSlashes(
$values[] = "b'" . $GLOBALS['dbi']->escapeString(
Util::printableBitValue(
$row[$j],
$fields_meta[$j]->length
@ -2411,10 +2411,12 @@ class ExportSql extends ExportPlugin
} else {
// something else -> treat as a string
$values[] = '\''
. str_replace(
$search,
$replace,
Util::sqlAddSlashes($row[$j])
. $GLOBALS['dbi']->escapeString(
str_replace(
$search,
$replace,
$row[$j]
)
)
. '\'';
} // end if

View File

@ -253,7 +253,7 @@ class ExportXml extends ExportPlugin
$result = $GLOBALS['dbi']->fetchResult(
'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`'
. ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`'
. ' = \'' . Util::sqlAddSlashes($db) . '\' LIMIT 1'
. ' = \'' . $GLOBALS['dbi']->escapeString($db) . '\' LIMIT 1'
);
$db_collation = $result[0]['DEFAULT_COLLATION_NAME'];
$db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME'];
@ -349,7 +349,7 @@ class ExportXml extends ExportPlugin
// Export events
$events = $GLOBALS['dbi']->fetchResult(
"SELECT EVENT_NAME FROM information_schema.EVENTS "
. "WHERE EVENT_SCHEMA='" . Util::sqlAddslashes($db)
. "WHERE EVENT_SCHEMA='" . $GLOBALS['dbi']->escapeString($db)
. "'"
);
$head .= $this->_exportDefinitions(

View File

@ -548,7 +548,7 @@ class ImportCsv extends AbstractImportCsv
$sql .= 'NULL';
} else {
$sql .= '\''
. PMA\libraries\Util::sqlAddSlashes($val)
. $GLOBALS['dbi']->escapeString($val)
. '\'';
}

View File

@ -117,7 +117,7 @@ class ImportLdi extends AbstractImportCsv
if (isset($ldi_local_option)) {
$sql .= ' LOCAL';
}
$sql .= ' INFILE \'' . PMA\libraries\Util::sqlAddSlashes($import_file)
$sql .= ' INFILE \'' . $GLOBALS['dbi']->escapeString($import_file)
. '\'';
if (isset($ldi_replace)) {
$sql .= ' REPLACE';
@ -131,11 +131,11 @@ class ImportLdi extends AbstractImportCsv
}
if (strlen($ldi_enclosed) > 0) {
$sql .= ' ENCLOSED BY \''
. PMA\libraries\Util::sqlAddSlashes($ldi_enclosed) . '\'';
. $GLOBALS['dbi']->escapeString($ldi_enclosed) . '\'';
}
if (strlen($ldi_escaped) > 0) {
$sql .= ' ESCAPED BY \''
. PMA\libraries\Util::sqlAddSlashes($ldi_escaped) . '\'';
. $GLOBALS['dbi']->escapeString($ldi_escaped) . '\'';
}
if (strlen($ldi_new_line) > 0) {
if ($ldi_new_line == 'auto') {

View File

@ -240,7 +240,7 @@ class Pdf extends PDF_lib
$test_query = 'SELECT * FROM '
. Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
. Util::backquote($GLOBALS['cfgRelation']['pdf_pages'])
. ' WHERE db_name = \'' . Util::sqlAddSlashes($this->_db)
. ' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($this->_db)
. '\' AND page_nr = \'' . $this->_pageNumber . '\'';
$test_rs = PMA_queryAsControlUser($test_query);
$pages = @$GLOBALS['dbi']->fetchAssoc($test_rs);

View File

@ -47,9 +47,8 @@ abstract class TextImageLinkTransformationsPlugin extends TransformationsPlugin
public function applyTransformation($buffer, $options = array(), $meta = '')
{
$url = (isset($options[0]) ? $options[0] : '') . $buffer;
$parsed = parse_url($url);
/* Do not allow javascript links */
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
if (! PMA_checkLink($url, true, true)) {
return htmlspecialchars($url);
}
return '<a href="' . htmlspecialchars($url)

View File

@ -47,9 +47,8 @@ abstract class TextLinkTransformationsPlugin extends TransformationsPlugin
public function applyTransformation($buffer, $options = array(), $meta = '')
{
$url = (isset($options[0]) ? $options[0] : '') . ((isset($options[2]) && $options[2]) ? '' : $buffer);
$parsed = parse_url($url);
/* Do not allow javascript links */
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
if (! PMA_checkLink($url, true, true)) {
return htmlspecialchars($url);
}
return '<a href="'

View File

@ -42,10 +42,10 @@ function PMA_getTablesInfo()
$GLOBALS['PMD']['TABLE_NAME_SMALL'][$i] = $one_table['TABLE_NAME'];
$GLOBALS['PMD_URL']['TABLE_NAME'][$i]
= urlencode($GLOBALS['db'] . "." . $one_table['TABLE_NAME']);
$GLOBALS['PMD_URL']['OWNER'][$i] = urlencode($GLOBALS['db']);
= $GLOBALS['db'] . "." . $one_table['TABLE_NAME'];
$GLOBALS['PMD_URL']['OWNER'][$i] = $GLOBALS['db'];
$GLOBALS['PMD_URL']['TABLE_NAME_SMALL'][$i]
= urlencode($one_table['TABLE_NAME']);
= $one_table['TABLE_NAME'];
$GLOBALS['PMD_OUT']['TABLE_NAME'][$i] = htmlspecialchars(
$GLOBALS['db'] . "." . $one_table['TABLE_NAME'], ENT_QUOTES
@ -63,7 +63,7 @@ function PMA_getTablesInfo()
$DF = PMA_getDisplayField($GLOBALS['db'], $one_table['TABLE_NAME']);
if ($DF != '') {
$retval[$GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i]] = urlencode($DF);
$retval[$GLOBALS['PMD_URL']["TABLE_NAME_SMALL"][$i]] = $DF;
}
$i++;
@ -123,8 +123,7 @@ function PMA_getScriptContr()
);
while ($val = @$GLOBALS['dbi']->fetchRow($alltab_rs)) {
$row = PMA_getForeigners($GLOBALS['db'], $val[0], '', 'internal');
//echo "<br> internal ".$GLOBALS['db']." - ".$val[0]." - ";
//print_r($row);
if ($row !== false) {
foreach ($row as $field => $value) {
$con['C_NAME'][$i] = '';
@ -138,12 +137,11 @@ function PMA_getScriptContr()
}
}
$row = PMA_getForeigners($GLOBALS['db'], $val[0], '', 'foreign');
//echo "<br> INNO ";
//print_r($row);
if ($row !== false) {
foreach ($row['foreign_keys_data'] as $one_key) {
foreach ($one_key['index_list'] as $index => $one_field) {
$con['C_NAME'][$i] = '';
$con['C_NAME'][$i] = $one_key['constraint'];
$con['DTN'][$i] = urlencode($GLOBALS['db'] . "." . $val[0]);
$con['DCN'][$i] = urlencode($one_field);
$con['STN'][$i] = urlencode(
@ -352,8 +350,8 @@ function PMA_getDefaultPage($db)
$query = "SELECT `page_nr`"
. " FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. " WHERE `db_name` = '" . PMA\libraries\Util::sqlAddSlashes($db) . "'"
. " AND `page_descr` = '" . PMA\libraries\Util::sqlAddSlashes($db) . "'";
. " WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($db) . "'"
. " AND `page_descr` = '" . $GLOBALS['dbi']->escapeString($db) . "'";
$default_page_no = $GLOBALS['dbi']->fetchResult(
$query,
@ -393,7 +391,7 @@ function PMA_getLoadingPage($db)
$query = "SELECT MIN(`page_nr`)"
. " FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. " WHERE `db_name` = '" . PMA\libraries\Util::sqlAddSlashes($db) . "'";
. " WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($db) . "'";
$min_page_no = $GLOBALS['dbi']->fetchResult(
$query,
@ -450,9 +448,9 @@ function PMA_saveTablePositions($pg)
. "." . PMA\libraries\Util::backquote(
$GLOBALS['cfgRelation']['table_coords']
)
. " WHERE `db_name` = '" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['db'])
. " WHERE `db_name` = '" . $GLOBALS['dbi']->escapeString($_REQUEST['db'])
. "'"
. " AND `pdf_page_number` = '" . PMA\libraries\Util::sqlAddSlashes($pg)
. " AND `pdf_page_number` = '" . $GLOBALS['dbi']->escapeString($pg)
. "'";
$res = PMA_queryAsControlUser(
@ -476,11 +474,11 @@ function PMA_saveTablePositions($pg)
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['table_coords'])
. " (`db_name`, `table_name`, `pdf_page_number`, `x`, `y`)"
. " VALUES ("
. "'" . PMA\libraries\Util::sqlAddSlashes($DB) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($TAB) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($pg) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['t_x'][$key]) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($_REQUEST['t_y'][$key]) . "')";
. "'" . $GLOBALS['dbi']->escapeString($DB) . "', "
. "'" . $GLOBALS['dbi']->escapeString($TAB) . "', "
. "'" . $GLOBALS['dbi']->escapeString($pg) . "', "
. "'" . $GLOBALS['dbi']->escapeString($_REQUEST['t_x'][$key]) . "', "
. "'" . $GLOBALS['dbi']->escapeString($_REQUEST['t_y'][$key]) . "')";
$res = PMA_queryAsControlUser(
$query, true, PMA\libraries\DatabaseInterface::QUERY_STORE
@ -623,12 +621,12 @@ function PMA_addNewRelation($db, $T1, $F1, $T2, $F2, $on_delete, $on_update)
. "(master_db, master_table, master_field, "
. "foreign_db, foreign_table, foreign_field)"
. " values("
. "'" . PMA\libraries\Util::sqlAddSlashes($db) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($T2) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($F2) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($db) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($T1) . "', "
. "'" . PMA\libraries\Util::sqlAddSlashes($F1) . "')";
. "'" . $GLOBALS['dbi']->escapeString($db) . "', "
. "'" . $GLOBALS['dbi']->escapeString($T2) . "', "
. "'" . $GLOBALS['dbi']->escapeString($F2) . "', "
. "'" . $GLOBALS['dbi']->escapeString($db) . "', "
. "'" . $GLOBALS['dbi']->escapeString($T1) . "', "
. "'" . $GLOBALS['dbi']->escapeString($F1) . "')";
if (PMA_queryAsControlUser($q, false, PMA\libraries\DatabaseInterface::QUERY_STORE)
) {
@ -692,12 +690,12 @@ function PMA_removeRelation($T1, $F1, $T2, $F2)
$delete_query = "DELETE FROM "
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['db']) . "."
. $GLOBALS['cfgRelation']['relation'] . " WHERE "
. "master_db = '" . PMA\libraries\Util::sqlAddSlashes($DB2) . "'"
. " AND master_table = '" . PMA\libraries\Util::sqlAddSlashes($T2) . "'"
. " AND master_field = '" . PMA\libraries\Util::sqlAddSlashes($F2) . "'"
. " AND foreign_db = '" . PMA\libraries\Util::sqlAddSlashes($DB1) . "'"
. " AND foreign_table = '" . PMA\libraries\Util::sqlAddSlashes($T1) . "'"
. " AND foreign_field = '" . PMA\libraries\Util::sqlAddSlashes($F1) . "'";
. "master_db = '" . $GLOBALS['dbi']->escapeString($DB2) . "'"
. " AND master_table = '" . $GLOBALS['dbi']->escapeString($T2) . "'"
. " AND master_field = '" . $GLOBALS['dbi']->escapeString($F2) . "'"
. " AND foreign_db = '" . $GLOBALS['dbi']->escapeString($DB1) . "'"
. " AND foreign_table = '" . $GLOBALS['dbi']->escapeString($T1) . "'"
. " AND foreign_field = '" . $GLOBALS['dbi']->escapeString($F1) . "'";
$result = PMA_queryAsControlUser(
$delete_query,
@ -740,7 +738,7 @@ function PMA_saveDesignerSetting($index, $value)
. " FROM " . PMA\libraries\Util::backquote($cfgDesigner['db'])
. "." . PMA\libraries\Util::backquote($cfgDesigner['table'])
. " WHERE username = '"
. PMA\libraries\Util::sqlAddSlashes($cfgDesigner['user']) . "';";
. $GLOBALS['dbi']->escapeString($cfgDesigner['user']) . "';";
$orig_data = $GLOBALS['dbi']->fetchSingleRow(
$orig_data_query, 'ASSOC', $GLOBALS['controllink']
@ -756,7 +754,7 @@ function PMA_saveDesignerSetting($index, $value)
. "." . PMA\libraries\Util::backquote($cfgDesigner['table'])
. " SET settings_data = '" . $orig_data . "'"
. " WHERE username = '"
. PMA\libraries\Util::sqlAddSlashes($cfgDesigner['user']) . "';";
. $GLOBALS['dbi']->escapeString($cfgDesigner['user']) . "';";
$success = PMA_queryAsControlUser($save_query);
} else {

View File

@ -756,12 +756,12 @@ function PMA_getForeigners($db, $table, $column = '', $source = 'both')
`foreign_field`
FROM ' . PMA\libraries\Util::backquote($cfgRelation['db'])
. '.' . PMA\libraries\Util::backquote($cfgRelation['relation']) . '
WHERE `master_db` = \'' . PMA\libraries\Util::sqlAddSlashes($db) . '\'
AND `master_table` = \'' . PMA\libraries\Util::sqlAddSlashes($table)
WHERE `master_db` = \'' . $GLOBALS['dbi']->escapeString($db) . '\'
AND `master_table` = \'' . $GLOBALS['dbi']->escapeString($table)
. '\' ';
if (mb_strlen($column)) {
$rel_query .= ' AND `master_field` = '
. '\'' . PMA\libraries\Util::sqlAddSlashes($column) . '\'';
. '\'' . $GLOBALS['dbi']->escapeString($column) . '\'';
}
$foreign = $GLOBALS['dbi']->fetchResult(
$rel_query, 'master_field', null, $GLOBALS['controllink']
@ -836,8 +836,8 @@ function PMA_getDisplayField($db, $table)
SELECT `display_field`
FROM ' . PMA\libraries\Util::backquote($cfgRelation['db'])
. '.' . PMA\libraries\Util::backquote($cfgRelation['table_info']) . '
WHERE `db_name` = \'' . PMA\libraries\Util::sqlAddSlashes($db) . '\'
AND `table_name` = \'' . PMA\libraries\Util::sqlAddSlashes($table)
WHERE `db_name` = \'' . $GLOBALS['dbi']->escapeString($db) . '\'
AND `table_name` = \'' . $GLOBALS['dbi']->escapeString($table)
. '\'';
$row = $GLOBALS['dbi']->fetchSingleRow(
@ -919,7 +919,7 @@ function PMA_getDbComment($db)
FROM " . PMA\libraries\Util::backquote($cfgRelation['db'])
. "." . PMA\libraries\Util::backquote($cfgRelation['column_info'])
. "
WHERE db_name = '" . PMA\libraries\Util::sqlAddSlashes($db) . "'
WHERE db_name = '" . $GLOBALS['dbi']->escapeString($db) . "'
AND table_name = ''
AND column_name = '(db_comment)'";
$com_rs = PMA_queryAsControlUser(
@ -995,17 +995,17 @@ function PMA_setDbComment($db, $comment = '')
. PMA\libraries\Util::backquote($cfgRelation['column_info'])
. ' (`db_name`, `table_name`, `column_name`, `comment`)'
. ' VALUES (\''
. PMA\libraries\Util::sqlAddSlashes($db)
. $GLOBALS['dbi']->escapeString($db)
. "', '', '(db_comment)', '"
. PMA\libraries\Util::sqlAddSlashes($comment)
. $GLOBALS['dbi']->escapeString($comment)
. "') "
. ' ON DUPLICATE KEY UPDATE '
. "`comment` = '" . PMA\libraries\Util::sqlAddSlashes($comment) . "'";
. "`comment` = '" . $GLOBALS['dbi']->escapeString($comment) . "'";
} else {
$upd_query = 'DELETE FROM '
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['column_info'])
. ' WHERE `db_name` = \'' . PMA\libraries\Util::sqlAddSlashes($db)
. ' WHERE `db_name` = \'' . $GLOBALS['dbi']->escapeString($db)
. '\'
AND `table_name` = \'\'
AND `column_name` = \'(db_comment)\'';
@ -1071,11 +1071,11 @@ function PMA_setHistory($db, $table, $username, $sqlquery)
`timevalue`,
`sqlquery`)
VALUES
(\'' . PMA\libraries\Util::sqlAddSlashes($username) . '\',
\'' . PMA\libraries\Util::sqlAddSlashes($db) . '\',
\'' . PMA\libraries\Util::sqlAddSlashes($table) . '\',
(\'' . $GLOBALS['dbi']->escapeString($username) . '\',
\'' . $GLOBALS['dbi']->escapeString($db) . '\',
\'' . $GLOBALS['dbi']->escapeString($table) . '\',
NOW(),
\'' . PMA\libraries\Util::sqlAddSlashes($sqlquery) . '\')'
\'' . $GLOBALS['dbi']->escapeString($sqlquery) . '\')'
);
PMA_purgeHistory($username);
@ -1117,7 +1117,7 @@ function PMA_getHistory($username)
`timevalue`
FROM ' . PMA\libraries\Util::backquote($cfgRelation['db'])
. '.' . PMA\libraries\Util::backquote($cfgRelation['history']) . '
WHERE `username` = \'' . PMA\libraries\Util::sqlAddSlashes($username) . '\'
WHERE `username` = \'' . $GLOBALS['dbi']->escapeString($username) . '\'
ORDER BY `id` DESC';
return $GLOBALS['dbi']->fetchResult(
@ -1152,7 +1152,7 @@ function PMA_purgeHistory($username)
SELECT `timevalue`
FROM ' . PMA\libraries\Util::backquote($cfgRelation['db'])
. '.' . PMA\libraries\Util::backquote($cfgRelation['history']) . '
WHERE `username` = \'' . PMA\libraries\Util::sqlAddSlashes($username) . '\'
WHERE `username` = \'' . $GLOBALS['dbi']->escapeString($username) . '\'
ORDER BY `timevalue` DESC
LIMIT ' . $GLOBALS['cfg']['QueryHistoryMax'] . ', 1';
@ -1163,7 +1163,7 @@ function PMA_purgeHistory($username)
'DELETE FROM '
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['history']) . '
WHERE `username` = \'' . PMA\libraries\Util::sqlAddSlashes($username)
WHERE `username` = \'' . $GLOBALS['dbi']->escapeString($username)
. '\'
AND `timevalue` <= \'' . $max_time . '\''
);
@ -1330,13 +1330,17 @@ function PMA_foreignDropdown($disp_row, $foreign_field, $foreign_display, $data,
* @param bool $override_total whether to override the total
* @param string $foreign_filter a possible filter
* @param string $foreign_limit a possible LIMIT clause
* @param bool $get_total optional, whether to get total num of rows
* in $foreignData['the_total;]
* (has an effect of performance)
*
* @return array data about the foreign keys
*
* @access public
*/
function PMA_getForeignData(
$foreigners, $field, $override_total, $foreign_filter, $foreign_limit
$foreigners, $field, $override_total,
$foreign_filter, $foreign_limit, $get_total=false
) {
// we always show the foreign field in the drop-down; if a display
// field is defined, we show it besides the foreign field
@ -1362,11 +1366,13 @@ function PMA_getForeignData(
// We could also do the SELECT anyway, with a LIMIT, and ensure that
// the current value of the field is one of the choices.
$the_total = $GLOBALS['dbi']->getTable($foreign_db, $foreign_table)
->countRecords(true);
// Check if table has more rows than specified by
// $GLOBALS['cfg']['ForeignKeyMaxLimit']
$moreThanLimit = $GLOBALS['dbi']->getTable($foreign_db, $foreign_table)
->checkIfMinRecordsExist($GLOBALS['cfg']['ForeignKeyMaxLimit']);
if ($override_total == true
|| $the_total < $GLOBALS['cfg']['ForeignKeyMaxLimit']
|| !$moreThanLimit
) {
// foreign_display can be false if no display field defined:
$foreign_display = PMA_getDisplayField($foreign_db, $foreign_table);
@ -1381,7 +1387,7 @@ function PMA_getForeignData(
. '.' . PMA\libraries\Util::backquote($foreign_table);
$f_query_filter = empty($foreign_filter) ? '' : ' WHERE '
. PMA\libraries\Util::backquote($foreign_field)
. ' LIKE "%' . PMA\libraries\Util::sqlAddSlashes(
. ' LIKE "%' . $GLOBALS['dbi']->escapeString(
$foreign_filter,
true
) . '%"'
@ -1389,7 +1395,7 @@ function PMA_getForeignData(
($foreign_display == false)
? ''
: ' OR ' . PMA\libraries\Util::backquote($foreign_display)
. ' LIKE "%' . PMA\libraries\Util::sqlAddSlashes(
. ' LIKE "%' . $GLOBALS['dbi']->escapeString(
$foreign_filter,
true
)
@ -1398,7 +1404,8 @@ function PMA_getForeignData(
$f_query_order = ($foreign_display == false) ? '' :' ORDER BY '
. PMA\libraries\Util::backquote($foreign_table) . '.'
. PMA\libraries\Util::backquote($foreign_display);
$f_query_limit = isset($foreign_limit) ? $foreign_limit : '';
$f_query_limit = ! empty($foreign_limit) ? ($foreign_limit) : '';
if (!empty($foreign_filter)) {
$the_total = $GLOBALS['dbi']->fetchValue(
@ -1436,6 +1443,11 @@ function PMA_getForeignData(
}
} while (false);
if ($get_total) {
$the_total = $GLOBALS['dbi']->getTable($foreign_db, $foreign_table)
->countRecords(true);
}
$foreignData = array();
$foreignData['foreign_link'] = $foreign_link;
$foreignData['the_total'] = isset($the_total) ? $the_total : null;
@ -1444,6 +1456,7 @@ function PMA_getForeignData(
);
$foreignData['disp_row'] = isset($disp_row) ? $disp_row : null;
$foreignData['foreign_field'] = isset($foreign_field) ? $foreign_field : null;
return $foreignData;
} // end of 'PMA_getForeignData()' function
@ -1467,14 +1480,14 @@ function PMA_REL_renameField($db, $table, $field, $new_name)
$table_query = 'UPDATE '
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['table_info'])
. ' SET display_field = \'' . PMA\libraries\Util::sqlAddSlashes(
. ' SET display_field = \'' . $GLOBALS['dbi']->escapeString(
$new_name
) . '\''
. ' WHERE db_name = \'' . PMA\libraries\Util::sqlAddSlashes($db)
. ' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db)
. '\''
. ' AND table_name = \'' . PMA\libraries\Util::sqlAddSlashes($table)
. ' AND table_name = \'' . $GLOBALS['dbi']->escapeString($table)
. '\''
. ' AND display_field = \'' . PMA\libraries\Util::sqlAddSlashes($field)
. ' AND display_field = \'' . $GLOBALS['dbi']->escapeString($field)
. '\'';
PMA_queryAsControlUser($table_query);
}
@ -1483,28 +1496,28 @@ function PMA_REL_renameField($db, $table, $field, $new_name)
$table_query = 'UPDATE '
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['relation'])
. ' SET master_field = \'' . PMA\libraries\Util::sqlAddSlashes(
. ' SET master_field = \'' . $GLOBALS['dbi']->escapeString(
$new_name
) . '\''
. ' WHERE master_db = \'' . PMA\libraries\Util::sqlAddSlashes($db)
. ' WHERE master_db = \'' . $GLOBALS['dbi']->escapeString($db)
. '\''
. ' AND master_table = \'' . PMA\libraries\Util::sqlAddSlashes($table)
. ' AND master_table = \'' . $GLOBALS['dbi']->escapeString($table)
. '\''
. ' AND master_field = \'' . PMA\libraries\Util::sqlAddSlashes($field)
. ' AND master_field = \'' . $GLOBALS['dbi']->escapeString($field)
. '\'';
PMA_queryAsControlUser($table_query);
$table_query = 'UPDATE '
. PMA\libraries\Util::backquote($cfgRelation['db']) . '.'
. PMA\libraries\Util::backquote($cfgRelation['relation'])
. ' SET foreign_field = \'' . PMA\libraries\Util::sqlAddSlashes(
. ' SET foreign_field = \'' . $GLOBALS['dbi']->escapeString(
$new_name
) . '\''
. ' WHERE foreign_db = \'' . PMA\libraries\Util::sqlAddSlashes($db)
. ' WHERE foreign_db = \'' . $GLOBALS['dbi']->escapeString($db)
. '\''
. ' AND foreign_table = \'' . PMA\libraries\Util::sqlAddSlashes($table)
. ' AND foreign_table = \'' . $GLOBALS['dbi']->escapeString($table)
. '\''
. ' AND foreign_field = \'' . PMA\libraries\Util::sqlAddSlashes($field)
. ' AND foreign_field = \'' . $GLOBALS['dbi']->escapeString($field)
. '\'';
PMA_queryAsControlUser($table_query);
@ -1534,14 +1547,14 @@ function PMA_REL_renameSingleTable($table,
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['db']) . '.'
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation'][$table])
. ' SET '
. $db_field . ' = \'' . PMA\libraries\Util::sqlAddSlashes($target_db)
. $db_field . ' = \'' . $GLOBALS['dbi']->escapeString($target_db)
. '\', '
. $table_field . ' = \'' . PMA\libraries\Util::sqlAddSlashes($target_table)
. $table_field . ' = \'' . $GLOBALS['dbi']->escapeString($target_table)
. '\''
. ' WHERE '
. $db_field . ' = \'' . PMA\libraries\Util::sqlAddSlashes($source_db) . '\''
. $db_field . ' = \'' . $GLOBALS['dbi']->escapeString($source_db) . '\''
. ' AND '
. $table_field . ' = \'' . PMA\libraries\Util::sqlAddSlashes($source_table)
. $table_field . ' = \'' . $GLOBALS['dbi']->escapeString($source_table)
. '\'';
PMA_queryAsControlUser($query);
}
@ -1614,8 +1627,8 @@ function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_tabl
$remove_query = "DELETE FROM "
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['db']) . "."
. PMA\libraries\Util::backquote($GLOBALS['cfgRelation']['table_coords'])
. " WHERE db_name = '" . PMA\libraries\Util::sqlAddSlashes($source_db) . "'"
. " AND table_name = '" . PMA\libraries\Util::sqlAddSlashes($source_table)
. " WHERE db_name = '" . $GLOBALS['dbi']->escapeString($source_db) . "'"
. " AND table_name = '" . $GLOBALS['dbi']->escapeString($source_table)
. "'";
PMA_queryAsControlUser($remove_query);
}
@ -1645,13 +1658,13 @@ function PMA_REL_renameTable($source_db, $target_db, $source_table, $target_tabl
. PMA\libraries\Util::backquote(
$GLOBALS['cfgRelation']['navigationhiding']
)
. " SET db_name = '" . PMA\libraries\Util::sqlAddSlashes($target_db)
. " SET db_name = '" . $GLOBALS['dbi']->escapeString($target_db)
. "',"
. " item_name = '" . PMA\libraries\Util::sqlAddSlashes($target_table)
. " item_name = '" . $GLOBALS['dbi']->escapeString($target_table)
. "'"
. " WHERE db_name = '" . PMA\libraries\Util::sqlAddSlashes($source_db)
. " WHERE db_name = '" . $GLOBALS['dbi']->escapeString($source_db)
. "'"
. " AND item_name = '" . PMA\libraries\Util::sqlAddSlashes($source_table)
. " AND item_name = '" . $GLOBALS['dbi']->escapeString($source_table)
. "'"
. " AND item_type = 'table'";
PMA_queryAsControlUser($query);
@ -1677,8 +1690,8 @@ function PMA_REL_createPage($newpage, $cfgRelation, $db)
. PMA\libraries\Util::backquote($cfgRelation['pdf_pages'])
. ' (db_name, page_descr)'
. ' VALUES (\''
. PMA\libraries\Util::sqlAddSlashes($db) . '\', \''
. PMA\libraries\Util::sqlAddSlashes($newpage) . '\')';
. $GLOBALS['dbi']->escapeString($db) . '\', \''
. $GLOBALS['dbi']->escapeString($newpage) . '\')';
PMA_queryAsControlUser($ins_query, false);
return $GLOBALS['dbi']->insertId(
@ -1704,12 +1717,12 @@ function PMA_getChildReferences($db, $table, $column = '')
. " `table_schema`, `referenced_column_name`"
. " FROM `information_schema`.`key_column_usage`"
. " WHERE `referenced_table_name` = '"
. PMA\libraries\Util::sqlAddSlashes($table) . "'"
. $GLOBALS['dbi']->escapeString($table) . "'"
. " AND `referenced_table_schema` = '"
. PMA\libraries\Util::sqlAddSlashes($db) . "'";
. $GLOBALS['dbi']->escapeString($db) . "'";
if ($column) {
$rel_query .= " AND `referenced_column_name` = '"
. PMA\libraries\Util::sqlAddSlashes($column) . "'";
. $GLOBALS['dbi']->escapeString($column) . "'";
}
$child_references = $GLOBALS['dbi']->fetchResult(

Some files were not shown because too many files have changed in this diff Show More