mirror of
https://github.com/ramsey/uuid.git
synced 2026-06-14 15:56:48 +03:00
fix: max UUID should be variant 7, nil UUID should be variant 0
This commit is contained in:
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
* Hexadecimal is never an empty string; fixed in [#593](https://github.com/ramsey/uuid/pull/593).
|
||||
* Update call to `str_getcsv()` to avoid deprecation notice in PHP 8.4; fixed in [#590](https://github.com/ramsey/uuid/pull/590).
|
||||
* Update docblocks for `Uuid::fromBytes()`, `Uuid::fromString()`, `Uuid::fromDateTime()`, `Uuid::fromHexadecimal()`, and `Uuid::fromInteger()` to note that each can throw `InvalidArgumentException`, addressing PHPStan errors occurring at call sites; fixed in [#552](https://github.com/ramsey/uuid/pull/552).
|
||||
* `getVariant()` for `MaxUuid` now correctly returns `Uuid::RESERVED_FUTURE`, as specified in [RFC 9562, section 5.10](https://www.rfc-editor.org/rfc/rfc9562#section-5.10).
|
||||
* `getVariant()` for `NilUuid` now correctly returns `Uuid::RESERVED_NCS`, as specified in [RFC 9562, section 5.9](https://www.rfc-editor.org/rfc/rfc9562#section-5.9).
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
||||
@@ -42,13 +42,13 @@ class UuidBuilder implements UuidBuilderInterface
|
||||
* @param NumberConverterInterface $numberConverter The number converter to use when constructing the Uuid
|
||||
* @param TimeConverterInterface $timeConverter The time converter to use for converting Gregorian time extracted
|
||||
* from version 1, 2, and 6 UUIDs to Unix timestamps
|
||||
* @param TimeConverterInterface|null $unixTimeConverter The time converter to use for converter Unix Epoch time
|
||||
* @param TimeConverterInterface | null $unixTimeConverter The time converter to use for converter Unix Epoch time
|
||||
* extracted from version 7 UUIDs to Unix timestamps
|
||||
*/
|
||||
public function __construct(
|
||||
private NumberConverterInterface $numberConverter,
|
||||
private TimeConverterInterface $timeConverter,
|
||||
?TimeConverterInterface $unixTimeConverter = null
|
||||
?TimeConverterInterface $unixTimeConverter = null,
|
||||
) {
|
||||
$this->unixTimeConverter = $unixTimeConverter ?? new UnixTimeConverter(new BrickMathCalculator());
|
||||
}
|
||||
|
||||
@@ -58,8 +58,18 @@ trait VariantTrait
|
||||
throw new InvalidBytesException('Invalid number of bytes');
|
||||
}
|
||||
|
||||
if ($this->isMax() || $this->isNil()) {
|
||||
return Uuid::RFC_4122;
|
||||
// According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and
|
||||
// {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 5.10}, the Max UUID falls within the range
|
||||
// of the future variant.
|
||||
if ($this->isMax()) {
|
||||
return Uuid::RESERVED_FUTURE;
|
||||
}
|
||||
|
||||
// According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and
|
||||
// {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 5.9}, the Nil UUID falls within the range
|
||||
// of the Apollo NCS variant.
|
||||
if ($this->isNil()) {
|
||||
return Uuid::RESERVED_NCS;
|
||||
}
|
||||
|
||||
/** @var int[] $parts */
|
||||
|
||||
@@ -380,7 +380,7 @@ class ExpectedBehaviorTest extends TestCase
|
||||
public function provideFromStringInteger()
|
||||
{
|
||||
return [
|
||||
['00000000-0000-0000-0000-000000000000', null, 2, '0'],
|
||||
['00000000-0000-0000-0000-000000000000', null, 0, '0'],
|
||||
['ff6f8cb0-c57d-11e1-8b21-0800200c9a66', 1, 2, '339532337419071774304650190139318639206'],
|
||||
['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 1, 2, '339532337419071774305803111643925486182'],
|
||||
['ff6f8cb0-c57d-11e1-ab21-0800200c9a66', 1, 2, '339532337419071774306956033148532333158'],
|
||||
@@ -413,7 +413,7 @@ class ExpectedBehaviorTest extends TestCase
|
||||
['ff6f8cb0-c57d-01e1-db21-0800200c9a66', null, 6, '339532337419071698752551071748029454950'],
|
||||
['ff6f8cb0-c57d-01e1-eb21-0800200c9a66', null, 7, '339532337419071698753703993252636301926'],
|
||||
['ff6f8cb0-c57d-01e1-fb21-0800200c9a66', null, 7, '339532337419071698754856914757243148902'],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', null, 2, '340282366920938463463374607431768211455'],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', null, 7, '340282366920938463463374607431768211455'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ class FieldsTest extends TestCase
|
||||
['00000000000000000000000000000000', 'getTimeLow', '00000000'],
|
||||
['00000000000000000000000000000000', 'getTimeMid', '0000'],
|
||||
['00000000000000000000000000000000', 'getTimestamp', '000000000000000'],
|
||||
['00000000000000000000000000000000', 'getVariant', 2],
|
||||
['00000000000000000000000000000000', 'getVariant', 0],
|
||||
['00000000000000000000000000000000', 'getVersion', null],
|
||||
['00000000000000000000000000000000', 'isNil', true],
|
||||
['00000000000000000000000000000000', 'isMax', false],
|
||||
@@ -215,7 +215,7 @@ class FieldsTest extends TestCase
|
||||
['ffffffffffffffffffffffffffffffff', 'getTimeLow', 'ffffffff'],
|
||||
['ffffffffffffffffffffffffffffffff', 'getTimeMid', 'ffff'],
|
||||
['ffffffffffffffffffffffffffffffff', 'getTimestamp', 'fffffffffffffff'],
|
||||
['ffffffffffffffffffffffffffffffff', 'getVariant', 2],
|
||||
['ffffffffffffffffffffffffffffffff', 'getVariant', 7],
|
||||
['ffffffffffffffffffffffffffffffff', 'getVersion', null],
|
||||
['ffffffffffffffffffffffffffffffff', 'isNil', false],
|
||||
['ffffffffffffffffffffffffffffffff', 'isMax', true],
|
||||
|
||||
@@ -201,7 +201,7 @@ class FieldsTest extends TestCase
|
||||
['00000000-0000-0000-0000-000000000000', 'getTimeLow', '00000000'],
|
||||
['00000000-0000-0000-0000-000000000000', 'getTimeMid', '0000'],
|
||||
['00000000-0000-0000-0000-000000000000', 'getTimestamp', '000000000000000'],
|
||||
['00000000-0000-0000-0000-000000000000', 'getVariant', 2],
|
||||
['00000000-0000-0000-0000-000000000000', 'getVariant', 0],
|
||||
['00000000-0000-0000-0000-000000000000', 'getVersion', null],
|
||||
['00000000-0000-0000-0000-000000000000', 'isNil', true],
|
||||
['00000000-0000-0000-0000-000000000000', 'isMax', false],
|
||||
@@ -214,7 +214,7 @@ class FieldsTest extends TestCase
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeLow', 'ffffffff'],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimeMid', 'ffff'],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getTimestamp', 'fffffffffffffff'],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVariant', 2],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVariant', 7],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVersion', null],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isNil', false],
|
||||
['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isMax', true],
|
||||
|
||||
+3
-16
@@ -1436,13 +1436,7 @@ class UuidTest extends TestCase
|
||||
'urn' => 'urn:uuid:00000000-0000-0000-0000-000000000000',
|
||||
'time' => '0',
|
||||
'clock_seq' => '0000',
|
||||
// This is a departure from the Python tests. The Python tests
|
||||
// are technically "correct" because all bits are set to zero,
|
||||
// so it stands to reason that the variant is also zero, but
|
||||
// that leads to this being considered a "Reserved NCS" variant,
|
||||
// and that is not the case. RFC 4122 defines this special UUID,
|
||||
// so it is an RFC 4122 variant.
|
||||
'variant' => Uuid::RFC_4122,
|
||||
'variant' => Uuid::RESERVED_NCS,
|
||||
'version' => null,
|
||||
],
|
||||
[
|
||||
@@ -1701,20 +1695,13 @@ class UuidTest extends TestCase
|
||||
],
|
||||
'urn' => 'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff',
|
||||
'time' => 'fffffffffffffff',
|
||||
// This is a departure from the Python tests. The Python tests
|
||||
// are technically "correct" because all bits are set to one,
|
||||
// which ends up calculating the variant as 7, or "Reserved
|
||||
// Future," but that is not the case, and now that max UUIDs
|
||||
// are defined as a special type, within the RFC 4122 variant
|
||||
// rules, we also consider it an RFC 4122 variant.
|
||||
//
|
||||
// Similarly, Python's tests think the clock sequence should be
|
||||
// Python's tests think the clock sequence should be
|
||||
// 0x3fff because of the bit shifting performed on this field.
|
||||
// However, since all the bits in this UUID are defined as being
|
||||
// set to one, we will consider the clock sequence as 0xffff,
|
||||
// which all bits set to one.
|
||||
'clock_seq' => 'ffff',
|
||||
'variant' => Uuid::RFC_4122,
|
||||
'variant' => Uuid::RESERVED_FUTURE,
|
||||
'version' => null,
|
||||
],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user