diff --git a/src/Symfony/Component/Uid/BinaryUtil.php b/src/Symfony/Component/Uid/BinaryUtil.php index 082346cd155f0..32e7e0dff3c6c 100644 --- a/src/Symfony/Component/Uid/BinaryUtil.php +++ b/src/Symfony/Component/Uid/BinaryUtil.php @@ -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 @@ public static function timeToFloat(string $time): float } $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; } } diff --git a/src/Symfony/Component/Uid/Ulid.php b/src/Symfony/Component/Uid/Ulid.php index b467f9be2b74d..5ff31bb398ef7 100644 --- a/src/Symfony/Component/Uid/Ulid.php +++ b/src/Symfony/Component/Uid/Ulid.php @@ -153,7 +153,7 @@ private static function generate(): string 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), diff --git a/src/Symfony/Component/Uid/Uuid.php b/src/Symfony/Component/Uid/Uuid.php index 87a285b9c3ff9..a9fbbc2158e4d 100644 --- a/src/Symfony/Component/Uid/Uuid.php +++ b/src/Symfony/Component/Uid/Uuid.php @@ -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 @@ public static function fromString(string $uuid): parent 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 @@ public static function isValid(string $uuid): bool 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