Issue #3379102 by phenaproxima, Wim Leers, borisson_: Add validation constraint to type: label + type: text: disallow control characters
parent
ded815fbe0
commit
3a661cf7be
|
@ -64,13 +64,11 @@ label:
|
|||
translatable: true
|
||||
constraints:
|
||||
Regex:
|
||||
# Forbid any kind of line ending:
|
||||
# - Windows: `\r\n`
|
||||
# - old macOS: `\r`
|
||||
# - *nix: `\n`
|
||||
pattern: '/(\r\n|\r|\n)/'
|
||||
# Forbid any kind of control character.
|
||||
# @see https://stackoverflow.com/a/66587087
|
||||
pattern: '/([^\PC])/u'
|
||||
match: false
|
||||
message: 'Labels are not allowed to span multiple lines.'
|
||||
message: 'Labels are not allowed to span multiple lines or contain control characters.'
|
||||
|
||||
required_label:
|
||||
type: label
|
||||
|
@ -93,6 +91,18 @@ text:
|
|||
type: string
|
||||
label: 'Text'
|
||||
translatable: true
|
||||
constraints:
|
||||
Regex:
|
||||
# Disallow all control characters except for tabs (ASCII 9, 0x09) as well
|
||||
# as carriage returns (ASCII 13, 0x0D) and line feeds (ASCII 10, 0x0A),
|
||||
# which are used for line endings:
|
||||
# - Windows: `\r\n`
|
||||
# - old macOS: `\r`
|
||||
# - *nix: `\n`
|
||||
# @see https://stackoverflow.com/a/66587087
|
||||
pattern: '/([^\PC\x09\x0a\x0d])/u'
|
||||
match: false
|
||||
message: 'Text is not allowed to contain control characters, only visible characters.'
|
||||
|
||||
# A UUID.
|
||||
uuid:
|
||||
|
|
|
@ -86,7 +86,7 @@ class BlockValidationTest extends ConfigEntityValidationTestBase {
|
|||
// key, it is impossible for the generic ::testLabelValidation()
|
||||
// implementation in the base class to know at which property to expect a
|
||||
// validation error. Hence it is hardcoded in this case.
|
||||
$this->assertValidationErrors(['settings.label' => "Labels are not allowed to span multiple lines."]);
|
||||
$this->assertValidationErrors(['settings.label' => "Labels are not allowed to span multiple lines or contain control characters."]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -119,6 +119,15 @@ views.field.numeric:
|
|||
format_plural_string:
|
||||
type: plural_label
|
||||
label: 'Plural variants'
|
||||
constraints:
|
||||
Regex:
|
||||
# Normally, labels cannot contain invisible control characters. In this particular
|
||||
# case, an invisible character (ASCII 3, 0x03) is used to encode translation
|
||||
# information, so carve out an exception for that only.
|
||||
# @see \Drupal\views\Plugin\views\field\NumericField
|
||||
pattern: '/([^\PC\x03])/u'
|
||||
match: false
|
||||
message: 'Labels are not allowed to span multiple lines or contain control characters.'
|
||||
prefix:
|
||||
type: label
|
||||
label: 'Prefix'
|
||||
|
|
|
@ -318,7 +318,7 @@ abstract class ConfigEntityValidationTestBase extends KernelTestBase {
|
|||
}
|
||||
|
||||
static::setLabel($this->entity, "Multi\nLine");
|
||||
$this->assertValidationErrors([$this->entity->getEntityType()->getKey('label') => "Labels are not allowed to span multiple lines."]);
|
||||
$this->assertValidationErrors([$this->entity->getEntityType()->getKey('label') => "Labels are not allowed to span multiple lines or contain control characters."]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -72,4 +72,81 @@ class SimpleConfigValidationTest extends KernelTestBase {
|
|||
$this->assertSame("'invalid_key' is not a supported key.", (string) $violations[0]->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testSpecialCharacters().
|
||||
*
|
||||
* @return array[]
|
||||
* The test cases.
|
||||
*/
|
||||
public function providerSpecialCharacters(): array {
|
||||
$data = [];
|
||||
|
||||
for ($code_point = 0; $code_point < 32; $code_point++) {
|
||||
$data["label $code_point"] = [
|
||||
'system.site',
|
||||
'name',
|
||||
mb_chr($code_point),
|
||||
'Labels are not allowed to span multiple lines or contain control characters.',
|
||||
];
|
||||
$data["text $code_point"] = [
|
||||
'system.maintenance',
|
||||
'message',
|
||||
mb_chr($code_point),
|
||||
'Text is not allowed to contain control characters, only visible characters.',
|
||||
];
|
||||
}
|
||||
// Line feeds (ASCII 10) and carriage returns (ASCII 13) are used to create
|
||||
// new lines, so they are allowed in text data, along with tabs (ASCII 9).
|
||||
$data['text 9'][3] = $data['text 10'][3] = $data['text 13'][3] = NULL;
|
||||
|
||||
// Ensure emoji are allowed.
|
||||
$data['emoji in label'] = [
|
||||
'system.site',
|
||||
'name',
|
||||
'😎',
|
||||
NULL,
|
||||
];
|
||||
$data['emoji in text'] = [
|
||||
'system.maintenance',
|
||||
'message',
|
||||
'🤓',
|
||||
NULL,
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that special characters are not allowed in labels or text data.
|
||||
*
|
||||
* @param string $config_name
|
||||
* The name of the simple config to test with.
|
||||
* @param string $property
|
||||
* The config property in which to embed a control character.
|
||||
* @param string $character
|
||||
* A special character to embed.
|
||||
* @param string|null $expected_error_message
|
||||
* The expected validation error message, if any.
|
||||
*
|
||||
* @dataProvider providerSpecialCharacters
|
||||
*/
|
||||
public function testSpecialCharacters(string $config_name, string $property, string $character, ?string $expected_error_message): void {
|
||||
$config = $this->config($config_name)
|
||||
->set($property, "This has a special character: $character");
|
||||
|
||||
$violations = $this->container->get('config.typed')
|
||||
->createFromNameAndData($config->getName(), $config->get())
|
||||
->validate();
|
||||
|
||||
if ($expected_error_message === NULL) {
|
||||
$this->assertCount(0, $violations);
|
||||
}
|
||||
else {
|
||||
$code_point = mb_ord($character);
|
||||
$this->assertCount(1, $violations, "Character $code_point did not raise a constraint violation.");
|
||||
$this->assertSame($property, $violations[0]->getPropertyPath());
|
||||
$this->assertSame($expected_error_message, (string) $violations[0]->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue