diff --git a/composer.json b/composer.json index f3b75fa84be9..e9e27332478d 100644 --- a/composer.json +++ b/composer.json @@ -58,6 +58,7 @@ "symfony/polyfill-ctype": "^1.17.0", "symfony/polyfill-mbstring": "^1.17.0", "twig/twig": "^3.0.1", + "webmozart/assert": "^1.10", "williamdes/mariadb-mysql-kbs": "^1.2" }, "conflict": { diff --git a/libraries/classes/Controllers/Table/PartitionController.php b/libraries/classes/Controllers/Table/PartitionController.php index bb8f486dda2b..5c5eff8652db 100644 --- a/libraries/classes/Controllers/Table/PartitionController.php +++ b/libraries/classes/Controllers/Table/PartitionController.php @@ -4,10 +4,13 @@ namespace PhpMyAdmin\Controllers\Table; +use PhpMyAdmin\Dbal\DatabaseName; use PhpMyAdmin\Html\Generator; +use PhpMyAdmin\Message; use PhpMyAdmin\Response; use PhpMyAdmin\Table\Partition; use PhpMyAdmin\Template; +use Throwable; use function strlen; @@ -36,7 +39,14 @@ public function analyze(): void return; } - [$rows, $query] = $this->model->analyze($this->db, $this->table, $partitionName); + try { + [$rows, $query] = $this->model->analyze(new DatabaseName($this->db), $this->table, $partitionName); + } catch (Throwable $e) { + $message = Message::error($e->getMessage()); + $this->response->addHTML($message->getDisplay()); + + return; + } $message = Generator::getMessage( __('Your SQL query has been executed successfully.'), diff --git a/libraries/classes/Dbal/DatabaseName.php b/libraries/classes/Dbal/DatabaseName.php new file mode 100644 index 000000000000..db4ec7d762ec --- /dev/null +++ b/libraries/classes/Dbal/DatabaseName.php @@ -0,0 +1,41 @@ +name = $name; + } + + public function getName(): string + { + return $this->name; + } + + public function __toString(): string + { + return $this->name; + } +} diff --git a/libraries/classes/Table/Partition.php b/libraries/classes/Table/Partition.php index 30c6b49b4f5e..3875869d8386 100644 --- a/libraries/classes/Table/Partition.php +++ b/libraries/classes/Table/Partition.php @@ -5,6 +5,7 @@ namespace PhpMyAdmin\Table; use PhpMyAdmin\DatabaseInterface; +use PhpMyAdmin\Dbal\DatabaseName; use PhpMyAdmin\Util; use function sprintf; @@ -19,7 +20,7 @@ public function __construct(DatabaseInterface $dbi) $this->dbi = $dbi; } - public function analyze(string $db, string $table, string $partition): array + public function analyze(DatabaseName $db, string $table, string $partition): array { $query = sprintf( 'ALTER TABLE %s ANALYZE PARTITION %s;', @@ -27,7 +28,7 @@ public function analyze(string $db, string $table, string $partition): array Util::backquote($partition) ); - $this->dbi->selectDb($db); + $this->dbi->selectDb($db->getName()); $result = $this->dbi->fetchResult($query); $rows = []; diff --git a/test/classes/Dbal/DatabaseNameTest.php b/test/classes/Dbal/DatabaseNameTest.php new file mode 100644 index 000000000000..bda469962f8d --- /dev/null +++ b/test/classes/Dbal/DatabaseNameTest.php @@ -0,0 +1,45 @@ +expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Expected a different value than "".'); + new DatabaseName(''); + } + + public function testNameWithTrailingWhitespace(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Expected a value not to end with " ". Got: "a "'); + new DatabaseName('a '); + } + + public function testLongName(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage( + 'Expected a value to contain at most 64 characters. Got: ' + . '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"' + ); + new DatabaseName(str_repeat('a', 65)); + } + + public function testValidName(): void + { + $name = new DatabaseName('name'); + $this->assertEquals('name', $name->getName()); + $this->assertEquals('name', (string) $name); + } +}