Merge branch 'QA_5_2'
Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
commit
0819043d0e
@ -5,6 +5,11 @@ phpMyAdmin - ChangeLog
|
||||
- issue #17842 Change js.cookie.js to js.cookie.min.js
|
||||
- issue #17632 Improve tab keypress to text fields on the login form
|
||||
|
||||
5.2.2 (not yet released)
|
||||
- issue #17028 Fix total count of rows in not accurate
|
||||
- issue #17683 Fix total count of rows in not accurate
|
||||
- issue #17766 Allow to open in a new tab copy and edit row actions
|
||||
|
||||
5.2.1 (2023-02-07)
|
||||
- issue #17522 Fix case where the routes cache file is invalid
|
||||
- issue #17506 Fix error when configuring 2FA without XMLWriter or Imagick
|
||||
|
||||
@ -134,7 +134,7 @@ var DragDropImport = {
|
||||
var filename = $this.parent('span').attr('data-filename');
|
||||
$('body').append('<div class="pma_drop_result"><h2>' +
|
||||
window.Messages.dropImportImportResultHeader + ' - ' +
|
||||
Functions.escapeHtml(filename) + '<span class="close">x</span></h2>' + value.message + '</div>');
|
||||
escapeHtml(filename) + '<span class="close">x</span></h2>' + value.message + '</div>');
|
||||
$('.pma_drop_result').draggable(); // to make this dialog draggable
|
||||
}
|
||||
});
|
||||
|
||||
@ -7,6 +7,7 @@ namespace PhpMyAdmin\Controllers\Table;
|
||||
use PhpMyAdmin\Config\PageSettings;
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\AbstractController;
|
||||
use PhpMyAdmin\Core;
|
||||
use PhpMyAdmin\DbTableExists;
|
||||
use PhpMyAdmin\Html\Generator;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
@ -82,6 +83,12 @@ class ChangeController extends AbstractController
|
||||
|
||||
DbTableExists::check($GLOBALS['db'], $GLOBALS['table']);
|
||||
|
||||
if (isset($_GET['where_clause'], $_GET['where_clause_signature'])) {
|
||||
if (Core::checkSqlQuerySignature($_GET['where_clause'], $_GET['where_clause_signature'])) {
|
||||
$where_clause = $_GET['where_clause'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether Insert or Edit and set global variables
|
||||
*/
|
||||
|
||||
@ -290,7 +290,7 @@ final class ReplaceController extends AbstractController
|
||||
$valueSets[] = implode(', ', $queryValues);
|
||||
} else {
|
||||
// build update query
|
||||
$clauseIsUnique = $_POST['clause_is_unique'] ?? '';// Should contain 0 or 1
|
||||
$clauseIsUnique = $_POST['clause_is_unique'] ?? $_GET['clause_is_unique'] ?? '';// Should contain 0 or 1
|
||||
$GLOBALS['query'][] = 'UPDATE ' . Util::backquote($GLOBALS['table'])
|
||||
. ' SET ' . implode(', ', $queryValues)
|
||||
. ' WHERE ' . $where_clause
|
||||
|
||||
@ -2735,8 +2735,10 @@ class Results
|
||||
'db' => $this->properties['db'],
|
||||
'table' => $this->properties['table'],
|
||||
'where_clause' => $whereClause,
|
||||
'where_clause_signature' => Core::signSqlQuery($whereClause),
|
||||
'clause_is_unique' => $clauseIsUnique,
|
||||
'sql_query' => $urlSqlQuery,
|
||||
'sql_signature' => Core::signSqlQuery($urlSqlQuery),
|
||||
'goto' => Url::getFromRoute('/sql'),
|
||||
];
|
||||
|
||||
|
||||
@ -135,6 +135,13 @@ class InsertEdit
|
||||
'err_url' => $errorUrl,
|
||||
'sql_query' => $_POST['sql_query'] ?? '',
|
||||
];
|
||||
|
||||
if ($formParams['sql_query'] === '' && isset($_GET['sql_query'], $_GET['sql_signature'])) {
|
||||
if (Core::checkSqlQuerySignature($_GET['sql_query'], $_GET['sql_signature'])) {
|
||||
$formParams['sql_query'] = $_GET['sql_query'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($whereClauses)) {
|
||||
foreach ($whereClauseArray as $keyId => $whereClause) {
|
||||
$formParams['where_clause[' . $keyId . ']'] = trim($whereClause);
|
||||
@ -143,6 +150,8 @@ class InsertEdit
|
||||
|
||||
if (isset($_POST['clause_is_unique'])) {
|
||||
$formParams['clause_is_unique'] = $_POST['clause_is_unique'];
|
||||
} elseif (isset($_GET['clause_is_unique'])) {
|
||||
$formParams['clause_is_unique'] = $_GET['clause_is_unique'];
|
||||
}
|
||||
|
||||
return $formParams;
|
||||
|
||||
@ -15,6 +15,7 @@ use PhpMyAdmin\Html\Generator;
|
||||
use PhpMyAdmin\Html\MySQLDocumentation;
|
||||
use PhpMyAdmin\Query\Generator as QueryGenerator;
|
||||
use PhpMyAdmin\Query\Utilities;
|
||||
use PhpMyAdmin\SqlParser\Components\Expression;
|
||||
use PhpMyAdmin\SqlParser\Statements\AlterStatement;
|
||||
use PhpMyAdmin\SqlParser\Statements\DropStatement;
|
||||
use PhpMyAdmin\SqlParser\Statements\SelectStatement;
|
||||
@ -707,24 +708,24 @@ class Sql
|
||||
}
|
||||
} else {
|
||||
$statement = $statementInfo->statement;
|
||||
$tokenList = $statementInfo->parser->list;
|
||||
$replaces = [
|
||||
// Remove ORDER BY to decrease unnecessary sorting time
|
||||
[
|
||||
'ORDER BY',
|
||||
'',
|
||||
],
|
||||
// Removes LIMIT clause that might have been added
|
||||
[
|
||||
'LIMIT',
|
||||
'',
|
||||
],
|
||||
];
|
||||
$countQuery = 'SELECT COUNT(*) FROM (' . Query::replaceClauses(
|
||||
$statement,
|
||||
$tokenList,
|
||||
$replaces
|
||||
) . ') as cnt';
|
||||
|
||||
// Remove ORDER BY to decrease unnecessary sorting time
|
||||
if ($statementInfo->order !== false) {
|
||||
$statement->order = null;
|
||||
}
|
||||
|
||||
// Removes LIMIT clause that might have been added
|
||||
if ($statementInfo->limit !== null) {
|
||||
$statement->limit = null;
|
||||
}
|
||||
|
||||
if ($statementInfo->isGroup === false && count($statement->expr) === 1) {
|
||||
$statement->expr[0] = new Expression();
|
||||
$statement->expr[0]->expr = '1';
|
||||
}
|
||||
|
||||
$countQuery = 'SELECT COUNT(*) FROM (' . $statement->build() . ' ) as cnt';
|
||||
|
||||
$unlimNumRows = $this->dbi->fetchValue($countQuery);
|
||||
if ($unlimNumRows === false) {
|
||||
$unlimNumRows = 0;
|
||||
|
||||
@ -7960,6 +7960,21 @@ parameters:
|
||||
count: 1
|
||||
path: libraries/classes/Setup/Index.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property PhpMyAdmin\\\\SqlParser\\\\Statement\\:\\:\\$expr\\.$#"
|
||||
count: 2
|
||||
path: libraries/classes/Sql.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property PhpMyAdmin\\\\SqlParser\\\\Statement\\:\\:\\$limit\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Sql.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property PhpMyAdmin\\\\SqlParser\\\\Statement\\:\\:\\$order\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Sql.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Sql\\:\\:countQueryResults\\(\\) should return int\\|numeric\\-string but returns mixed\\.$#"
|
||||
count: 1
|
||||
@ -8100,11 +8115,6 @@ parameters:
|
||||
count: 2
|
||||
path: libraries/classes/Sql.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$list of static method PhpMyAdmin\\\\SqlParser\\\\Utils\\\\Query\\:\\:replaceClauses\\(\\) expects PhpMyAdmin\\\\SqlParser\\\\TokensList, PhpMyAdmin\\\\SqlParser\\\\TokensList\\|null given\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Sql.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\Sql\\:\\:handleSortOrder\\(\\) expects string, string\\|null given\\.$#"
|
||||
count: 1
|
||||
|
||||
@ -2874,9 +2874,15 @@
|
||||
<MixedOperand occurrences="1">
|
||||
<code>$GLOBALS['biggest_max_file_size']</code>
|
||||
</MixedOperand>
|
||||
<PossiblyInvalidArgument occurrences="1">
|
||||
<PossiblyInvalidArgument occurrences="3">
|
||||
<code>$GLOBALS['current_result']</code>
|
||||
<code>$_GET['where_clause']</code>
|
||||
<code>$_GET['where_clause_signature']</code>
|
||||
</PossiblyInvalidArgument>
|
||||
<PossiblyInvalidCast occurrences="2">
|
||||
<code>$_GET['where_clause']</code>
|
||||
<code>$_GET['where_clause_signature']</code>
|
||||
</PossiblyInvalidCast>
|
||||
<PossiblyNullArgument occurrences="2">
|
||||
<code>$GLOBALS['text_dir']</code>
|
||||
<code>$isUpload</code>
|
||||
@ -2884,6 +2890,9 @@
|
||||
<TypeDoesNotContainType occurrences="1">
|
||||
<code>$GLOBALS['biggest_max_file_size'] > 0</code>
|
||||
</TypeDoesNotContainType>
|
||||
<UnusedVariable occurrences="1">
|
||||
<code>$where_clause</code>
|
||||
</UnusedVariable>
|
||||
</file>
|
||||
<file src="libraries/classes/Controllers/Table/ChangeRowsController.php">
|
||||
<MixedAssignment occurrences="2">
|
||||
@ -7594,14 +7603,18 @@
|
||||
</MixedOperand>
|
||||
<MixedReturnStatement occurrences="1"/>
|
||||
<MoreSpecificReturnType occurrences="1"/>
|
||||
<PossiblyInvalidArgument occurrences="2">
|
||||
<PossiblyInvalidArgument occurrences="4">
|
||||
<code>$_GET['sql_query']</code>
|
||||
<code>$_GET['sql_signature']</code>
|
||||
<code>$whereClause</code>
|
||||
<code>$whereClause</code>
|
||||
</PossiblyInvalidArgument>
|
||||
<PossiblyInvalidArrayOffset occurrences="1">
|
||||
<code>$_POST['fields']['multi_edit']</code>
|
||||
</PossiblyInvalidArrayOffset>
|
||||
<PossiblyInvalidCast occurrences="1">
|
||||
<PossiblyInvalidCast occurrences="3">
|
||||
<code>$_GET['sql_query']</code>
|
||||
<code>$_GET['sql_signature']</code>
|
||||
<code>$whereClause</code>
|
||||
</PossiblyInvalidCast>
|
||||
<PossiblyInvalidOperand occurrences="1">
|
||||
@ -12175,6 +12188,11 @@
|
||||
<code>$row['#']</code>
|
||||
</PossiblyNullOperand>
|
||||
</file>
|
||||
<file src="libraries/classes/Server/Status/Processes.php">
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>0 !== --$sortableColCount</code>
|
||||
</RedundantCondition>
|
||||
</file>
|
||||
<file src="libraries/classes/Session.php">
|
||||
<MixedArgument occurrences="3">
|
||||
<code>$config->getCookie('phpMyAdmin')</code>
|
||||
@ -12276,7 +12294,7 @@
|
||||
<LessSpecificReturnStatement occurrences="1">
|
||||
<code>$unlimNumRows</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MixedArgument occurrences="11">
|
||||
<MixedArgument occurrences="12">
|
||||
<code>$columns[$indexColumnName]['Extra']</code>
|
||||
<code>$extraData['error']</code>
|
||||
<code>$fieldInfoResult[0]['Type']</code>
|
||||
@ -12285,6 +12303,7 @@
|
||||
<code>$oneResult['Duration']</code>
|
||||
<code>$oneResult['Status']</code>
|
||||
<code>$sortCol</code>
|
||||
<code>$statement->expr</code>
|
||||
<code>$unlimNumRows</code>
|
||||
<code>$unlimNumRows</code>
|
||||
<code>Message::sanitize($warning)</code>
|
||||
@ -12311,9 +12330,10 @@
|
||||
<code>$oneResult['Status']</code>
|
||||
<code>$statementInfo->statement->where[0]</code>
|
||||
</MixedArrayAccess>
|
||||
<MixedArrayAssignment occurrences="2">
|
||||
<MixedArrayAssignment occurrences="3">
|
||||
<code>$_SESSION['tmpval']['pos']</code>
|
||||
<code>$_SESSION['tmpval']['possible_as_geometry']</code>
|
||||
<code>$statement->expr[0]</code>
|
||||
</MixedArrayAssignment>
|
||||
<MixedAssignment occurrences="16">
|
||||
<code>$maxRows</code>
|
||||
@ -12384,18 +12404,28 @@
|
||||
<PossiblyInvalidPropertyFetch occurrences="1">
|
||||
<code>$statement->altered[0]->field->column</code>
|
||||
</PossiblyInvalidPropertyFetch>
|
||||
<PossiblyNullArgument occurrences="7">
|
||||
<PossiblyNullArgument occurrences="6">
|
||||
<code>$result</code>
|
||||
<code>$row[0]</code>
|
||||
<code>$statementInfo->parser->list</code>
|
||||
<code>$statementInfo->parser->list</code>
|
||||
<code>$statementInfo->parser->list</code>
|
||||
<code>$table</code>
|
||||
<code>$tokenList</code>
|
||||
</PossiblyNullArgument>
|
||||
<RedundantCast occurrences="1">
|
||||
<code>(bool) $GLOBALS['cfg']['ShowSQL']</code>
|
||||
</RedundantCast>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$statementInfo->limit !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedPropertyAssignment occurrences="3">
|
||||
<code>$statement->expr</code>
|
||||
<code>$statement->limit</code>
|
||||
<code>$statement->order</code>
|
||||
</UndefinedPropertyAssignment>
|
||||
<UndefinedPropertyFetch occurrences="1">
|
||||
<code>$statement->expr</code>
|
||||
</UndefinedPropertyFetch>
|
||||
</file>
|
||||
<file src="libraries/classes/SqlQueryForm.php">
|
||||
<MixedArgument occurrences="1"/>
|
||||
|
||||
@ -14,9 +14,9 @@ use function class_exists;
|
||||
use function sort;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const ROOT_PATH;
|
||||
use const SORT_NATURAL;
|
||||
use const SORT_REGULAR;
|
||||
use const TEST_PATH;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Command\TwigLintCommand
|
||||
@ -42,7 +42,7 @@ class TwigLintCommandTest extends AbstractTestCase
|
||||
public function testGetTemplateContents(): void
|
||||
{
|
||||
$contents = $this->callFunction($this->command, TwigLintCommand::class, 'getTemplateContents', [
|
||||
ROOT_PATH . 'test/classes/_data/file_listing/subfolder/one.ini',
|
||||
TEST_PATH . 'test/classes/_data/file_listing/subfolder/one.ini',
|
||||
]);
|
||||
|
||||
$this->assertSame('key=value' . "\n", $contents);
|
||||
@ -50,7 +50,7 @@ class TwigLintCommandTest extends AbstractTestCase
|
||||
|
||||
public function testFindFiles(): void
|
||||
{
|
||||
$path = ROOT_PATH . 'test/classes/_data/file_listing';
|
||||
$path = TEST_PATH . 'test/classes/_data/file_listing';
|
||||
$filesFound = $this->callFunction($this->command, TwigLintCommand::class, 'findFiles', [$path]);
|
||||
|
||||
// Sort results to avoid file system test specific failures
|
||||
@ -66,7 +66,7 @@ class TwigLintCommandTest extends AbstractTestCase
|
||||
|
||||
public function testGetFilesInfo(): void
|
||||
{
|
||||
$path = ROOT_PATH . 'test/classes/_data/file_listing';
|
||||
$path = TEST_PATH . 'test/classes/_data/file_listing';
|
||||
$filesInfos = $this->callFunction($this->command, TwigLintCommand::class, 'getFilesInfo', [$path]);
|
||||
|
||||
// Sort results to avoid file system test specific failures
|
||||
@ -120,7 +120,7 @@ class TwigLintCommandTest extends AbstractTestCase
|
||||
->willReturnOnConsecutiveCalls('{{ file }}', '{{ file }');
|
||||
|
||||
$filesFound = $this->callFunction($command, TwigLintCommand::class, 'getFilesInfo', [
|
||||
ROOT_PATH . 'test/classes/_data/file_listing',
|
||||
TEST_PATH . 'test/classes/_data/file_listing',
|
||||
]);
|
||||
|
||||
$this->assertEquals([
|
||||
|
||||
@ -153,6 +153,43 @@ class InsertEditTest extends AbstractTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getFormParametersForInsertForm
|
||||
*/
|
||||
public function testGetFormParametersForInsertFormGet(): void
|
||||
{
|
||||
$where_clause = [
|
||||
'foo' => 'bar ',
|
||||
'1' => ' test',
|
||||
];
|
||||
$_GET['clause_is_unique'] = false;
|
||||
$_GET['sql_query'] = 'SELECT a';
|
||||
$_GET['sql_signature'] = Core::signSqlQuery($_GET['sql_query']);
|
||||
$GLOBALS['goto'] = 'index.php';
|
||||
|
||||
$result = $this->insertEdit->getFormParametersForInsertForm(
|
||||
'dbname',
|
||||
'tablename',
|
||||
[],
|
||||
$where_clause,
|
||||
'localhost'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'db' => 'dbname',
|
||||
'table' => 'tablename',
|
||||
'goto' => 'index.php',
|
||||
'err_url' => 'localhost',
|
||||
'sql_query' => 'SELECT a',
|
||||
'where_clause[foo]' => 'bar',
|
||||
'where_clause[1]' => 'test',
|
||||
'clause_is_unique' => false,
|
||||
],
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getWhereClauseArray
|
||||
*/
|
||||
|
||||
@ -371,9 +371,9 @@ class SqlTest extends AbstractTestCase
|
||||
164056,
|
||||
50,
|
||||
false,
|
||||
'SELECT COUNT(*) FROM (select * from game_auth_logs l join ('
|
||||
'SELECT COUNT(*) FROM (SELECT 1 FROM game_auth_logs AS `l` JOIN ('
|
||||
. ' select al.user_id, max(al.id) as id from game_auth_logs al '
|
||||
. 'where al.successfull = 1 group by al.user_id ) last_log on last_log.id = l.id'
|
||||
. 'where al.successfull = 1 group by al.user_id ) AS `last_log` ON last_log.id = l.id'
|
||||
. ' ) as cnt',
|
||||
],
|
||||
'join on SELECT results with alias.*' => [
|
||||
@ -385,9 +385,9 @@ class SqlTest extends AbstractTestCase
|
||||
267,
|
||||
50,
|
||||
false,
|
||||
'SELECT COUNT(*) FROM (select l.* from game_auth_logs l join ('
|
||||
'SELECT COUNT(*) FROM (SELECT 1 FROM game_auth_logs AS `l` JOIN ('
|
||||
. ' select al.user_id, max(al.id) as id from game_auth_logs al '
|
||||
. 'where al.successfull = 1 group by al.user_id ) last_log on last_log.id = l.id'
|
||||
. 'where al.successfull = 1 group by al.user_id ) AS `last_log` ON last_log.id = l.id'
|
||||
. ' ) as cnt',
|
||||
],
|
||||
[
|
||||
|
||||
@ -2742,17 +2742,17 @@ class DbiDummy implements DbiExtension
|
||||
'result' => [['hostname', 'username', 'password']],
|
||||
],
|
||||
[
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT * FROM company_users WHERE not_working_count != 0 ) as cnt',
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT 1 FROM company_users WHERE not_working_count != 0 ) as cnt',
|
||||
'result' => false,
|
||||
],
|
||||
[
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT * FROM company_users ) as cnt',
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT 1 FROM company_users ) as cnt',
|
||||
'result' => [
|
||||
[4],
|
||||
],
|
||||
],
|
||||
[
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT * FROM company_users WHERE working_count = 0 ) as cnt',
|
||||
'query' => 'SELECT COUNT(*) FROM (SELECT 1 FROM company_users WHERE working_count = 0 ) as cnt',
|
||||
'result' => [
|
||||
[15],
|
||||
],
|
||||
@ -2765,8 +2765,8 @@ class DbiDummy implements DbiExtension
|
||||
],
|
||||
[
|
||||
'query' => 'SELECT COUNT(*) FROM ('
|
||||
. 'SELECT *, 1, (SELECT COUNT(*) FROM tbl1) as c1, '
|
||||
. '(SELECT 1 FROM tbl2) as c2 FROM company_users WHERE subquery_case = 0 ) as cnt',
|
||||
. 'SELECT *, 1, (SELECT COUNT(*) FROM tbl1) AS `c1`, '
|
||||
. '(SELECT 1 FROM tbl2) AS `c2` FROM company_users WHERE subquery_case = 0 ) as cnt',
|
||||
'result' => [
|
||||
[42],
|
||||
],
|
||||
|
||||
@ -65,7 +65,7 @@ class ThemeTest extends AbstractTestCase
|
||||
*/
|
||||
public function testCheckImgPathIncorrect(): void
|
||||
{
|
||||
$this->object->setPath(ROOT_PATH . 'test/classes/_data/incorrect_theme');
|
||||
$this->object->setPath(TEST_PATH . 'test/classes/_data/incorrect_theme');
|
||||
$this->assertFalse(
|
||||
$this->object->loadInfo(),
|
||||
'Theme name is not properly set'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user