Skip to content

Commit

Permalink
Merge pull request phpmyadmin#19552 from kamil-tekiela/Fix-default-va…
Browse files Browse the repository at this point in the history
…lues

Fix default values
  • Loading branch information
MauricioFauth authored Jan 30, 2025
2 parents b0d985c + d5e9a91 commit a7af119
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 52 deletions.
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8935,7 +8935,7 @@ parameters:
path: src/InsertEdit.php

-
message: '#^Parameter \#1 \$defaultValue of method PhpMyAdmin\\InsertEdit\:\:getSpecialCharsForInsertingMode\(\) expects string\|null, mixed given\.$#'
message: '#^Parameter \#1 \$defaultValue of method PhpMyAdmin\\InsertEdit\:\:getDefaultValue\(\) expects string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/InsertEdit.php
Expand Down
5 changes: 4 additions & 1 deletion src/Dbal/DatabaseInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,10 @@ private function convertToColumns(array $fields): array
$column['Collation'],
$column['Null'] === 'YES',
$column['Key'],
$column['Default'],
// null means lack of default value, 'NULL' means default value is NULL
$column['Default'] === null || $column['Default'] === 'NULL'

Check warning on line 896 in src/Dbal/DatabaseInterface.php

View workflow job for this annotation

GitHub Actions / Infection (8.2, ubuntu-latest)

Escaped Mutant for Mutator "Identical": --- Original +++ New @@ @@ $column['Null'] === 'YES', $column['Key'], // null means lack of default value, 'NULL' means default value is NULL - $column['Default'] === null || $column['Default'] === 'NULL' ? null : Util::unquoteDefaultValue($column['Default']), + $column['Default'] === null || $column['Default'] !== 'NULL' ? null : Util::unquoteDefaultValue($column['Default']), $column['Extra'], $column['Privileges'], $column['Comment']

Check warning on line 896 in src/Dbal/DatabaseInterface.php

View workflow job for this annotation

GitHub Actions / Infection (8.2, ubuntu-latest)

Escaped Mutant for Mutator "LogicalOrAllSubExprNegation": --- Original +++ New @@ @@ $column['Null'] === 'YES', $column['Key'], // null means lack of default value, 'NULL' means default value is NULL - $column['Default'] === null || $column['Default'] === 'NULL' ? null : Util::unquoteDefaultValue($column['Default']), + !($column['Default'] === null) || !($column['Default'] === 'NULL') ? null : Util::unquoteDefaultValue($column['Default']), $column['Extra'], $column['Privileges'], $column['Comment']
? null
: Util::unquoteDefaultValue($column['Default']),
$column['Extra'],
$column['Privileges'],
$column['Comment'],
Expand Down
28 changes: 12 additions & 16 deletions src/InsertEdit.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@
use function preg_match;
use function preg_replace;
use function str_contains;
use function str_ends_with;
use function str_replace;
use function str_starts_with;
use function stripcslashes;
use function stripslashes;
use function substr;
use function trim;

use const ENT_COMPAT;
Expand Down Expand Up @@ -766,7 +763,7 @@ private function getSpecialCharsAndBackupFieldForExistingRow(
/**
* display default values
*/
private function getSpecialCharsForInsertingMode(
private function getDefaultValue(
string|null $defaultValue,
string $trueType,
): string {
Expand All @@ -775,19 +772,18 @@ private function getSpecialCharsForInsertingMode(
}

if ($trueType === 'bit') {
$specialChars = Util::convertBitDefaultValue($defaultValue);
} elseif ($trueType === 'timestamp' || $trueType === 'datetime' || $trueType === 'time') {
$specialChars = Util::addMicroseconds($defaultValue);
} elseif ($trueType === 'binary' || $trueType === 'varbinary') {
$specialChars = bin2hex($defaultValue);
} elseif (str_ends_with($trueType, 'text')) {
$textDefault = substr($defaultValue, 1, -1);
$specialChars = htmlspecialchars(stripcslashes($textDefault !== '' ? $textDefault : $defaultValue));
} else {
$specialChars = htmlspecialchars($defaultValue);
return Util::convertBitDefaultValue($defaultValue);
}

if ($trueType === 'timestamp' || $trueType === 'datetime' || $trueType === 'time') {
return Util::addMicroseconds($defaultValue);
}

if ($trueType === 'binary' || $trueType === 'varbinary') {
return bin2hex($defaultValue);
}

return $specialChars;
return $defaultValue;
}

/**
Expand Down Expand Up @@ -1572,7 +1568,7 @@ private function getHtmlForInsertEditFormColumn(

$realNullValue = $defaultValue === null;
$data = (string) $defaultValue;
$specialChars = $this->getSpecialCharsForInsertingMode($defaultValue, $column->trueType);
$specialChars = htmlspecialchars($this->getDefaultValue($defaultValue, $column->trueType));
$specialCharsEncoded = Util::duplicateFirstNewline($specialChars);
$backupField = '';
}
Expand Down
13 changes: 2 additions & 11 deletions src/Table/ColumnsDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
use function preg_quote;
use function preg_replace;
use function rtrim;
use function str_ends_with;
use function stripcslashes;
use function substr;
use function trim;

/**
Expand Down Expand Up @@ -186,7 +183,6 @@ public function displayForm(
}

$columnMetaDefault = self::decorateColumnMetaDefault(
$columnMeta['Type'],
$columnMeta['Default'],
$columnMeta['Null'] === 'YES',
);
Expand Down Expand Up @@ -365,9 +361,9 @@ public function displayForm(
/**
* Set default type and default value according to the column metadata
*
* @return array{DefaultType:string, DefaultValue: string, Default?: string}
* @return array{DefaultType:string, DefaultValue: string}
*/
public static function decorateColumnMetaDefault(string $type, string|null $default, bool $isNull): array
public static function decorateColumnMetaDefault(string|null $default, bool $isNull): array
{
$metaDefault = ['DefaultType' => 'USER_DEFINED', 'DefaultValue' => ''];

Expand All @@ -389,11 +385,6 @@ public static function decorateColumnMetaDefault(string $type, string|null $defa
default:
$metaDefault['DefaultValue'] = $default;

if (str_ends_with($type, 'text')) {
$textDefault = substr($default, 1, -1);
$metaDefault['Default'] = stripcslashes($textDefault);
}

break;
}

Expand Down
10 changes: 10 additions & 0 deletions src/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
use function strrev;
use function strtolower;
use function strtr;
use function substr;
use function trim;
use function uksort;

Expand Down Expand Up @@ -2013,4 +2014,13 @@ public static function getUploadSizeInBytes(): int

return $size;
}

public static function unquoteDefaultValue(string $value): string
{
if (! str_starts_with($value, "'")) {
return $value;
}

return strtr(substr($value, 1, -1), ["''" => "'", "\\'" => "'", '\\\\' => '\\']);
}
}
14 changes: 7 additions & 7 deletions tests/unit/InsertEditTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1182,10 +1182,10 @@ public function testGetSpecialCharsAndBackupFieldForExistingRow(): void
}

/**
* Test for getSpecialCharsForInsertingMode
* Test for getDefaultValue
*/
#[DataProvider('providerForTestGetSpecialCharsForInsertingMode')]
public function testGetSpecialCharsForInsertingMode(
public function testGetDefaultValue(
string|null $defaultValue,
string $trueType,
string $expected,
Expand All @@ -1198,15 +1198,15 @@ public function testGetSpecialCharsForInsertingMode(
$result = $this->callFunction(
$this->insertEdit,
InsertEdit::class,
'getSpecialCharsForInsertingMode',
'getDefaultValue',
[$defaultValue, $trueType],
);

self::assertSame($expected, $result);
}

/**
* Data provider for test getSpecialCharsForInsertingMode()
* Data provider for test getDefaultValue()
*
* @return array<string, array{string|null, string, string}>
*/
Expand Down Expand Up @@ -1246,17 +1246,17 @@ public static function providerForTestGetSpecialCharsForInsertingMode(): array
'any text with escape text default' => [
'"lorem\"ipsem"',
'text',
'lorem&quot;ipsem',
'"lorem\"ipsem"',
],
'varchar with html special chars' => [
'hello world<br><b>lorem</b> ipsem',
'varchar',
'hello world&lt;br&gt;&lt;b&gt;lorem&lt;/b&gt; ipsem',
'hello world<br><b>lorem</b> ipsem',
],
'text with html special chars' => [
'\'</textarea><script>alert(1)</script>\'',
'text',
'&lt;/textarea&gt;&lt;script&gt;alert(1)&lt;/script&gt;',
'\'</textarea><script>alert(1)</script>\'',
],
];
}
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/Stubs/DbiDummy.php
Original file line number Diff line number Diff line change
Expand Up @@ -1681,9 +1681,9 @@ private function init(): void
. ' WHERE `TABLE_SCHEMA` COLLATE utf8_bin = \'test_db\' AND `TABLE_NAME` COLLATE utf8_bin = \'test_table\'',
'columns' => ['Field', 'Type', 'Collation', 'Null', 'Key', 'Default', 'Extra', 'Privileges', 'Comment'],
'result' => [
['id', 'int(11)', null, 'NO', 'PRI', 'NULL', 'auto_increment', '', ''],
['name', 'varchar(20)', null, 'NO', '', 'NULL', '', '', ''],
['datetimefield', 'datetime', null, 'NO', '', 'NULL', '', '', ''],
['id', 'int(11)', null, 'NO', 'PRI', "'NULL'", 'auto_increment', '', ''],
['name', 'varchar(20)', null, 'NO', '', "'NULL'", '', '', ''],
['datetimefield', 'datetime', null, 'NO', '', "'NULL'", '', '', ''],
],
],
[
Expand Down
17 changes: 4 additions & 13 deletions tests/unit/Table/ColumnsDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,68 +224,59 @@ public function testDisplayForm(): void
*/
#[DataProvider('providerColumnMetaDefault')]
public function testDecorateColumnMetaDefault(
string $type,
string|null $default,
bool $isNull,
array $expected,
): void {
$result = ColumnsDefinition::decorateColumnMetaDefault($type, $default, $isNull);
$result = ColumnsDefinition::decorateColumnMetaDefault($default, $isNull);

self::assertEquals($expected, $result);
}

/**
* Data provider for testDecorateColumnMetaDefault
*
* @psalm-return array<string, array{string, string|null, bool, array<string, string>}>
* @psalm-return array<string, array{string|null, bool, array<string, string>}>
*/
public static function providerColumnMetaDefault(): array
{
return [
'when Default is null and Null is YES' => [
'',
null,
true,
['DefaultType' => 'NULL', 'DefaultValue' => ''],
],
'when Default is null and Null is NO' => [
'',
null,
false,
['DefaultType' => 'NONE', 'DefaultValue' => ''],
],
'when Default is CURRENT_TIMESTAMP' => [
'',
'CURRENT_TIMESTAMP',
false,
['DefaultType' => 'CURRENT_TIMESTAMP', 'DefaultValue' => ''],
],
'when Default is current_timestamp' => [
'',
'current_timestamp()',
false,
['DefaultType' => 'CURRENT_TIMESTAMP', 'DefaultValue' => ''],
],
'when Default is UUID' => [
'',
'UUID',
false,
['DefaultType' => 'UUID', 'DefaultValue' => ''],
],
'when Default is uuid()' => [
'',
'uuid()',
false,
['DefaultType' => 'UUID', 'DefaultValue' => ''],
],
'when Default is anything else and Type is text' => [
'text',
'"some\/thing"',
'"some/thing"',
false,
['Default' => 'some/thing', 'DefaultType' => 'USER_DEFINED', 'DefaultValue' => '"some\/thing"'],
['DefaultType' => 'USER_DEFINED', 'DefaultValue' => '"some/thing"'],
],
'when Default is anything else and Type is not text' => [
'something',
'"some\/thing"',
false,
['DefaultType' => 'USER_DEFINED', 'DefaultValue' => '"some\/thing"'],
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/UtilTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1551,4 +1551,17 @@ public static function providerForTestGetValueByKey(): iterable
'def',
];
}

public function testUnquoteDefaultValue(): void
{
self::assertSame('foo', Util::unquoteDefaultValue('foo'));
self::assertSame('"foo"', Util::unquoteDefaultValue('"foo"'));
self::assertSame('`foo`', Util::unquoteDefaultValue('`foo`'));
self::assertSame('foo', Util::unquoteDefaultValue('\'foo\''));
self::assertSame('', Util::unquoteDefaultValue('\'\''));
self::assertSame('\'', Util::unquoteDefaultValue('\'\'\'\''));
self::assertSame('q\'q', Util::unquoteDefaultValue('\'q\'q\''));
self::assertSame('s\\s', Util::unquoteDefaultValue('\'s\\\\s\''));
self::assertSame('sq\'sq', Util::unquoteDefaultValue('\'sq\\\'sq\''));
}
}

0 comments on commit a7af119

Please sign in to comment.