[Uid] fix checking for valid UUIDs

This commit is contained in:
Nicolas Grekas 2021-01-23 20:10:32 +01:00
parent a933c3e0a1
commit 7daef4ff6d
3 changed files with 16 additions and 16 deletions

View File

@ -40,7 +40,7 @@ class BinaryUtil
// 0x01b21dd213814000 is the number of 100-ns intervals between the
// UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
private const TIME_OFFSET_INT = 0x01b21dd213814000;
private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
private const TIME_OFFSET_COM2 = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
public static function toBase(string $bytes, array $map): string
{
@ -121,9 +121,15 @@ class BinaryUtil
}
$time = str_pad(hex2bin($time), 8, "\0", \STR_PAD_LEFT);
$time = self::add($time, self::TIME_OFFSET_COM);
$time[0] = $time[0] & "\x7F";
$time = self::add($time, self::TIME_OFFSET_COM2);
return self::toBase($time, self::BASE10) / 10000000;
if ($time >= self::TIME_OFFSET_COM2) {
$time = -1 * self::toBase($time ^ "\xff\xff\xff\xff\xff\xff\xff\xff", self::BASE10);
} else {
$time[0] = $time[0] & "\x7F";
$time = self::toBase($time, self::BASE10);
}
return $time / 10000000;
}
}

View File

@ -153,7 +153,7 @@ class Ulid extends AbstractUid
if (\PHP_INT_SIZE >= 8) {
$time = base_convert($time, 10, 32);
} else {
$time = bin2hex(BinaryUtil::fromBase($time, BinaryUtil::BASE10));
$time = str_pad(bin2hex(BinaryUtil::fromBase($time, BinaryUtil::BASE10)), 12, '0', \STR_PAD_LEFT);
$time = sprintf('%s%04s%04s',
base_convert(substr($time, 0, 2), 16, 32),
base_convert(substr($time, 2, 5), 16, 32),

View File

@ -22,11 +22,7 @@ class Uuid extends AbstractUid
public function __construct(string $uuid)
{
try {
$type = uuid_type($uuid);
} catch (\ValueError $e) {
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid), 0, $e);
}
$type = uuid_is_valid($uuid) ? uuid_type($uuid) : false;
if (false === $type || \UUID_TYPE_INVALID === $type || (static::TYPE ?: $type) !== $type) {
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid));
@ -59,13 +55,11 @@ class Uuid extends AbstractUid
return new static($uuid);
}
try {
$type = uuid_type($uuid);
} catch (\ValueError $e) {
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid), 0, $e);
if (!uuid_is_valid($uuid)) {
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid));
}
switch ($type) {
switch (uuid_type($uuid)) {
case UuidV1::TYPE: return new UuidV1($uuid);
case UuidV3::TYPE: return new UuidV3($uuid);
case UuidV4::TYPE: return new UuidV4($uuid);
@ -114,7 +108,7 @@ class Uuid extends AbstractUid
return uuid_is_valid($uuid);
}
return static::TYPE === uuid_type($uuid);
return uuid_is_valid($uuid) && static::TYPE === uuid_type($uuid);
}
public function toBinary(): string