From 723433cba198975a3546c9375e7b35ff0a668b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Sat, 7 Mar 2020 12:35:51 +0100 Subject: [PATCH] constants are scalars, can be securely serialized --- src/AbstractEnum.php | 43 ++++++++++++++++++++++++--------- src/Enum.php | 2 +- tests/Enum/AbstractEnumTest.php | 18 ++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/AbstractEnum.php b/src/AbstractEnum.php index d22a7a7..4a46698 100644 --- a/src/AbstractEnum.php +++ b/src/AbstractEnum.php @@ -143,34 +143,53 @@ final public function getValue() } /** - * @return string[] + * @return array */ - final public function __sleep(): array + final public function __serialize(): array { - throw new EnumException(\sprintf('Enum "%s" cannot be serialized', static::class)); + return ['value' => $this->value]; } - final public function __wakeup(): void + /** + * @param array $data + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + final public function __unserialize(array $data): void { - throw new EnumException(\sprintf('Enum "%s" cannot be unserialized', static::class)); + $this->assertImmutable(); + $this->assertFinal(); + + $value = $data['value']; + + $this->checkValue($value); + + $this->value = $value; } /** - * @return array + * {@inheritdoc} */ - final public function __serialize(): array + final public function serialize(): string { - throw new EnumException(\sprintf('Enum "%s" cannot be serialized', static::class)); + return \serialize($this->value); } /** - * @param array $data + * {@inheritdoc} * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @param mixed $serialized */ - final public function __unserialize(array $data): void + public function unserialize($serialized): void { - throw new EnumException(\sprintf('Enum "%s" cannot be unserialized', static::class)); + $this->assertImmutable(); + $this->assertFinal(); + + $value = \unserialize($serialized, ['allowed_classes' => false]); + + $this->checkValue($value); + + $this->value = $value; } final public function __clone() diff --git a/src/Enum.php b/src/Enum.php index 1b8fdf6..d1138da 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -16,7 +16,7 @@ /** * Enum interface. */ -interface Enum +interface Enum extends \Serializable { /** * Check enum equality. diff --git a/tests/Enum/AbstractEnumTest.php b/tests/Enum/AbstractEnumTest.php index 7c18425..2200215 100644 --- a/tests/Enum/AbstractEnumTest.php +++ b/tests/Enum/AbstractEnumTest.php @@ -116,20 +116,16 @@ public function testStaticCreation(): void static::assertFalse($stub->isAnyOf([OrdinalEnumStub::VALUE_TWO(), OrdinalEnumStub::VALUE_THREE()])); } - public function testNoSerialization(): void + public function testSerialization(): void { - $this->expectException(EnumException::class); - $this->expectExceptionMessage('Enum "Gears\Enum\Tests\Stub\OrdinalEnumStub" cannot be serialized'); - - \serialize(OrdinalEnumStub::VALUE_ONE()); - } + $stub = OrdinalEnumStub::VALUE_ONE(); - public function testNoDeserialization(): void - { - $this->expectException(EnumException::class); - $this->expectExceptionMessage('Enum "Gears\Enum\Tests\Stub\OrdinalEnumStub" cannot be unserialized'); + $serialized = \version_compare(\PHP_VERSION, '7.4.0') >= 0 + ? 'O:37:"Gears\Enum\Tests\Stub\OrdinalEnumStub":1:{s:5:"value";s:3:"one";}' + : 'C:37:"Gears\Enum\Tests\Stub\OrdinalEnumStub":10:{s:3:"one";}'; - \unserialize('O:37:"Gears\Enum\Tests\Stub\OrdinalEnumStub":0:{}'); + static::assertSame($serialized, \serialize($stub)); + static::assertSame('one', (\unserialize($serialized))->getValue()); } public function testClone(): void