mirror of
https://github.com/ramsey/uuid.git
synced 2026-06-14 15:56:48 +03:00
Fix collection deserialization errors
This commit is contained in:
+11
-1
@@ -21,6 +21,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
### Security
|
||||
|
||||
|
||||
## [4.0.1] - 2020-03-29
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix collection deserialization errors due to upstream `allowed_classes` being
|
||||
set to `false`. For details, see [ramsey/uuid#303](https://github.com/ramsey/uuid/issues/303)
|
||||
and [ramsey/collection#47](https://github.com/ramsey/collection/issues/47).
|
||||
|
||||
|
||||
## [4.0.0] - 2020-03-22
|
||||
|
||||
### Added
|
||||
@@ -1173,7 +1182,8 @@ versions leading up to this release.*
|
||||
[ramsey/uuid-doctrine]: https://github.com/ramsey/uuid-doctrine
|
||||
[ramsey/uuid-console]: https://github.com/ramsey/uuid-console
|
||||
|
||||
[unreleased]: https://github.com/ramsey/uuid/compare/4.0.0...HEAD
|
||||
[unreleased]: https://github.com/ramsey/uuid/compare/4.0.1...HEAD
|
||||
[4.0.1]: https://github.com/ramsey/uuid/compare/4.0.0...4.0.1
|
||||
[4.0.0]: https://github.com/ramsey/uuid/compare/4.0.0-beta2...4.0.0
|
||||
[4.0.0-beta2]: https://github.com/ramsey/uuid/compare/4.0.0-beta1...4.0.0-beta2
|
||||
[4.0.0-beta1]: https://github.com/ramsey/uuid/compare/4.0.0-alpha5...4.0.0-beta1
|
||||
|
||||
@@ -16,6 +16,13 @@ namespace Ramsey\Uuid\Builder;
|
||||
|
||||
use Ramsey\Collection\AbstractCollection;
|
||||
use Ramsey\Collection\CollectionInterface;
|
||||
use Ramsey\Uuid\Converter\Number\GenericNumberConverter;
|
||||
use Ramsey\Uuid\Converter\Time\GenericTimeConverter;
|
||||
use Ramsey\Uuid\Converter\Time\PhpTimeConverter;
|
||||
use Ramsey\Uuid\Guid\GuidBuilder;
|
||||
use Ramsey\Uuid\Math\BrickMathCalculator;
|
||||
use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder;
|
||||
use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
@@ -37,4 +44,30 @@ class BuilderCollection extends AbstractCollection implements CollectionInterfac
|
||||
{
|
||||
return parent::getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-constructs the object from its serialized form
|
||||
*
|
||||
* @param string $serialized The serialized PHP string to unserialize into
|
||||
* a UuidInterface instance
|
||||
*
|
||||
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
|
||||
*/
|
||||
public function unserialize($serialized): void
|
||||
{
|
||||
/** @var mixed[] $data */
|
||||
$data = unserialize($serialized, [
|
||||
'allowed_classes' => [
|
||||
BrickMathCalculator::class,
|
||||
GenericNumberConverter::class,
|
||||
GenericTimeConverter::class,
|
||||
GuidBuilder::class,
|
||||
NonstandardUuidBuilder::class,
|
||||
PhpTimeConverter::class,
|
||||
Rfc4122UuidBuilder::class,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Ramsey\Uuid\Provider\Node;
|
||||
use Ramsey\Collection\AbstractCollection;
|
||||
use Ramsey\Collection\CollectionInterface;
|
||||
use Ramsey\Uuid\Provider\NodeProviderInterface;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
|
||||
/**
|
||||
* A collection of NodeProviderInterface objects
|
||||
@@ -27,4 +28,27 @@ class NodeProviderCollection extends AbstractCollection implements CollectionInt
|
||||
{
|
||||
return NodeProviderInterface::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-constructs the object from its serialized form
|
||||
*
|
||||
* @param string $serialized The serialized PHP string to unserialize into
|
||||
* a UuidInterface instance
|
||||
*
|
||||
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
|
||||
*/
|
||||
public function unserialize($serialized): void
|
||||
{
|
||||
/** @var mixed[] $data */
|
||||
$data = unserialize($serialized, [
|
||||
'allowed_classes' => [
|
||||
Hexadecimal::class,
|
||||
RandomNodeProvider::class,
|
||||
StaticNodeProvider::class,
|
||||
SystemNodeProvider::class,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +291,7 @@ class Uuid implements UuidInterface
|
||||
$this->codec = $uuid->codec;
|
||||
$this->numberConverter = $uuid->numberConverter;
|
||||
$this->fields = $uuid->fields;
|
||||
$this->timeConverter = $uuid->timeConverter;
|
||||
}
|
||||
|
||||
public function compareTo(UuidInterface $other): int
|
||||
|
||||
@@ -4,14 +4,28 @@ declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Uuid\Test\Builder;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Mockery;
|
||||
use Ramsey\Uuid\Builder\BuilderCollection;
|
||||
use Ramsey\Uuid\Builder\FallbackBuilder;
|
||||
use Ramsey\Uuid\Builder\UuidBuilderInterface;
|
||||
use Ramsey\Uuid\Codec\CodecInterface;
|
||||
use Ramsey\Uuid\Codec\StringCodec;
|
||||
use Ramsey\Uuid\Converter\Number\GenericNumberConverter;
|
||||
use Ramsey\Uuid\Converter\Time\GenericTimeConverter;
|
||||
use Ramsey\Uuid\Converter\Time\PhpTimeConverter;
|
||||
use Ramsey\Uuid\Exception\BuilderNotFoundException;
|
||||
use Ramsey\Uuid\Exception\UnableToBuildUuidException;
|
||||
use Ramsey\Uuid\Guid\GuidBuilder;
|
||||
use Ramsey\Uuid\Math\BrickMathCalculator;
|
||||
use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder;
|
||||
use Ramsey\Uuid\Nonstandard\UuidV6;
|
||||
use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder;
|
||||
use Ramsey\Uuid\Rfc4122\UuidV1;
|
||||
use Ramsey\Uuid\Rfc4122\UuidV2;
|
||||
use Ramsey\Uuid\Test\TestCase;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Ramsey\Uuid\Validator\GenericValidator;
|
||||
|
||||
class FallbackBuilderTest extends TestCase
|
||||
{
|
||||
@@ -50,4 +64,148 @@ class FallbackBuilderTest extends TestCase
|
||||
|
||||
$fallbackBuilder->build($codec, $bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideBytes
|
||||
*/
|
||||
public function testSerializationOfBuilderCollection(string $bytes): void
|
||||
{
|
||||
$validator = new GenericValidator();
|
||||
$calculator = new BrickMathCalculator();
|
||||
$genericNumberConverter = new GenericNumberConverter($calculator);
|
||||
$genericTimeConverter = new GenericTimeConverter($calculator);
|
||||
$phpTimeConverter = new PhpTimeConverter($calculator, $genericTimeConverter);
|
||||
|
||||
// Use the GenericTimeConverter.
|
||||
$guidBuilder = new GuidBuilder($genericNumberConverter, $genericTimeConverter);
|
||||
$rfc4122Builder = new Rfc4122UuidBuilder($genericNumberConverter, $genericTimeConverter);
|
||||
$nonstandardBuilder = new NonstandardUuidBuilder($genericNumberConverter, $genericTimeConverter);
|
||||
|
||||
// Use the PhpTimeConverter.
|
||||
$guidBuilder2 = new GuidBuilder($genericNumberConverter, $phpTimeConverter);
|
||||
$rfc4122Builder2 = new Rfc4122UuidBuilder($genericNumberConverter, $phpTimeConverter);
|
||||
$nonstandardBuilder2 = new NonstandardUuidBuilder($genericNumberConverter, $phpTimeConverter);
|
||||
|
||||
$builderCollection = new BuilderCollection(
|
||||
[
|
||||
$guidBuilder,
|
||||
$guidBuilder2,
|
||||
$rfc4122Builder,
|
||||
$rfc4122Builder2,
|
||||
$nonstandardBuilder,
|
||||
$nonstandardBuilder2,
|
||||
]
|
||||
);
|
||||
|
||||
$serializedBuilderCollection = serialize($builderCollection);
|
||||
|
||||
/** @var BuilderCollection $unserializedBuilderCollection */
|
||||
$unserializedBuilderCollection = unserialize($serializedBuilderCollection);
|
||||
|
||||
$this->assertInstanceOf(BuilderCollection::class, $unserializedBuilderCollection);
|
||||
|
||||
/** @var UuidBuilderInterface $builder */
|
||||
foreach ($unserializedBuilderCollection as $builder) {
|
||||
$codec = new StringCodec($builder);
|
||||
|
||||
$this->assertInstanceOf(UuidBuilderInterface::class, $builder);
|
||||
|
||||
try {
|
||||
$uuid = $builder->build($codec, $bytes);
|
||||
$this->assertInstanceOf(UuidInterface::class, $uuid);
|
||||
|
||||
if (($uuid instanceof UuidV1) || ($uuid instanceof UuidV2) || ($uuid instanceof UuidV6)) {
|
||||
$this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime());
|
||||
}
|
||||
} catch (UnableToBuildUuidException $exception) {
|
||||
switch ($exception->getMessage()) {
|
||||
case 'The byte string received does not contain a valid version':
|
||||
case 'The byte string received does not conform to the RFC 4122 variant':
|
||||
case 'The byte string received does not conform to the RFC 4122 or Microsoft Corporation variants':
|
||||
// This is expected; ignoring.
|
||||
|
||||
break;
|
||||
default:
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification
|
||||
*/
|
||||
public function provideBytes(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1110b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1111b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1112b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1113b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1114b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1115b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1116b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e1117b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e111eb210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// GUID bytes
|
||||
'bytes' => hex2bin('b08c6fff7dc5e111fb210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// Version 1 bytes
|
||||
'bytes' => hex2bin('ff6f8cb0c57d11e19b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// Version 2 bytes
|
||||
'bytes' => hex2bin('000001f55cde21ea84000242ac130003'),
|
||||
],
|
||||
[
|
||||
// Version 3 bytes
|
||||
'bytes' => hex2bin('ff6f8cb0c57d31e1bb210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// Version 4 bytes
|
||||
'bytes' => hex2bin('ff6f8cb0c57d41e1ab210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// Version 5 bytes
|
||||
'bytes' => hex2bin('ff6f8cb0c57d51e18b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// Version 6 bytes
|
||||
'bytes' => hex2bin('ff6f8cb0c57d61e18b210800200c9a66'),
|
||||
],
|
||||
[
|
||||
// NIL bytes
|
||||
'bytes' => hex2bin('00000000000000000000000000000000'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ namespace Ramsey\Uuid\Test\Provider\Node;
|
||||
use Ramsey\Uuid\Exception\NodeException;
|
||||
use Ramsey\Uuid\Provider\Node\FallbackNodeProvider;
|
||||
use Ramsey\Uuid\Provider\Node\NodeProviderCollection;
|
||||
use Ramsey\Uuid\Provider\Node\RandomNodeProvider;
|
||||
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
|
||||
use Ramsey\Uuid\Provider\Node\SystemNodeProvider;
|
||||
use Ramsey\Uuid\Provider\NodeProviderInterface;
|
||||
use Ramsey\Uuid\Test\TestCase;
|
||||
use Ramsey\Uuid\Type\Hexadecimal;
|
||||
@@ -65,4 +68,31 @@ class FallbackNodeProviderTest extends TestCase
|
||||
|
||||
$provider->getNode();
|
||||
}
|
||||
|
||||
public function testSerializationOfNodeProviderCollection(): void
|
||||
{
|
||||
$staticNodeProvider = new StaticNodeProvider(new Hexadecimal('aabbccddeeff'));
|
||||
$randomNodeProvider = new RandomNodeProvider();
|
||||
$systemNodeProvider = new SystemNodeProvider();
|
||||
|
||||
$nodeProviderCollection = new NodeProviderCollection(
|
||||
[
|
||||
$staticNodeProvider,
|
||||
$randomNodeProvider,
|
||||
$systemNodeProvider,
|
||||
]
|
||||
);
|
||||
|
||||
$serializedNodeProviderCollection = serialize($nodeProviderCollection);
|
||||
|
||||
/** @var NodeProviderCollection $unserializedNodeProviderCollection */
|
||||
$unserializedNodeProviderCollection = unserialize($serializedNodeProviderCollection);
|
||||
|
||||
$this->assertInstanceOf(NodeProviderCollection::class, $unserializedNodeProviderCollection);
|
||||
|
||||
foreach ($unserializedNodeProviderCollection as $nodeProvider) {
|
||||
$this->assertInstanceOf(NodeProviderInterface::class, $nodeProvider);
|
||||
$this->assertInstanceOf(Hexadecimal::class, $nodeProvider->getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user