diff --git a/libraries/classes/Server/Privileges.php b/libraries/classes/Server/Privileges.php
index 70e985f4e7..44c9dc0f32 100644
--- a/libraries/classes/Server/Privileges.php
+++ b/libraries/classes/Server/Privileges.php
@@ -51,6 +51,7 @@ use function sprintf;
use function str_contains;
use function str_replace;
use function strlen;
+use function strtr;
use function trim;
use function uksort;
@@ -132,16 +133,20 @@ class Privileges
*
* @return string the generated condition
*/
- public function rangeOfUsers($initial = '')
+ public function rangeOfUsers(?string $initial = null)
{
- // strtolower() is used because the User field
- // might be BINARY, so LIKE would be case sensitive
- if ($initial === null || $initial === '') {
+ if ($initial === null) {
return '';
}
+ if ($initial === '') {
+ return " WHERE `User` = ''";
+ }
+
$like = strtr($initial, ['_' => '\\_', '%' => '\\%', '\\' => '\\\\']) . '%';
+ // strtolower() is used because the User field
+ // might be BINARY, so LIKE would be case sensitive
return " WHERE `User` LIKE '"
. $this->dbi->escapeString($like) . "'"
. " OR `User` LIKE '"
diff --git a/templates/server/privileges/initials_row.twig b/templates/server/privileges/initials_row.twig
index 622310d65b..40315e66d1 100644
--- a/templates/server/privileges/initials_row.twig
+++ b/templates/server/privileges/initials_row.twig
@@ -4,7 +4,13 @@
{% if tmp_initial is not same as(null) %}
{% if initial_was_found %}
- {{ tmp_initial }}
+
+ {% if tmp_initial is same as('') %}
+ {{ 'Any' |trans }}
+ {% else %}
+ {{ tmp_initial }}
+ {% endif %}
+
{% else %}
diff --git a/test/classes/Server/PrivilegesTest.php b/test/classes/Server/PrivilegesTest.php
index 52df46922b..b028cfaf51 100644
--- a/test/classes/Server/PrivilegesTest.php
+++ b/test/classes/Server/PrivilegesTest.php
@@ -28,6 +28,7 @@ use function __;
use function _pgettext;
use function htmlspecialchars;
use function implode;
+use function preg_quote;
/**
* @covers \PhpMyAdmin\Server\Privileges
@@ -244,6 +245,9 @@ class PrivilegesTest extends AbstractTestCase
$ret = $this->serverPrivileges->rangeOfUsers('%');
$this->assertEquals(' WHERE `User` LIKE \'\\%%\' OR `User` LIKE \'\\%%\'', $ret);
+ $ret = $this->serverPrivileges->rangeOfUsers('');
+ $this->assertEquals(" WHERE `User` = ''", $ret);
+
$ret = $this->serverPrivileges->rangeOfUsers();
$this->assertEquals('', $ret);
}
@@ -1684,7 +1688,7 @@ class PrivilegesTest extends AbstractTestCase
->will($this->returnValue($resultStub));
$resultStub->expects($this->atLeastOnce())
->method('fetchRow')
- ->will($this->onConsecutiveCalls(['-'], ['"'], ['%'], ['\\'], []));
+ ->will($this->onConsecutiveCalls(['-'], ['"'], ['%'], ['\\'], [''], []));
$this->serverPrivileges->dbi = $dbi;
$actual = $this->serverPrivileges->getHtmlForInitials();
@@ -1696,20 +1700,26 @@ class PrivilegesTest extends AbstractTestCase
'Z',
$actual
);
- $this->assertStringContainsString(
- '-',
+ $this->assertMatchesRegularExpression(
+ '/\s*-\s*<\/a>/',
$actual
);
- $this->assertStringContainsString(
- '"',
+ $this->assertMatchesRegularExpression(
+ '/\s*"\s*<\/a>/',
$actual
);
- $this->assertStringContainsString(
- '%',
+ $this->assertMatchesRegularExpression(
+ '/\s*%\s*<\/a>/',
$actual
);
- $this->assertStringContainsString(
- '\\',
+ $this->assertMatchesRegularExpression(
+ '/\s*\\\\\s*<\/a>/',
+ $actual
+ );
+ $this->assertMatchesRegularExpression(
+ '/\s*' .
+ '' . preg_quote(__('Any')) . '<\/span>' .
+ '\s*<\/a>/',
$actual
);
$this->assertStringContainsString('Show all', $actual);