diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ebd13..18456f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,9 +76,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed -* Hexadecimal is never an empty string; fixed in [#593](https://github.com/ramsey/uuid/pull/593). +* Allow brick/math version `^0.13`; fixed in [#589](https://github.com/ramsey/uuid/pull/589). * Update call to `str_getcsv()` to avoid deprecation notice in PHP 8.4; fixed in [#590](https://github.com/ramsey/uuid/pull/590). +* Hexadecimal is never an empty string; fixed in [#593](https://github.com/ramsey/uuid/pull/593). * 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 diff --git a/composer.json b/composer.json index bff4edb..21ea6d9 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "require": { "php": "^8.2", "ext-json": "*", - "brick/math": "^0.11 || ^0.12" + "brick/math": "^0.11 || ^0.12 || ^0.13" }, "require-dev": { "captainhook/captainhook": "^5.25", diff --git a/composer.lock b/composer.lock index 43fa360..3b37a5e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,29 +4,29 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1dd714ad3bd396f8cb8d4e0b5227acd7", + "content-hash": "d8c670f63b96a7f61d29da1702892f34", "packages": [ { "name": "brick/math", - "version": "0.12.3", + "version": "0.11.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", + "url": "https://api.github.com/repos/brick/math/zipball/0ad82ce168c82ba30d1c01ec86116ab52f589478", + "reference": "0ad82ce168c82ba30d1c01ec86116ab52f589478", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "6.8.8" + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "5.0.0" }, "type": "library", "autoload": { @@ -46,17 +46,12 @@ "arithmetic", "bigdecimal", "bignum", - "bignumber", "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" + "math" ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.3" + "source": "https://github.com/brick/math/tree/0.11.0" }, "funding": [ { @@ -64,7 +59,7 @@ "type": "github" } ], - "time": "2025-02-28T13:11:00+00:00" + "time": "2023-01-15T23:15:59+00:00" } ], "packages-dev": [ diff --git a/src/Rfc4122/VariantTrait.php b/src/Rfc4122/VariantTrait.php index 65862ef..50f1324 100644 --- a/src/Rfc4122/VariantTrait.php +++ b/src/Rfc4122/VariantTrait.php @@ -49,8 +49,18 @@ trait VariantTrait throw new InvalidBytesException('Invalid number of bytes'); } - if ($this->isMax() || $this->isNil()) { - return Variant::Rfc4122; + // 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 Variant::ReservedFuture; + } + + // 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 Variant::ReservedNcs; } /** @var int[] $parts */ diff --git a/tests/ExpectedBehaviorTest.php b/tests/ExpectedBehaviorTest.php index 8210eed..a9cf02e 100644 --- a/tests/ExpectedBehaviorTest.php +++ b/tests/ExpectedBehaviorTest.php @@ -303,7 +303,7 @@ class ExpectedBehaviorTest extends TestCase public static function provideFromStringInteger(): array { 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'], @@ -336,7 +336,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'], ]; } diff --git a/tests/Guid/FieldsTest.php b/tests/Guid/FieldsTest.php index 793ed9a..65963ef 100644 --- a/tests/Guid/FieldsTest.php +++ b/tests/Guid/FieldsTest.php @@ -208,7 +208,7 @@ class FieldsTest extends TestCase ['00000000000000000000000000000000', 'getTimeLow', '00000000'], ['00000000000000000000000000000000', 'getTimeMid', '0000'], ['00000000000000000000000000000000', 'getTimestamp', '000000000000000'], - ['00000000000000000000000000000000', 'getVariant', Variant::Rfc4122], + ['00000000000000000000000000000000', 'getVariant', Variant::ReservedNcs], ['00000000000000000000000000000000', 'getVersion', null], ['00000000000000000000000000000000', 'isNil', true], ['00000000000000000000000000000000', 'isMax', false], @@ -222,7 +222,7 @@ class FieldsTest extends TestCase ['ffffffffffffffffffffffffffffffff', 'getTimeLow', 'ffffffff'], ['ffffffffffffffffffffffffffffffff', 'getTimeMid', 'ffff'], ['ffffffffffffffffffffffffffffffff', 'getTimestamp', 'fffffffffffffff'], - ['ffffffffffffffffffffffffffffffff', 'getVariant', Variant::Rfc4122], + ['ffffffffffffffffffffffffffffffff', 'getVariant', Variant::ReservedFuture], ['ffffffffffffffffffffffffffffffff', 'getVersion', null], ['ffffffffffffffffffffffffffffffff', 'isNil', false], ['ffffffffffffffffffffffffffffffff', 'isMax', true], diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index 9504980..50f88f0 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -208,7 +208,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', Variant::Rfc4122], + ['00000000-0000-0000-0000-000000000000', 'getVariant', Variant::ReservedNcs], ['00000000-0000-0000-0000-000000000000', 'getVersion', null], ['00000000-0000-0000-0000-000000000000', 'isNil', true], ['00000000-0000-0000-0000-000000000000', 'isMax', false], @@ -221,7 +221,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', Variant::Rfc4122], + ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVariant', Variant::ReservedFuture], ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'getVersion', null], ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isNil', false], ['ffffffff-ffff-ffff-ffff-ffffffffffff', 'isMax', true], diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 1175a83..7b96532 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1306,13 +1306,7 @@ class UuidTest extends TestCase 'urn' => 'urn:uuid:00000000-0000-0000-0000-000000000000', 'time' => '000000000000000', 'clockSeq' => '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' => Variant::Rfc4122, + 'variant' => Variant::ReservedNcs, 'version' => null, ], [ @@ -1571,20 +1565,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. 'clockSeq' => 'ffff', - 'variant' => Variant::Rfc4122, + 'variant' => Variant::ReservedFuture, 'version' => null, ], ];