feature #26484 [Validator] String normalization options for string-based validators (renan-taranto)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Validator] String normalization options for string-based validators

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #26239
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/9433

Todo:
- [x] Document the new options
- [x] Update Doc PR

Add trimming options to the string constraints.

Commits
-------

708d759b8d [Validator] String normalization options for string-based validators
This commit is contained in:
Fabien Potencier 2019-03-31 13:55:59 +02:00
commit b14d5cd358
29 changed files with 547 additions and 2 deletions

View File

@ -8,8 +8,13 @@ CHANGELOG
* added UATP cards support to `CardSchemeValidator`
* added option `allowNull` to NotBlank constraint
* added `Json` constraint
<<<<<<< HEAD
* added `Unique` constraint
=======
* added a new `normalizer` option to the string constraints and to the `NotBlank` constraint
>>>>>>> pull/26484
4.2.0
-----

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
use Egulias\EmailValidator\EmailValidator as StrictEmailValidator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
use Symfony\Component\Validator\Exception\LogicException;
/**
@ -73,6 +74,7 @@ class Email extends Constraint
*/
public $strict;
public $mode;
public $normalizer;
public function __construct($options = null)
{
@ -89,7 +91,7 @@ class Email extends Constraint
}
if (\is_array($options) && \array_key_exists('mode', $options) && !\in_array($options['mode'], self::$validationModes, true)) {
throw new \InvalidArgumentException('The "mode" parameter value is not valid.');
throw new InvalidArgumentException('The "mode" parameter value is not valid.');
}
parent::__construct($options);
@ -98,5 +100,9 @@ class Email extends Constraint
// throw new LogicException(sprintf('The "egulias/email-validator" component is required to use the "%s" constraint in strict mode.', __CLASS__));
@trigger_error(sprintf('Using the "%s" constraint in strict mode without the "egulias/email-validator" component installed is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED);
}
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -81,6 +81,10 @@ class EmailValidator extends ConstraintValidator
$value = (string) $value;
if (null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
if (null !== $constraint->strict) {
@trigger_error(sprintf('The %s::$strict property is deprecated since Symfony 4.1. Use %s::mode="%s" instead.', Email::class, Email::class, Email::VALIDATION_MODE_STRICT), E_USER_DEPRECATED);

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* Validates that a value is a valid IP address.
@ -72,6 +73,8 @@ class Ip extends Constraint
public $message = 'This is not a valid IP address.';
public $normalizer;
/**
* {@inheritdoc}
*/
@ -82,5 +85,9 @@ class Ip extends Constraint
if (!\in_array($this->version, self::$versions)) {
throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s"', implode('", "', self::$versions)));
}
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -43,6 +43,10 @@ class IpValidator extends ConstraintValidator
$value = (string) $value;
if (null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
switch ($constraint->version) {
case Ip::V4:
$flag = FILTER_FLAG_IPV4;

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
use Symfony\Component\Validator\Exception\MissingOptionsException;
/**
@ -39,6 +40,7 @@ class Length extends Constraint
public $max;
public $min;
public $charset = 'UTF-8';
public $normalizer;
public function __construct($options = null)
{
@ -54,5 +56,9 @@ class Length extends Constraint
if (null === $this->min && null === $this->max) {
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']);
}
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -40,6 +40,10 @@ class LengthValidator extends ConstraintValidator
$stringValue = (string) $value;
if (null !== $constraint->normalizer) {
$stringValue = ($constraint->normalizer)($stringValue);
}
if (!$invalidCharset = !@mb_check_encoding($stringValue, $constraint->charset)) {
$length = mb_strlen($stringValue, $constraint->charset);
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* @Annotation
@ -30,4 +31,14 @@ class NotBlank extends Constraint
public $message = 'This value should not be blank.';
public $allowNull = false;
public $normalizer;
public function __construct($options = null)
{
parent::__construct($options);
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -34,6 +34,10 @@ class NotBlankValidator extends ConstraintValidator
return;
}
if (\is_string($value) && null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
if (false === $value || (empty($value) && '0' != $value)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* @Annotation
@ -31,6 +32,16 @@ class Regex extends Constraint
public $pattern;
public $htmlPattern;
public $match = true;
public $normalizer;
public function __construct($options = null)
{
parent::__construct($options);
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
/**
* {@inheritdoc}

View File

@ -43,6 +43,10 @@ class RegexValidator extends ConstraintValidator
$value = (string) $value;
if (null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
if ($constraint->match xor preg_match($constraint->pattern, $value)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* @Annotation
@ -105,6 +106,7 @@ class Url extends Constraint
*/
public $checkDNS = self::CHECK_DNS_TYPE_NONE;
public $relativeProtocol = false;
public $normalizer;
public function __construct($options = null)
{
@ -118,5 +120,9 @@ class Url extends Constraint
}
parent::__construct($options);
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -62,6 +62,10 @@ class UrlValidator extends ConstraintValidator
return;
}
if (null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
$pattern = $constraint->relativeProtocol ? str_replace('(%s):', '(?:(%s):)?', static::PATTERN) : static::PATTERN;
$pattern = sprintf($pattern, implode('|', $constraint->protocols));

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* @Annotation
@ -74,4 +75,15 @@ class Uuid extends Constraint
self::V4_RANDOM,
self::V5_SHA1,
];
public $normalizer;
public function __construct($options = null)
{
parent::__construct($options);
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', \is_object($this->normalizer) ? \get_class($this->normalizer) : \gettype($this->normalizer)));
}
}
}

View File

@ -81,6 +81,10 @@ class UuidValidator extends ConstraintValidator
$value = (string) $value;
if (null !== $constraint->normalizer) {
$value = ($constraint->normalizer)($value);
}
if ($constraint->strict) {
$this->validateStrict($value, $constraint);

View File

@ -35,11 +35,36 @@ class EmailTest extends TestCase
}
/**
* @expectedException \InvalidArgumentException
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "mode" parameter value is not valid.
*/
public function testUnknownModesTriggerException()
{
new Email(['mode' => 'Unknown Mode']);
}
public function testNormalizerCanBeSet()
{
$email = new Email(['normalizer' => 'trim']);
$this->assertEquals('trim', $email->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Email(['normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Email(['normalizer' => new \stdClass()]);
}
}

View File

@ -94,6 +94,28 @@ class EmailValidatorTest extends ConstraintValidatorTestCase
];
}
/**
* @dataProvider getValidEmailsWithWhitespaces
*/
public function testValidNormalizedEmails($email)
{
$this->validator->validate($email, new Email(['normalizer' => 'trim']));
$this->assertNoViolation();
}
public function getValidEmailsWithWhitespaces()
{
return [
["\x20example@example.co.uk\x20"],
["\x09\x09example@example.co..uk\x09\x09"],
["\x0A{}~!@!@£$%%^&*().!@£$%^&*()\x0A"],
["\x0D\x0Dexample@example.co..uk\x0D\x0D"],
["\x00example@-example.com"],
["example@example.com\x0B\x0B"],
];
}
/**
* @dataProvider getValidEmailsHtml5
*/

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints\Ip;
/**
* @author Renan Taranto <renantaranto@gmail.com>
*/
class IpTest extends TestCase
{
public function testNormalizerCanBeSet()
{
$ip = new Ip(['normalizer' => 'trim']);
$this->assertEquals('trim', $ip->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Ip(['normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Ip(['normalizer' => new \stdClass()]);
}
}

View File

@ -80,6 +80,31 @@ class IpValidatorTest extends ConstraintValidatorTestCase
];
}
/**
* @dataProvider getValidIpsV4WithWhitespaces
*/
public function testValidIpsV4WithWhitespaces($ip)
{
$this->validator->validate($ip, new Ip([
'version' => Ip::V4,
'normalizer' => 'trim',
]));
$this->assertNoViolation();
}
public function getValidIpsV4WithWhitespaces()
{
return [
["\x200.0.0.0"],
["\x09\x0910.0.0.0"],
["123.45.67.178\x0A"],
["172.16.0.0\x0D\x0D"],
["\x00192.168.1.0\x00"],
["\x0B\x0B224.0.0.1\x0B\x0B"],
];
}
/**
* @dataProvider getValidIpsV6
*/

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints\Length;
/**
* @author Renan Taranto <renantaranto@gmail.com>
*/
class LengthTest extends TestCase
{
public function testNormalizerCanBeSet()
{
$length = new Length(['min' => 0, 'max' => 10, 'normalizer' => 'trim']);
$this->assertEquals('trim', $length->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Length(['min' => 0, 'max' => 10, 'normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Length(['min' => 0, 'max' => 10, 'normalizer' => new \stdClass()]);
}
}

View File

@ -92,6 +92,18 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
];
}
public function getThreeCharactersWithWhitespaces()
{
return [
["\x20ccc"],
["\x09c\x09c"],
["\x0Accc\x0A"],
["ccc\x0D\x0D"],
["\x00ccc\x00"],
["\x0Bc\x0Bc\x0B"],
];
}
/**
* @dataProvider getFiveOrMoreCharacters
*/
@ -125,6 +137,17 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
/**
* @dataProvider getThreeCharactersWithWhitespaces
*/
public function testValidNormalizedValues($value)
{
$constraint = new Length(['min' => 3, 'max' => 3, 'normalizer' => 'trim']);
$this->validator->validate($value, $constraint);
$this->assertNoViolation();
}
/**
* @dataProvider getThreeOrLessCharacters
*/

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* @author Renan Taranto <renantaranto@gmail.com>
*/
class NotBlankTest extends TestCase
{
public function testNormalizerCanBeSet()
{
$notBlank = new NotBlank(['normalizer' => 'trim']);
$this->assertEquals('trim', $notBlank->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new NotBlank(['normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new NotBlank(['normalizer' => new \stdClass()]);
}
}

View File

@ -124,4 +124,34 @@ class NotBlankValidatorTest extends ConstraintValidatorTestCase
->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
/**
* @dataProvider getWhitespaces
*/
public function testNormalizedStringIsInvalid($value)
{
$constraint = new NotBlank([
'message' => 'myMessage',
'normalizer' => 'trim',
]);
$this->validator->validate($value, $constraint);
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '""')
->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
public function getWhitespaces()
{
return [
["\x20"],
["\x09\x09"],
["\x0A"],
["\x0D\x0D"],
["\x00"],
["\x0B\x0B"],
];
}
}

View File

@ -85,4 +85,29 @@ class RegexTest extends TestCase
$this->assertSame('((?![0-9]$|[a-z]+).)*', $constraint->pattern);
$this->assertSame('foobar', $constraint->getHtmlPattern());
}
public function testNormalizerCanBeSet()
{
$regex = new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'trim']);
$this->assertEquals('trim', $regex->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => new \stdClass()]);
}
}

View File

@ -55,6 +55,17 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
/**
* @dataProvider getValidValuesWithWhitespaces
*/
public function testValidValuesWithWhitespaces($value)
{
$constraint = new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => 'trim']);
$this->validator->validate($value, $constraint);
$this->assertNoViolation();
}
public function getValidValues()
{
return [
@ -71,6 +82,18 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
];
}
public function getValidValuesWithWhitespaces()
{
return [
["\x207"],
["\x09\x09070707\x09\x09"],
["70707\x0A"],
["7\x0D\x0D"],
["\x00070707\x00"],
["\x0B\x0B70707\x0B\x0B"],
];
}
/**
* @dataProvider getInvalidValues
*/

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints\Url;
/**
* @author Renan Taranto <renantaranto@gmail.com>
*/
class UrlTest extends TestCase
{
public function testNormalizerCanBeSet()
{
$url = new Url(['normalizer' => 'trim']);
$this->assertEquals('trim', $url->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Url(['normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Url(['normalizer' => new \stdClass()]);
}
}

View File

@ -65,6 +65,16 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
$this->assertNoViolation();
}
/**
* @dataProvider getValidUrlsWithWhitespaces
*/
public function testValidUrlsWithWhitespaces($url)
{
$this->validator->validate($url, new Url(['normalizer' => 'trim']));
$this->assertNoViolation();
}
/**
* @dataProvider getValidRelativeUrls
* @dataProvider getValidUrls
@ -155,6 +165,18 @@ class UrlValidatorTest extends ConstraintValidatorTestCase
];
}
public function getValidUrlsWithWhitespaces()
{
return [
["\x20http://www.google.com"],
["\x09\x09http://www.google.com."],
["http://symfony.fake/blog/\x0A"],
["http://symfony.com/search?type=&q=url+validator\x0D\x0D"],
["\x00https://google.com:80\x00"],
["\x0B\x0Bhttp://username:password@symfony.com\x0B\x0B"],
];
}
/**
* @dataProvider getInvalidUrls
*/

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Constraints\Uuid;
/**
* @author Renan Taranto <renantaranto@gmail.com>
*/
class UuidTest extends TestCase
{
public function testNormalizerCanBeSet()
{
$uuid = new Uuid(['normalizer' => 'trim']);
$this->assertEquals('trim', $uuid->normalizer);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("string" given).
*/
public function testInvalidNormalizerThrowsException()
{
new Uuid(['normalizer' => 'Unknown Callable']);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidArgumentException
* @expectedExceptionMessage The "normalizer" option must be a valid callable ("stdClass" given).
*/
public function testInvalidNormalizerObjectThrowsException()
{
new Uuid(['normalizer' => new \stdClass()]);
}
}

View File

@ -85,6 +85,34 @@ class UuidValidatorTest extends ConstraintValidatorTestCase
];
}
/**
* @dataProvider getValidStrictUuidsWithWhitespaces
*/
public function testValidStrictUuidsWithWhitespaces($uuid, $versions = null)
{
$constraint = new Uuid(['normalizer' => 'trim']);
if (null !== $versions) {
$constraint->versions = $versions;
}
$this->validator->validate($uuid, $constraint);
$this->assertNoViolation();
}
public function getValidStrictUuidsWithWhitespaces()
{
return [
["\x20216fff40-98d9-11e3-a5e2-0800200c9a66"], // Version 1 UUID in lowercase
["\x09\x09216fff40-98d9-11e3-a5e2-0800200c9a66", [Uuid::V1_MAC]],
["216FFF40-98D9-11E3-A5E2-0800200C9A66\x0A"], // Version 1 UUID in UPPERCASE
["456daefb-5aa6-41b5-8dbc-068b05a8b201\x0D\x0D"], // Version 4 UUID in lowercase
["\x00456daEFb-5AA6-41B5-8DBC-068B05A8B201\x00"], // Version 4 UUID in mixed case
["\x0B\x0B456daEFb-5AA6-41B5-8DBC-068B05A8B201\x0B\x0B", [Uuid::V4_RANDOM]],
];
}
/**
* @dataProvider getInvalidStrictUuids
*/