diff --git a/src/Rfc4122/FieldsInterface.php b/src/Rfc4122/FieldsInterface.php index a0cc4f4a..2241cf57 100644 --- a/src/Rfc4122/FieldsInterface.php +++ b/src/Rfc4122/FieldsInterface.php @@ -109,6 +109,7 @@ public function getVariant(): int; * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 * 6. Reordered time UUID + * 7. Unix Epoch time UUID * * This returns `null` if the UUID is not an RFC 4122 variant, since version * is only meaningful for this variant. diff --git a/src/Rfc4122/Validator.php b/src/Rfc4122/Validator.php index ed43c982..6b1f0de0 100644 --- a/src/Rfc4122/Validator.php +++ b/src/Rfc4122/Validator.php @@ -28,7 +28,7 @@ final class Validator implements ValidatorInterface { private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; + . '[1-7][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; /** * @psalm-return non-empty-string @@ -43,7 +43,8 @@ public function getPattern(): string public function validate(string $uuid): bool { $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); + $uuid = strtolower($uuid); - return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); + return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } diff --git a/tests/Rfc4122/ValidatorTest.php b/tests/Rfc4122/ValidatorTest.php index e8b97709..779de50d 100644 --- a/tests/Rfc4122/ValidatorTest.php +++ b/tests/Rfc4122/ValidatorTest.php @@ -30,7 +30,15 @@ public function testValidate(string $value, bool $expected): void $validator = new Validator(); foreach ($variations as $variation) { - $this->assertSame($expected, $validator->validate($variation)); + $this->assertSame( + $expected, + $validator->validate($variation), + sprintf( + 'Expected "%s" to be %s', + $variation, + $expected ? 'valid' : 'not valid', + ), + ); } } @@ -40,7 +48,7 @@ public function testValidate(string $value, bool $expected): void public function provideValuesForValidation(): array { $hexMutations = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']; - $trueVersions = [1, 2, 3, 4, 5]; + $trueVersions = [1, 2, 3, 4, 5, 6, 7]; $trueVariants = [8, 9, 'a', 'b']; $testValues = []; @@ -87,13 +95,25 @@ public function provideValuesForValidation(): array 'value' => "\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\n", 'expected' => false, ], + [ + 'value' => '00000000-0000-0000-0000-000000000000', + 'expected' => true, + ], + [ + 'value' => 'ffffffff-ffff-ffff-ffff-ffffffffffff', + 'expected' => true, + ], + [ + 'value' => 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF', + 'expected' => true, + ], ]); } public function testGetPattern(): void { $expectedPattern = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; + . '[1-7][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; $validator = new Validator();