diff --git a/doc/security.rst b/doc/security.rst index 02e252f71b..4d2e7658c1 100644 --- a/doc/security.rst +++ b/doc/security.rst @@ -64,7 +64,7 @@ mysql control connection. This controlconnection can have additional privileges which the logged in user does not poses. E.g. access the :ref:`linked-tables`. User data that is included in (administrative) queries should always be run -through DatabaseInterface::escapeString(). +through DatabaseInterface::quoteString(). .. seealso:: diff --git a/libraries/classes/Bookmark.php b/libraries/classes/Bookmark.php index 8b9808de4d..f08011857d 100644 --- a/libraries/classes/Bookmark.php +++ b/libraries/classes/Bookmark.php @@ -120,10 +120,10 @@ class Bookmark $query = 'INSERT INTO ' . Util::backquote($bookmarkFeature->database) . '.' . Util::backquote($bookmarkFeature->bookmark) . ' (id, dbase, user, query, label) VALUES (NULL, ' - . "'" . $this->dbi->escapeString($this->database) . "', " - . "'" . $this->dbi->escapeString($this->currentUser) . "', " - . "'" . $this->dbi->escapeString($this->query) . "', " - . "'" . $this->dbi->escapeString($this->label) . "')"; + . $this->dbi->quoteString($this->database) . ', ' + . $this->dbi->quoteString($this->currentUser) . ', ' + . $this->dbi->quoteString($this->query) . ', ' + . $this->dbi->quoteString($this->label) . ')'; return (bool) $this->dbi->query($query, DatabaseInterface::CONNECT_CONTROL); } @@ -249,9 +249,9 @@ class Bookmark $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database) . '.' . Util::backquote($bookmarkFeature->bookmark) . " WHERE ( `user` = ''" - . " OR `user` = '" . $dbi->escapeString($user) . "' )"; + . ' OR `user` = ' . $dbi->quoteString($user) . ' )'; if ($db !== false) { - $query .= " AND dbase = '" . $dbi->escapeString($db) . "'"; + $query .= ' AND dbase = ' . $dbi->quoteString($db); } $query .= ' ORDER BY label ASC'; @@ -302,10 +302,9 @@ class Bookmark $query = 'SELECT * FROM ' . Util::backquote($bookmarkFeature->database) . '.' . Util::backquote($bookmarkFeature->bookmark) - . " WHERE dbase = '" . $dbi->escapeString($db->getName()) . "'"; + . ' WHERE dbase = ' . $dbi->quoteString($db->getName()); if (! $action_bookmark_all) { - $query .= " AND (user = '" - . $dbi->escapeString($user) . "'"; + $query .= ' AND (user = ' . $dbi->quoteString($user); if (! $exact_user_match) { $query .= " OR user = ''"; } @@ -314,7 +313,7 @@ class Bookmark } $query .= ' AND ' . Util::backquote($id_field) - . " = '" . $dbi->escapeString((string) $id) . "' LIMIT 1"; + . ' = ' . $dbi->quoteString((string) $id) . ' LIMIT 1'; $result = $dbi->fetchSingleRow($query, DatabaseInterface::FETCH_ASSOC, DatabaseInterface::CONNECT_CONTROL); if ($result !== null) { diff --git a/libraries/classes/ConfigStorage/Relation.php b/libraries/classes/ConfigStorage/Relation.php index 3d39d96b21..5bd20a7d85 100644 --- a/libraries/classes/ConfigStorage/Relation.php +++ b/libraries/classes/ConfigStorage/Relation.php @@ -428,11 +428,10 @@ class Relation . '`foreign_table`, `foreign_field`' . ' FROM ' . Util::backquote($relationFeature->database) . '.' . Util::backquote($relationFeature->relation) - . ' WHERE `master_db` = \'' . $this->dbi->escapeString($db) . '\'' - . ' AND `master_table` = \'' . $this->dbi->escapeString($table) . '\''; + . ' WHERE `master_db` = ' . $this->dbi->quoteString($db) + . ' AND `master_table` = ' . $this->dbi->quoteString($table); if (strlen($column) > 0) { - $rel_query .= ' AND `master_field` = ' - . '\'' . $this->dbi->escapeString($column) . '\''; + $rel_query .= ' AND `master_field` = ' . $this->dbi->quoteString($column); } $foreign = $this->dbi->fetchResult($rel_query, 'master_field', null, DatabaseInterface::CONNECT_CONTROL); @@ -500,8 +499,8 @@ class Relation $disp_query = 'SELECT `display_field`' . ' FROM ' . Util::backquote($displayFeature->database) . '.' . Util::backquote($displayFeature->tableInfo) - . ' WHERE `db_name` = \'' . $this->dbi->escapeString((string) $db) . '\'' - . ' AND `table_name` = \'' . $this->dbi->escapeString((string) $table) . '\''; + . ' WHERE `db_name` = ' . $this->dbi->quoteString((string) $db) + . ' AND `table_name` = ' . $this->dbi->quoteString((string) $table); $row = $this->dbi->fetchSingleRow( $disp_query, @@ -581,7 +580,7 @@ class Relation $com_qry = 'SELECT `comment`' . ' FROM ' . Util::backquote($columnCommentsFeature->database) . '.' . Util::backquote($columnCommentsFeature->columnInfo) - . ' WHERE db_name = \'' . $this->dbi->escapeString($db) . '\'' + . ' WHERE db_name = ' . $this->dbi->quoteString($db) . ' AND table_name = \'\'' . ' AND column_name = \'(db_comment)\''; $com_rs = $this->dbi->tryQueryAsControlUser($com_qry); @@ -639,19 +638,19 @@ class Relation . Util::backquote($columnCommentsFeature->database) . '.' . Util::backquote($columnCommentsFeature->columnInfo) . ' (`db_name`, `table_name`, `column_name`, `comment`)' - . ' VALUES (\'' - . $this->dbi->escapeString($db) - . "', '', '(db_comment)', '" - . $this->dbi->escapeString($comment) - . "') " + . ' VALUES (' + . $this->dbi->quoteString($db) + . ", '', '(db_comment)', " + . $this->dbi->quoteString($comment) + . ') ' . ' ON DUPLICATE KEY UPDATE ' - . "`comment` = '" . $this->dbi->escapeString($comment) . "'"; + . '`comment` = ' . $this->dbi->quoteString($comment); } else { $upd_query = 'DELETE FROM ' . Util::backquote($columnCommentsFeature->database) . '.' . Util::backquote($columnCommentsFeature->columnInfo) - . ' WHERE `db_name` = \'' . $this->dbi->escapeString($db) - . '\' + . ' WHERE `db_name` = ' . $this->dbi->quoteString($db) + . ' AND `table_name` = \'\' AND `column_name` = \'(db_comment)\''; } @@ -706,11 +705,11 @@ class Relation `timevalue`, `sqlquery`) VALUES - (\'' . $this->dbi->escapeString($username) . '\', - \'' . $this->dbi->escapeString($db) . '\', - \'' . $this->dbi->escapeString($table) . '\', + (' . $this->dbi->quoteString($username) . ', + ' . $this->dbi->quoteString($db) . ', + ' . $this->dbi->quoteString($table) . ', NOW(), - \'' . $this->dbi->escapeString($sqlquery) . '\')' + ' . $this->dbi->quoteString($sqlquery) . ')' ); $this->purgeHistory($username); @@ -749,7 +748,7 @@ class Relation `timevalue` FROM ' . Util::backquote($sqlHistoryFeature->database) . '.' . Util::backquote($sqlHistoryFeature->history) . ' - WHERE `username` = \'' . $this->dbi->escapeString($username) . '\' + WHERE `username` = ' . $this->dbi->quoteString($username) . ' ORDER BY `id` DESC'; return $this->dbi->fetchResult($hist_query, null, null, DatabaseInterface::CONNECT_CONTROL); @@ -774,7 +773,7 @@ class Relation SELECT `timevalue` FROM ' . Util::backquote($sqlHistoryFeature->database) . '.' . Util::backquote($sqlHistoryFeature->history) . ' - WHERE `username` = \'' . $this->dbi->escapeString($username) . '\' + WHERE `username` = ' . $this->dbi->quoteString($username) . ' ORDER BY `timevalue` DESC LIMIT ' . $GLOBALS['cfg']['QueryHistoryMax'] . ', 1'; @@ -788,8 +787,8 @@ class Relation 'DELETE FROM ' . Util::backquote($sqlHistoryFeature->database) . '.' . Util::backquote($sqlHistoryFeature->history) . ' - WHERE `username` = \'' . $this->dbi->escapeString($username) - . '\' + WHERE `username` = ' . $this->dbi->quoteString($username) + . ' AND `timevalue` <= \'' . $max_time . '\'' ); } @@ -1131,13 +1130,10 @@ class Relation $table_query = 'UPDATE ' . Util::backquote($relationParameters->displayFeature->database) . '.' . Util::backquote($relationParameters->displayFeature->tableInfo) - . ' SET display_field = \'' . $this->dbi->escapeString($new_name) . '\'' - . ' WHERE db_name = \'' . $this->dbi->escapeString($db) - . '\'' - . ' AND table_name = \'' . $this->dbi->escapeString($table) - . '\'' - . ' AND display_field = \'' . $this->dbi->escapeString($field) - . '\''; + . ' SET display_field = ' . $this->dbi->quoteString($new_name) + . ' WHERE db_name = ' . $this->dbi->quoteString($db) + . ' AND table_name = ' . $this->dbi->quoteString($table) + . ' AND display_field = ' . $this->dbi->quoteString($field); $this->dbi->queryAsControlUser($table_query); } @@ -1148,25 +1144,19 @@ class Relation $table_query = 'UPDATE ' . Util::backquote($relationParameters->relationFeature->database) . '.' . Util::backquote($relationParameters->relationFeature->relation) - . ' SET master_field = \'' . $this->dbi->escapeString($new_name) . '\'' - . ' WHERE master_db = \'' . $this->dbi->escapeString($db) - . '\'' - . ' AND master_table = \'' . $this->dbi->escapeString($table) - . '\'' - . ' AND master_field = \'' . $this->dbi->escapeString($field) - . '\''; + . ' SET master_field = ' . $this->dbi->quoteString($new_name) + . ' WHERE master_db = ' . $this->dbi->quoteString($db) + . ' AND master_table = ' . $this->dbi->quoteString($table) + . ' AND master_field = ' . $this->dbi->quoteString($field); $this->dbi->queryAsControlUser($table_query); $table_query = 'UPDATE ' . Util::backquote($relationParameters->relationFeature->database) . '.' . Util::backquote($relationParameters->relationFeature->relation) - . ' SET foreign_field = \'' . $this->dbi->escapeString($new_name) . '\'' - . ' WHERE foreign_db = \'' . $this->dbi->escapeString($db) - . '\'' - . ' AND foreign_table = \'' . $this->dbi->escapeString($table) - . '\'' - . ' AND foreign_field = \'' . $this->dbi->escapeString($field) - . '\''; + . ' SET foreign_field = ' . $this->dbi->quoteString($new_name) + . ' WHERE foreign_db = ' . $this->dbi->quoteString($db) + . ' AND foreign_table = ' . $this->dbi->quoteString($table) + . ' AND foreign_field = ' . $this->dbi->quoteString($field); $this->dbi->queryAsControlUser($table_query); } @@ -1194,15 +1184,13 @@ class Relation . Util::backquote($configStorageDatabase) . '.' . Util::backquote($configStorageTable) . ' SET ' - . $db_field . ' = \'' . $this->dbi->escapeString($target_db) - . '\', ' - . $table_field . ' = \'' . $this->dbi->escapeString($target_table) - . '\'' + . $db_field . ' = ' . $this->dbi->quoteString($target_db) + . ', ' + . $table_field . ' = ' . $this->dbi->quoteString($target_table) . ' WHERE ' - . $db_field . ' = \'' . $this->dbi->escapeString($source_db) . '\'' + . $db_field . ' = ' . $this->dbi->quoteString($source_db) . ' AND ' - . $table_field . ' = \'' . $this->dbi->escapeString($source_table) - . '\''; + . $table_field . ' = ' . $this->dbi->quoteString($source_table); $this->dbi->queryAsControlUser($query); } @@ -1293,9 +1281,8 @@ class Relation $remove_query = 'DELETE FROM ' . Util::backquote($relationParameters->pdfFeature->database) . '.' . Util::backquote($relationParameters->pdfFeature->tableCoords) - . " WHERE db_name = '" . $this->dbi->escapeString($source_db) . "'" - . " AND table_name = '" . $this->dbi->escapeString($source_table) - . "'"; + . ' WHERE db_name = ' . $this->dbi->quoteString($source_db) + . ' AND table_name = ' . $this->dbi->quoteString($source_table); $this->dbi->queryAsControlUser($remove_query); } } @@ -1333,14 +1320,11 @@ class Relation $query = 'UPDATE ' . Util::backquote($relationParameters->navigationItemsHidingFeature->database) . '.' . Util::backquote($relationParameters->navigationItemsHidingFeature->navigationHiding) - . " SET db_name = '" . $this->dbi->escapeString($target_db) - . "'," - . " item_name = '" . $this->dbi->escapeString($target_table) - . "'" - . " WHERE db_name = '" . $this->dbi->escapeString($source_db) - . "'" - . " AND item_name = '" . $this->dbi->escapeString($source_table) - . "'" + . ' SET db_name = ' . $this->dbi->quoteString($target_db) + . ',' + . ' item_name = ' . $this->dbi->quoteString($target_table) + . ' WHERE db_name = ' . $this->dbi->quoteString($source_db) + . ' AND item_name = ' . $this->dbi->quoteString($source_table) . " AND item_type = 'table'"; $this->dbi->queryAsControlUser($query); } @@ -1357,9 +1341,9 @@ class Relation . Util::backquote($pdfFeature->database) . '.' . Util::backquote($pdfFeature->pdfPages) . ' (db_name, page_descr)' - . ' VALUES (\'' - . $this->dbi->escapeString($db) . '\', \'' - . $this->dbi->escapeString($newpage ?: __('no description')) . '\')'; + . ' VALUES (' + . $this->dbi->quoteString($db) . ', ' + . $this->dbi->quoteString($newpage ?: __('no description')) . ')'; $this->dbi->tryQueryAsControlUser($ins_query); return $this->dbi->insertId(DatabaseInterface::CONNECT_CONTROL); @@ -1379,13 +1363,13 @@ class Relation $rel_query = 'SELECT `column_name`, `table_name`,' . ' `table_schema`, `referenced_column_name`' . ' FROM `information_schema`.`key_column_usage`' - . " WHERE `referenced_table_name` = '" - . $this->dbi->escapeString($table) . "'" - . " AND `referenced_table_schema` = '" - . $this->dbi->escapeString($db) . "'"; + . ' WHERE `referenced_table_name` = ' + . $this->dbi->quoteString($table) + . ' AND `referenced_table_schema` = ' + . $this->dbi->quoteString($db); if ($column) { - $rel_query .= " AND `referenced_column_name` = '" - . $this->dbi->escapeString($column) . "'"; + $rel_query .= ' AND `referenced_column_name` = ' + . $this->dbi->quoteString($column); } return $this->dbi->fetchResult( diff --git a/libraries/classes/DatabaseInterface.php b/libraries/classes/DatabaseInterface.php index 642405e536..7a6254ad73 100644 --- a/libraries/classes/DatabaseInterface.php +++ b/libraries/classes/DatabaseInterface.php @@ -485,18 +485,18 @@ class DatabaseInterface implements DbalInterface $needAnd = false; if ($table || ($tableIsGroup === true)) { if (is_array($table)) { - $sql .= ' `Name` IN (\'' + $sql .= ' `Name` IN (' . implode( - '\', \'', + ', ', array_map( [ $this, - 'escapeString', + 'quoteString', ], $table, $link ) - ) . '\')'; + ) . ')'; } else { $sql .= " `Name` LIKE '" . $this->escapeMysqlLikeString($table, $link) @@ -832,9 +832,9 @@ class DatabaseInterface implements DbalInterface ): array { if (! $GLOBALS['cfg']['Server']['DisableIS']) { $sql = QueryGenerator::getInformationSchemaColumnsFullRequest( - $database !== null ? $this->escapeString($database, $link) : null, - $table !== null ? $this->escapeString($table, $link) : null, - $column !== null ? $this->escapeString($column, $link) : null + $database !== null ? $this->quoteString($database, $link) : null, + $table !== null ? $this->quoteString($table, $link) : null, + $column !== null ? $this->quoteString($column, $link) : null ); $arrayKeys = QueryGenerator::getInformationSchemaColumns($database, $table, $column); @@ -1122,9 +1122,7 @@ class DatabaseInterface implements DbalInterface // Set timezone for the session, if required. if ($GLOBALS['cfg']['Server']['SessionTimeZone'] != '') { $sqlQueryTz = 'SET ' . Util::backquote('time_zone') . ' = ' - . '\'' - . $this->escapeString($GLOBALS['cfg']['Server']['SessionTimeZone']) - . '\''; + . $this->quoteString($GLOBALS['cfg']['Server']['SessionTimeZone']); if (! $this->tryQuery($sqlQueryTz)) { $errorMessageTz = sprintf( @@ -1167,9 +1165,9 @@ class DatabaseInterface implements DbalInterface } $result = $this->tryQuery( - "SET collation_connection = '" - . $this->escapeString($collation) - . "';" + 'SET collation_connection = ' + . $this->quoteString($collation) + . ';' ); if ($result === false) { @@ -1888,9 +1886,26 @@ class DatabaseInterface implements DbalInterface return $fields; } + /** + * Returns properly quoted string for use in MySQL queries. + * + * @param string $str string to be quoted + * @param mixed $link optional database link to use + * + * @psalm-return non-empty-string + * + * @psalm-taint-escape sql + */ + public function quoteString(string $str, $link = self::CONNECT_USER): string + { + return "'" . $this->extension->escapeString($this->links[$link], $str) . "'"; + } + /** * returns properly escaped string for use in MySQL queries * + * @deprecated Use {@see quoteString()} instead. + * * @param string $str string to be escaped * @param mixed $link optional database link to use * @@ -1986,8 +2001,8 @@ class DatabaseInterface implements DbalInterface if (! $GLOBALS['cfg']['Server']['DisableIS']) { // this is slow with thousands of databases $sql = 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA' - . ' WHERE SCHEMA_NAME = \'' . $this->escapeString($db) - . '\' LIMIT 1'; + . ' WHERE SCHEMA_NAME = ' . $this->quoteString($db) + . ' LIMIT 1'; return (string) $this->fetchValue($sql); } diff --git a/libraries/classes/Dbal/DbalInterface.php b/libraries/classes/Dbal/DbalInterface.php index e51a504c53..28d8f883c4 100644 --- a/libraries/classes/Dbal/DbalInterface.php +++ b/libraries/classes/Dbal/DbalInterface.php @@ -577,9 +577,23 @@ interface DbalInterface */ public function getFieldsMeta(ResultInterface $result): array; + /** + * Returns properly quoted string for use in MySQL queries. + * + * @param string $str string to be quoted + * @param mixed $link optional database link to use + * + * @psalm-return non-empty-string + * + * @psalm-taint-escape sql + */ + public function quoteString(string $str, $link = DatabaseInterface::CONNECT_USER): string; + /** * returns properly escaped string for use in MySQL queries * + * @deprecated Use {@see quoteString()} instead. + * * @param string $str string to be escaped * @param mixed $link optional database link to use * diff --git a/libraries/classes/Export.php b/libraries/classes/Export.php index 4dd5491b03..166ced3026 100644 --- a/libraries/classes/Export.php +++ b/libraries/classes/Export.php @@ -730,8 +730,8 @@ class Export // This obtains the current table's size $query = 'SELECT data_length + index_length from information_schema.TABLES - WHERE table_schema = "' . $this->dbi->escapeString($db->getName()) . '" - AND table_name = "' . $this->dbi->escapeString($table) . '"'; + WHERE table_schema = ' . $this->dbi->quoteString($db->getName()) . ' + AND table_name = ' . $this->dbi->quoteString($table); $size = (int) $this->dbi->fetchValue($query); //Converting the size to MB diff --git a/libraries/classes/Import.php b/libraries/classes/Import.php index 5a69a0951c..769ba10078 100644 --- a/libraries/classes/Import.php +++ b/libraries/classes/Import.php @@ -1127,9 +1127,9 @@ class Import $isVarchar = false; } - $tempSQLStr .= $isVarchar ? "'" : ''; - $tempSQLStr .= $GLOBALS['dbi']->escapeString((string) $tables[$i][self::ROWS][$j][$k]); - $tempSQLStr .= $isVarchar ? "'" : ''; + $tempSQLStr .= $isVarchar + ? $GLOBALS['dbi']->quoteString((string) $tables[$i][self::ROWS][$j][$k]) + : (string) $tables[$i][self::ROWS][$j][$k]; } if ($k != $numCols - 1) { @@ -1421,8 +1421,8 @@ class Import // Query to check if table is 'Transactional'. $checkQuery = 'SELECT `ENGINE` FROM `information_schema`.`tables` ' - . 'WHERE `table_name` = "' . $GLOBALS['dbi']->escapeString($table) . '" ' - . 'AND `table_schema` = "' . $GLOBALS['dbi']->escapeString($db) . '" ' + . 'WHERE `table_name` = ' . $GLOBALS['dbi']->quoteString($table) . ' ' + . 'AND `table_schema` = ' . $GLOBALS['dbi']->quoteString($db) . ' ' . 'AND UPPER(`engine`) IN ("' . implode('", "', $transactionalEngines) . '")'; diff --git a/libraries/classes/InsertEdit.php b/libraries/classes/InsertEdit.php index bd487bb9b7..5769cf17c4 100644 --- a/libraries/classes/InsertEdit.php +++ b/libraries/classes/InsertEdit.php @@ -1566,21 +1566,21 @@ class InsertEdit */ $hash = password_hash($editField->value, PASSWORD_DEFAULT); - return "'" . $this->dbi->escapeString($hash) . "'"; + return $this->dbi->quoteString($hash); } if ($editField->function === 'UUID') { /* This way user will know what UUID new row has */ $uuid = (string) $this->dbi->fetchValue('SELECT UUID()'); - return "'" . $this->dbi->escapeString($uuid) . "'"; + return $this->dbi->quoteString($uuid); } if ( in_array($editField->function, $this->getGisFromTextFunctions()) || in_array($editField->function, $this->getGisFromWKBFunctions()) ) { - return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "')"; + return $editField->function . '(' . $this->dbi->quoteString($editField->value) . ')'; } if ( @@ -1597,11 +1597,11 @@ class InsertEdit || $editField->function === 'DES_DECRYPT' || $editField->function === 'ENCRYPT')) ) { - return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "','" - . $this->dbi->escapeString($editField->salt) . "')"; + return $editField->function . '(' . $this->dbi->quoteString($editField->value) . ',' + . $this->dbi->quoteString($editField->salt) . ')'; } - return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "')"; + return $editField->function . '(' . $this->dbi->quoteString($editField->value) . ')'; } return $editField->function . '()'; @@ -1738,7 +1738,7 @@ class InsertEdit if ($editField->type === 'bit') { $currentValue = (string) preg_replace('/[^01]/', '0', $editField->value); - return "b'" . $this->dbi->escapeString($currentValue) . "'"; + return 'b' . $this->dbi->quoteString($currentValue); } // For uuid type, generate uuid value @@ -1755,7 +1755,7 @@ class InsertEdit ($editField->type !== 'datetime' && $editField->type !== 'timestamp' && $editField->type !== 'date') || ($editField->value !== 'CURRENT_TIMESTAMP' && $editField->value !== 'current_timestamp()') ) { - return "'" . $this->dbi->escapeString($editField->value) . "'"; + return $this->dbi->quoteString($editField->value); } // If there is a value, we ignore the Null checkbox; diff --git a/libraries/classes/Menu.php b/libraries/classes/Menu.php index 4d9bf22d81..8fffa57268 100644 --- a/libraries/classes/Menu.php +++ b/libraries/classes/Menu.php @@ -134,8 +134,8 @@ class Menu . " WHERE `allowed` = 'N'" . " AND `tab` LIKE '" . $level . "%'" . ' AND `usergroup` = (SELECT usergroup FROM ' - . $userTable . " WHERE `username` = '" - . $this->dbi->escapeString($GLOBALS['cfg']['Server']['user']) . "')"; + . $userTable . ' WHERE `username` = ' + . $this->dbi->quoteString($GLOBALS['cfg']['Server']['user']) . ')'; $result = $this->dbi->tryQueryAsControlUser($sqlQuery); if ($result) { diff --git a/libraries/classes/Operations.php b/libraries/classes/Operations.php index 0639149bc1..e939e38ba0 100644 --- a/libraries/classes/Operations.php +++ b/libraries/classes/Operations.php @@ -261,8 +261,8 @@ class Operations public function runEventDefinitionsForDb($db, DatabaseName $newDatabaseName): void { $event_names = $this->dbi->fetchResult( - 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= \'' - . $this->dbi->escapeString($db) . '\';' + 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA= ' + . $this->dbi->quoteString($db) . ';' ); if (! $event_names) { return; @@ -327,26 +327,26 @@ class Operations // For Db specific privileges $query_db_specific = 'UPDATE ' . Util::backquote('db') - . 'SET Db = \'' . $this->dbi->escapeString($newName) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newName) + . ' where Db = ' . $this->dbi->quoteString($oldDb) . ';'; $this->dbi->query($query_db_specific); // For table specific privileges $query_table_specific = 'UPDATE ' . Util::backquote('tables_priv') - . 'SET Db = \'' . $this->dbi->escapeString($newName) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newName) + . ' where Db = ' . $this->dbi->quoteString($oldDb) . ';'; $this->dbi->query($query_table_specific); // For column specific privileges $query_col_specific = 'UPDATE ' . Util::backquote('columns_priv') - . 'SET Db = \'' . $this->dbi->escapeString($newName) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newName) + . ' where Db = ' . $this->dbi->quoteString($oldDb) . ';'; $this->dbi->query($query_col_specific); // For procedures specific privileges $query_proc_specific = 'UPDATE ' . Util::backquote('procs_priv') - . 'SET Db = \'' . $this->dbi->escapeString($newName) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newName) + . ' where Db = ' . $this->dbi->quoteString($oldDb) . ';'; $this->dbi->query($query_proc_specific); // Finally FLUSH the new privileges @@ -680,8 +680,7 @@ class Operations $table_alters = []; if (isset($_POST['comment']) && urldecode($_POST['prev_comment']) !== $_POST['comment']) { - $table_alters[] = 'COMMENT = \'' - . $this->dbi->escapeString($_POST['comment']) . '\''; + $table_alters[] = 'COMMENT = ' . $this->dbi->quoteString($_POST['comment']); } if ( @@ -799,20 +798,20 @@ class Operations // For table specific privileges $query_table_specific = 'UPDATE ' . Util::backquote('tables_priv') - . 'SET Db = \'' . $this->dbi->escapeString($newDb) - . '\', Table_name = \'' . $this->dbi->escapeString($newTable) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) - . '\' AND Table_name = \'' . $this->dbi->escapeString($oldTable) - . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newDb) + . ', Table_name = ' . $this->dbi->quoteString($newTable) + . ' where Db = ' . $this->dbi->quoteString($oldDb) + . ' AND Table_name = ' . $this->dbi->quoteString($oldTable) + . ';'; $this->dbi->query($query_table_specific); // For column specific privileges $query_col_specific = 'UPDATE ' . Util::backquote('columns_priv') - . 'SET Db = \'' . $this->dbi->escapeString($newDb) - . '\', Table_name = \'' . $this->dbi->escapeString($newTable) - . '\' where Db = \'' . $this->dbi->escapeString($oldDb) - . '\' AND Table_name = \'' . $this->dbi->escapeString($oldTable) - . '\';'; + . 'SET Db = ' . $this->dbi->quoteString($newDb) + . ', Table_name = ' . $this->dbi->quoteString($newTable) + . ' where Db = ' . $this->dbi->quoteString($oldDb) + . ' AND Table_name = ' . $this->dbi->quoteString($oldTable) + . ';'; $this->dbi->query($query_col_specific); // Finally FLUSH the new privileges diff --git a/libraries/classes/Query/Generator.php b/libraries/classes/Query/Generator.php index 98064bebb2..32d16f3395 100644 --- a/libraries/classes/Query/Generator.php +++ b/libraries/classes/Query/Generator.php @@ -297,15 +297,15 @@ class Generator // get columns information from information_schema if ($escapedDatabase !== null) { - $sqlWheres[] = '`TABLE_SCHEMA` = \'' . $escapedDatabase . '\' '; + $sqlWheres[] = '`TABLE_SCHEMA` = ' . $escapedDatabase . ' '; } if ($escapedTable !== null) { - $sqlWheres[] = '`TABLE_NAME` = \'' . $escapedTable . '\' '; + $sqlWheres[] = '`TABLE_NAME` = ' . $escapedTable . ' '; } if ($escapedColumn !== null) { - $sqlWheres[] = '`COLUMN_NAME` = \'' . $escapedColumn . '\' '; + $sqlWheres[] = '`COLUMN_NAME` = ' . $escapedColumn . ' '; } // for PMA bc: diff --git a/libraries/classes/RecentFavoriteTable.php b/libraries/classes/RecentFavoriteTable.php index 1a3675ab93..c95e24134c 100644 --- a/libraries/classes/RecentFavoriteTable.php +++ b/libraries/classes/RecentFavoriteTable.php @@ -117,7 +117,7 @@ class RecentFavoriteTable { // Read from phpMyAdmin database, if recent tables is not in session $sql_query = ' SELECT `tables` FROM ' . $this->getPmaTable() - . " WHERE `username` = '" . $GLOBALS['dbi']->escapeString($GLOBALS['cfg']['Server']['user']) . "'"; + . ' WHERE `username` = ' . $GLOBALS['dbi']->quoteString($GLOBALS['cfg']['Server']['user']); $result = $GLOBALS['dbi']->tryQueryAsControlUser($sql_query); if ($result) { @@ -139,8 +139,8 @@ class RecentFavoriteTable { $username = $GLOBALS['cfg']['Server']['user']; $sql_query = ' REPLACE INTO ' . $this->getPmaTable() . ' (`username`, `tables`)' - . " VALUES ('" . $GLOBALS['dbi']->escapeString($username) . "', '" - . $GLOBALS['dbi']->escapeString(json_encode($this->tables)) . "')"; + . ' VALUES (' . $GLOBALS['dbi']->quoteString($username) . ', ' + . $GLOBALS['dbi']->quoteString(json_encode($this->tables)) . ')'; $success = $GLOBALS['dbi']->tryQuery($sql_query, DatabaseInterface::CONNECT_CONTROL); diff --git a/libraries/classes/Replication.php b/libraries/classes/Replication.php index f7972e66ee..7afb651214 100644 --- a/libraries/classes/Replication.php +++ b/libraries/classes/Replication.php @@ -93,11 +93,11 @@ class Replication $out = $GLOBALS['dbi']->tryQuery( 'CHANGE MASTER TO ' . - 'MASTER_HOST=\'' . $GLOBALS['dbi']->escapeString($host) . '\',' . + 'MASTER_HOST=' . $GLOBALS['dbi']->quoteString($host) . ',' . 'MASTER_PORT=' . $port . ',' . - 'MASTER_USER=\'' . $GLOBALS['dbi']->escapeString($user) . '\',' . - 'MASTER_PASSWORD=\'' . $GLOBALS['dbi']->escapeString($password) . '\',' . - 'MASTER_LOG_FILE=\'' . $pos['File'] . '\',' . + 'MASTER_USER=' . $GLOBALS['dbi']->quoteString($user) . ',' . + 'MASTER_PASSWORD=' . $GLOBALS['dbi']->quoteString($password) . ',' . + 'MASTER_LOG_FILE=' . $GLOBALS['dbi']->quoteString($pos['File']) . ',' . 'MASTER_LOG_POS=' . $pos['Position'] . ';', $link ); diff --git a/libraries/classes/ReplicationInfo.php b/libraries/classes/ReplicationInfo.php index 0b9b928f36..c3dd3f7b8a 100644 --- a/libraries/classes/ReplicationInfo.php +++ b/libraries/classes/ReplicationInfo.php @@ -125,7 +125,7 @@ final class ReplicationInfo private function setDefaultPrimaryConnection(string $connection): void { - $this->dbi->query(sprintf('SET @@default_master_connection = \'%s\'', $this->dbi->escapeString($connection))); + $this->dbi->query(sprintf('SET @@default_master_connection = %s', $this->dbi->quoteString($connection))); } private static function fill(array $status, string $key): array diff --git a/libraries/classes/SavedSearches.php b/libraries/classes/SavedSearches.php index fc6f8abe76..f6a352ec5e 100644 --- a/libraries/classes/SavedSearches.php +++ b/libraries/classes/SavedSearches.php @@ -264,8 +264,7 @@ class SavedSearches //If it's an insert. if ($this->getId() === null) { $wheres = [ - "search_name = '" . $GLOBALS['dbi']->escapeString($this->getSearchName()) - . "'", + 'search_name = ' . $GLOBALS['dbi']->quoteString($this->getSearchName()), ]; $existingSearches = $this->getList($savedQueryByExampleSearchesFeature, $wheres); @@ -283,11 +282,11 @@ class SavedSearches $sqlQuery = 'INSERT INTO ' . $savedSearchesTbl . '(`username`, `db_name`, `search_name`, `search_data`)' . ' VALUES (' - . "'" . $GLOBALS['dbi']->escapeString($this->getUsername()) . "'," - . "'" . $GLOBALS['dbi']->escapeString($this->getDbname()) . "'," - . "'" . $GLOBALS['dbi']->escapeString($this->getSearchName()) . "'," - . "'" . $GLOBALS['dbi']->escapeString(json_encode($this->getCriterias())) - . "')"; + . $GLOBALS['dbi']->quoteString($this->getUsername()) . ',' + . $GLOBALS['dbi']->quoteString($this->getDbname()) . ',' + . $GLOBALS['dbi']->quoteString($this->getSearchName()) . ',' + . $GLOBALS['dbi']->quoteString(json_encode($this->getCriterias())) + . ')'; $GLOBALS['dbi']->queryAsControlUser($sqlQuery); @@ -299,7 +298,7 @@ class SavedSearches //Else, it's an update. $wheres = [ 'id != ' . $this->getId(), - "search_name = '" . $GLOBALS['dbi']->escapeString($this->getSearchName()) . "'", + 'search_name = ' . $GLOBALS['dbi']->quoteString($this->getSearchName()), ]; $existingSearches = $this->getList($savedQueryByExampleSearchesFeature, $wheres); @@ -315,10 +314,10 @@ class SavedSearches } $sqlQuery = 'UPDATE ' . $savedSearchesTbl - . "SET `search_name` = '" - . $GLOBALS['dbi']->escapeString($this->getSearchName()) . "', " - . "`search_data` = '" - . $GLOBALS['dbi']->escapeString(json_encode($this->getCriterias())) . "' " + . 'SET `search_name` = ' + . $GLOBALS['dbi']->quoteString($this->getSearchName()) . ', ' + . '`search_data` = ' + . $GLOBALS['dbi']->quoteString(json_encode($this->getCriterias())) . ' ' . 'WHERE id = ' . $this->getId(); return (bool) $GLOBALS['dbi']->queryAsControlUser($sqlQuery); @@ -344,7 +343,7 @@ class SavedSearches . Util::backquote($savedQueryByExampleSearchesFeature->savedSearches); $sqlQuery = 'DELETE FROM ' . $savedSearchesTbl - . "WHERE id = '" . $GLOBALS['dbi']->escapeString((string) $this->getId()) . "'"; + . 'WHERE id = ' . $GLOBALS['dbi']->quoteString((string) $this->getId()); return (bool) $GLOBALS['dbi']->queryAsControlUser($sqlQuery); } @@ -370,7 +369,7 @@ class SavedSearches . Util::backquote($savedQueryByExampleSearchesFeature->savedSearches); $sqlQuery = 'SELECT id, search_name, search_data ' . 'FROM ' . $savedSearchesTbl . ' ' - . "WHERE id = '" . $GLOBALS['dbi']->escapeString((string) $this->getId()) . "' "; + . 'WHERE id = ' . $GLOBALS['dbi']->quoteString((string) $this->getId()); $resList = $GLOBALS['dbi']->queryAsControlUser($sqlQuery); $oneResult = $resList->fetchAssoc(); @@ -409,8 +408,8 @@ class SavedSearches $sqlQuery = 'SELECT id, search_name ' . 'FROM ' . $savedSearchesTbl . ' ' . 'WHERE ' - . "username = '" . $GLOBALS['dbi']->escapeString($this->getUsername()) . "' " - . "AND db_name = '" . $GLOBALS['dbi']->escapeString($this->getDbname()) . "' "; + . 'username = ' . $GLOBALS['dbi']->quoteString($this->getUsername()) . ' ' + . 'AND db_name = ' . $GLOBALS['dbi']->quoteString($this->getDbname()) . ' '; foreach ($wheres as $where) { $sqlQuery .= 'AND ' . $where . ' '; diff --git a/libraries/classes/SystemDatabase.php b/libraries/classes/SystemDatabase.php index 3b9b2acc81..5adefbcb9a 100644 --- a/libraries/classes/SystemDatabase.php +++ b/libraries/classes/SystemDatabase.php @@ -47,10 +47,10 @@ class SystemDatabase // Get the existing transformation details of the same database // from pma__column_info table $transformationSql = sprintf( - "SELECT * FROM %s.%s WHERE `db_name` = '%s'", + 'SELECT * FROM %s.%s WHERE `db_name` = %s', Util::backquote($browserTransformationFeature->database), Util::backquote($browserTransformationFeature->columnInfo), - $this->dbi->escapeString($db) + $this->dbi->quoteString($db) ); return $this->dbi->tryQuery($transformationSql); @@ -100,15 +100,15 @@ class SystemDatabase } $newTransformationsSql .= sprintf( - "%s ('%s', '%s', '%s', '%s', '%s', '%s', '%s')", + '%s (%s, %s, %s, %s, %s, %s, %s)', $addComma ? ', ' : '', - $db, - $viewName, - $column['real_column'] ?? $column['refering_column'], - $dataRow['comment'], - $dataRow['mimetype'], - $dataRow['transformation'], - $this->dbi->escapeString($dataRow['transformation_options']) + $this->dbi->quoteString($db), + $this->dbi->quoteString($viewName), + $this->dbi->quoteString($column['real_column'] ?? $column['refering_column']), + $this->dbi->quoteString($dataRow['comment']), + $this->dbi->quoteString($dataRow['mimetype']), + $this->dbi->quoteString($dataRow['transformation']), + $this->dbi->quoteString($dataRow['transformation_options']) ); $addComma = true; diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1a89c07005..784393c7e1 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4911,7 +4911,7 @@ parameters: path: libraries/classes/InsertEdit.php - - message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:escapeString\\(\\) expects string, string\\|false given\\.$#" + message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, string\\|false given\\.$#" count: 1 path: libraries/classes/InsertEdit.php @@ -7941,8 +7941,8 @@ parameters: path: libraries/classes/SystemDatabase.php - - message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:escapeString\\(\\) expects string, string\\|null given\\.$#" - count: 1 + message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, string\\|null given\\.$#" + count: 4 path: libraries/classes/SystemDatabase.php - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 1af57e1e20..e96264a44a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -46,6 +46,9 @@ + + escapeString + $bkm_fields['bkm_label'] $bkm_fields['bkm_sql_query'] @@ -767,6 +770,10 @@ + + escapeString + escapeString + usort($tables, 'strnatcasecmp') @@ -887,7 +894,67 @@ is_scalar($GLOBALS['cfg']['ForeignKeyDropdownOrder'][1]) + + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + + + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $tabNames @@ -1223,6 +1290,12 @@ $request->getParsedBodyParam('sql_query') + + + escapeString + escapeString + + $dbCollation @@ -2158,6 +2231,9 @@ + + escapeString + $import_plugin == null @@ -2955,6 +3031,9 @@ + + escapeString + $username @@ -2967,6 +3046,9 @@ + + escapeString + $params['name'] $params['name'] @@ -2977,6 +3059,10 @@ + + escapeString + escapeString + $formattedValue $varValue[1] @@ -3347,6 +3433,12 @@ + + escapeString + escapeString + escapeString + escapeString + $_POST['columnIndex'] $_POST['columnIndex'] @@ -4307,6 +4399,10 @@ + + escapeString + escapeString + $GLOBALS['view']['as'] @@ -4467,6 +4563,14 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $_POST['comment'] @@ -4602,6 +4706,41 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $tn_pageNow @@ -4795,6 +4934,10 @@ + + escapeString + escapeString + $tabColumn[$tableName]['COLUMN_ID'] $tabColumn[$tableName]['TYPE'][$j] @@ -4859,6 +5002,32 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $DB $TAB @@ -4957,6 +5126,17 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $GLOBALS['errors'] $GLOBALS['errors'] @@ -5268,6 +5448,22 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $itemParamDir $itemParamName @@ -5555,6 +5751,10 @@ + + escapeString + escapeString + $column['Field'] $eachTable @@ -5578,6 +5778,12 @@ + + escapeString + escapeString + escapeString + escapeString + $GLOBALS['errors'] $GLOBALS['errors'] @@ -5723,6 +5929,14 @@ + + [$this, 'escapeString'] + escapeString + escapeString + escapeString + escapeString + escapeString + $resultTarget[] @@ -5796,7 +6010,7 @@ $tableData['Engine'] $tableData['Index_length'] - + $databases[$databaseName] $resultRows[$row[$key]] $resultTarget[$row[$keyIndex]] @@ -5807,6 +6021,7 @@ $row[$keyIndex] $this->links[$link] $this->links[$link] + $this->links[$link] $aLength @@ -5881,6 +6096,9 @@ + + escapeString + $urlParams @@ -5940,6 +6158,9 @@ + + escapeString + $displayParts->hasNavigationBar && $statement !== null && empty($statement->limit) [] @@ -6593,6 +6814,20 @@ $state['username'] + + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + + $this->charsetnr @@ -7675,7 +7910,7 @@ $tables[$i][self::TBL_NAME] $tables[$i][self::TBL_NAME] - + $analyses[$i][self::FORMATTEDSQL][$colCount] $analyses[$i][self::SIZES] $analyses[$i][self::TYPES] @@ -7695,6 +7930,7 @@ $tables[$i][self::ROWS] $tables[$i][self::ROWS] $tables[$i][self::ROWS] + $tables[$i][self::ROWS] $tables[$i][self::TBL_NAME] $tables[$i][self::TBL_NAME] $tables[$n][self::TBL_NAME] @@ -8265,6 +8501,21 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $GLOBALS['cfg']['NavigationDisplayLogo'] $GLOBALS['cfg']['NavigationDisplayServers'] @@ -8289,6 +8540,10 @@ $table + + escapeString + escapeString + '' isset($this->pos) @@ -8431,6 +8686,15 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $GLOBALS['cfg']['Server']['hide_db'] $db @@ -8525,6 +8789,27 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $retval $retval @@ -8614,6 +8899,18 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $this->realParent()->realName $this->realParent()->realName @@ -8766,6 +9063,10 @@ + + escapeString + escapeString + $arr['foreign_db'] $arr['foreign_db'] @@ -8965,6 +9266,14 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $value['Name'] @@ -9652,6 +9961,18 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + empty($field->options) empty($field->references) @@ -9910,6 +10231,10 @@ + + escapeString + escapeString + $code $col_as @@ -10309,6 +10634,9 @@ + + escapeString + $nameArray === false $nameArray === false @@ -10401,6 +10729,11 @@ + + escapeString + escapeString + escapeString + $GLOBALS['ldi_columns'] $GLOBALS['ldi_enclosed'] @@ -10987,6 +11320,9 @@ + + escapeString + $data[$i] $data[$i] @@ -11979,6 +12315,9 @@ $output + + $pos['File'] + $data[0]['File'] $data[0]['Position'] @@ -11987,8 +12326,7 @@ $output['File'] $output['Position'] - - $pos['File'] + $pos['Position'] @@ -12171,6 +12509,108 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + '' @@ -12531,6 +12971,14 @@ $_POST['max_user_connections'] + + + escapeString + escapeString + escapeString + escapeString + + $server['only_db'] @@ -12598,6 +13046,9 @@ + + escapeString + $temp[strlen($temp) - 1] @@ -12810,6 +13261,9 @@ + + escapeString + $unlimNumRows @@ -13027,6 +13481,60 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $tableAutoIncrement ?? '' @@ -13386,6 +13894,12 @@ + + escapeString + escapeString + escapeString + escapeString + $_POST['criteriaColumnNames'][$column_index] $_POST['criteriaColumnTypes'][$column_index] @@ -13512,6 +14026,48 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + null null @@ -13583,6 +14139,14 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $columns $data[$which_log] @@ -13701,6 +14265,29 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $upd_query @@ -13799,6 +14386,16 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $hostname $hostname @@ -13824,6 +14421,15 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $path $url_params @@ -13844,6 +14450,12 @@ + + escapeString + escapeString + escapeString + escapeString + $group[$groupName]['tab' . $sep . 'count'] @@ -14786,6 +15398,10 @@ + + escapeString + escapeString + array array @@ -15682,6 +16298,15 @@ + + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + escapeString + $export $extra_data['new_privileges'] diff --git a/test/classes/Stubs/DbiDummy.php b/test/classes/Stubs/DbiDummy.php index e4affd0759..0784c51e75 100644 --- a/test/classes/Stubs/DbiDummy.php +++ b/test/classes/Stubs/DbiDummy.php @@ -2421,15 +2421,15 @@ class DbiDummy implements DbiExtension 'result' => [['table']], ], [ - 'query' => 'SELECT `ENGINE` FROM `information_schema`.`tables` WHERE `table_name` = "table_1"' - . ' AND `table_schema` = "PMA" AND UPPER(`engine`)' + 'query' => 'SELECT `ENGINE` FROM `information_schema`.`tables` WHERE `table_name` = \'table_1\'' + . ' AND `table_schema` = \'PMA\' AND UPPER(`engine`)' . ' IN ("INNODB", "FALCON", "NDB", "INFINIDB", "TOKUDB", "XTRADB", "SEQUENCE", "BDB")', 'columns' => ['ENGINE'], 'result' => [['INNODB']], ], [ - 'query' => 'SELECT `ENGINE` FROM `information_schema`.`tables` WHERE `table_name` = "table_2"' - . ' AND `table_schema` = "PMA" AND UPPER(`engine`)' + 'query' => 'SELECT `ENGINE` FROM `information_schema`.`tables` WHERE `table_name` = \'table_2\'' + . ' AND `table_schema` = \'PMA\' AND UPPER(`engine`)' . ' IN ("INNODB", "FALCON", "NDB", "INFINIDB", "TOKUDB", "XTRADB", "SEQUENCE", "BDB")', 'columns' => ['ENGINE'], 'result' => [['INNODB']], diff --git a/test/classes/SystemDatabaseTest.php b/test/classes/SystemDatabaseTest.php index 886d5fe9fd..f5d2666b6e 100644 --- a/test/classes/SystemDatabaseTest.php +++ b/test/classes/SystemDatabaseTest.php @@ -44,8 +44,10 @@ class SystemDatabaseTest extends AbstractTestCase ->will($this->returnValue($resultStub)); $dbi->expects($this->any()) - ->method('escapeString') - ->will($this->returnArgument(0)); + ->method('quoteString') + ->will($this->returnCallback(function (string $string) { + return "'" . $string . "'"; + })); $_SESSION['relation'] = []; $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([