Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.x] Validate UUID's version optionally #53341

Merged
merged 10 commits into from
Oct 31, 2024
28 changes: 26 additions & 2 deletions src/Illuminate/Support/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@
use Ramsey\Uuid\Generator\CombGenerator;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidFactory;
use Symfony\Component\Uid\NilUuid;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\UuidV1;
use Symfony\Component\Uid\UuidV3;
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Uid\UuidV5;
use Symfony\Component\Uid\UuidV6;
use Symfony\Component\Uid\UuidV7;
use Symfony\Component\Uid\UuidV8;
use Throwable;
use Traversable;
use voku\helper\ASCII;
Expand Down Expand Up @@ -595,15 +603,31 @@ public static function isUrl($value, array $protocols = [])
* Determine if a given value is a valid UUID.
*
* @param mixed $value
* @param int<-1, 8>|null $version
* @return bool
*/
public static function isUuid($value)
public static function isUuid($value, $version = null)
{
if (! is_string($value)) {
return false;
}

return preg_match('/^[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}$/D', $value) > 0;
if ($version === null) {
return preg_match('/^[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}$/D', $value) > 0;
}

return match ($version) {
-1, 0 => NilUuid::isValid($value),
1 => UuidV1::isValid($value),
// 2 => UuidV2::isValid($value), // Symfony/uid doesn't implement version 2
3 => UuidV3::isValid($value),
4 => UuidV4::isValid($value),
5 => UuidV5::isValid($value),
6 => UuidV6::isValid($value),
7 => UuidV7::isValid($value),
8 => UuidV8::isValid($value),
default => false,
};
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/Illuminate/Validation/Concerns/ValidatesAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -2550,11 +2550,12 @@ public function validateUlid($attribute, $value)
*
* @param string $attribute
* @param mixed $value
* @param array<int, int<-1, 8>> $parameters
* @return bool
*/
public function validateUuid($attribute, $value)
public function validateUuid($attribute, $value, $parameters)
{
return Str::isUuid($value);
return Str::isUuid($value, $parameters !== null && count($parameters) === 1 ? (int) $parameters[0] : null);
}

/**
Expand Down
24 changes: 24 additions & 0 deletions tests/Support/SupportStrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,12 @@ public function testIsUuidWithInvalidUuid($uuid)
$this->assertFalse(Str::isUuid($uuid));
}

#[DataProvider('uuidVersionList')]
public function testIsUuidWithVersion($uuid, $version, $passes)
{
$this->assertSame(Str::isUuid($uuid, $version), $passes);
}

public function testIsJson()
{
$this->assertTrue(Str::isJson('1'));
Expand Down Expand Up @@ -1306,6 +1312,24 @@ public static function invalidUuidList()
];
}

public static function uuidVersionList()
{
return [
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', null, true],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 1, false],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 4, true],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 42, false],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', null, true],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 1, true],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 4, false],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 42, false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', null, false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 1, false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 4, false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 42, false],
];
}

public static function strContainsProvider()
{
return [
Expand Down
26 changes: 26 additions & 0 deletions tests/Validation/ValidationValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8445,6 +8445,14 @@ public function testValidateWithInvalidUuid($uuid)
$this->assertFalse($v->passes());
}

#[DataProvider('uuidVersionList')]
public function testValidateWithUuidWithVersionConstraint($uuid, $rule, $passes)
{
$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, ['foo' => $uuid], ['foo' => $rule]);
$this->assertSame($v->passes(), $passes);
}

public static function validUuidList()
{
return [
Expand Down Expand Up @@ -8477,6 +8485,24 @@ public static function invalidUuidList()
];
}

public static function uuidVersionList()
{
return [
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid', true],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:1', false],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:4', true],
['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:42', false],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid', true],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:1', true],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:4', false],
['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:42', false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid', false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:1', false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:4', false],
['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:42', false],
];
}

public function testValidateWithValidAscii()
{
$trans = $this->getIlluminateArrayTranslator();
Expand Down