Skip to content
This repository was archived by the owner on Jan 31, 2020. It is now read-only.

Commit 0172690

Browse files
committed
Merging develop to master in preparation for 2.9.0 release.
2 parents b215914 + 846380e commit 0172690

File tree

7 files changed

+182
-23
lines changed

7 files changed

+182
-23
lines changed

CHANGELOG.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22

33
All notable changes to this project will be documented in this file, in reverse chronological order by release.
44

5-
## 2.8.2 - TBD
5+
## 2.9.0 - 2018-05-14
66

77
### Added
88

9+
- [#37](https://github.com/zendframework/zend-serializer/pull/37) adds support to the `PhpSerialize` adapter to allow it to support the
10+
PHP 7 `$options` parameter of `unserialize`, and, specifically, the `allowed_classes` parameter.
11+
A new options class, `PhpSerializeOptions`, now allows setting the `unserialize_class_whitelist`
12+
option, which may be one of `true` (any class may be unserialized; current behavior), `false`
13+
(no class may be unserialized), or an `array` of class names that are explicitly allowed to
14+
be unserialized. An instance of this class may now be passed to the `PhpSerialize` constructor
15+
in order to set the intended/expected behavior.
16+
17+
### Changed
18+
919
- Nothing.
1020

1121
### Deprecated
@@ -18,10 +28,7 @@ All notable changes to this project will be documented in this file, in reverse
1828

1929
### Fixed
2030

21-
- [#34](https://github.com/zendframework/zend-serializer/pull/34)
22-
* redundant doctrine dependency
23-
* documentaion updates
24-
* travis CI update
31+
- [#34](https://github.com/zendframework/zend-serializer/pull/34) removes a redundant dependency on a Doctrine package.
2532

2633
## 2.8.1 - 2017-11-20
2734

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
},
4646
"extra": {
4747
"branch-alias": {
48-
"dev-master": "2.8-dev",
49-
"dev-develop": "2.9-dev"
48+
"dev-master": "2.9.x-dev",
49+
"dev-develop": "2.10.x-dev"
5050
},
5151
"zf": {
5252
"component": "Zend\\Serializer",

composer.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/book/adapter.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ The `Zend\Serializer\Adapter\PhpSerialize` adapter uses the built-in
1616
[serialize()](http://php.net/serialize)/[unserialize()](http://php.net/unserialize)
1717
functions, and is a good default adapter choice.
1818

19-
There are no configurable options for this adapter.
19+
Available options include:
20+
21+
Option | Data Type | Default Value | Description
22+
--------------------------- | ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------
23+
unserialize_class_whitelist | `array` or `bool` | `true` | The allowed classes for unserialize(), see [unserialize()](http://php.net/unserialize) for more information. Only available on PHP 7.0 or higher.
24+
2025

2126
## The IgBinary Adapter
2227

src/Adapter/PhpSerialize.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<?php
22
/**
3-
* Zend Framework (http://framework.zend.com/)
4-
*
5-
* @link http://github.com/zendframework/zf2 for the canonical source repository
6-
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7-
* @license http://framework.zend.com/license/new-bsd New BSD License
3+
* @see https://github.com/zendframework/zend-serializer for the canonical source repository
4+
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-serializer/blob/master/LICENSE.md New BSD License
86
*/
97

108
namespace Zend\Serializer\Adapter;
119

10+
use Traversable;
1211
use Zend\Serializer\Exception;
1312
use Zend\Stdlib\ErrorHandler;
1413

@@ -21,8 +20,15 @@ class PhpSerialize extends AbstractAdapter
2120
*/
2221
private static $serializedFalse = null;
2322

23+
/**
24+
* @var PhpSerializeOptions
25+
*/
26+
protected $options;
27+
2428
/**
2529
* Constructor
30+
*
31+
* @param array|Traversable|PhpSerializeOptions|null $options
2632
*/
2733
public function __construct($options = null)
2834
{
@@ -35,6 +41,36 @@ public function __construct($options = null)
3541
parent::__construct($options);
3642
}
3743

44+
/**
45+
* Set options
46+
*
47+
* @param array|Traversable|PhpSerializeOptions $options
48+
* @return PhpSerialize
49+
*/
50+
public function setOptions($options)
51+
{
52+
if (! $options instanceof PhpSerializeOptions) {
53+
$options = new PhpSerializeOptions($options);
54+
}
55+
56+
$this->options = $options;
57+
return $this;
58+
}
59+
60+
/**
61+
* Get options
62+
*
63+
* @return PhpSerializeOptions
64+
*/
65+
public function getOptions()
66+
{
67+
if ($this->options === null) {
68+
$this->options = new PhpSerializeOptions();
69+
}
70+
71+
return $this->options;
72+
}
73+
3874
/**
3975
* Serialize using serialize()
4076
*
@@ -85,7 +121,12 @@ public function unserialize($serialized)
85121
}
86122

87123
ErrorHandler::start(E_NOTICE);
88-
$ret = unserialize($serialized);
124+
125+
// The second parameter to unserialize() is only available on PHP 7.0 or higher
126+
$ret = PHP_MAJOR_VERSION >= 7
127+
? unserialize($serialized, ['allowed_classes' => $this->getOptions()->getUnserializeClassWhitelist()])
128+
: unserialize($serialized);
129+
89130
$err = ErrorHandler::stop();
90131
if ($ret === false) {
91132
throw new Exception\RuntimeException('Unserialization failed', 0, $err);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* @see https://github.com/zendframework/zend-serializer for the canonical source repository
4+
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-serializer/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
namespace Zend\Serializer\Adapter;
9+
10+
use Zend\Json\Json as ZendJson;
11+
use Zend\Serializer\Exception;
12+
13+
class PhpSerializeOptions extends AdapterOptions
14+
{
15+
/**
16+
* The list of allowed classes for unserialization (PHP 7.0+).
17+
*
18+
* Possible values:
19+
*
20+
* - `array` of class names that are allowed to be unserialized
21+
* - `true` if all classes should be allowed (behavior pre-PHP 7.0)
22+
* - `false` if no classes should be allowed
23+
*
24+
* @var string[]|bool
25+
*/
26+
protected $unserializeClassWhitelist = true;
27+
28+
/**
29+
* @param string[]|bool $unserializeClassWhitelist
30+
* @return void
31+
*/
32+
public function setUnserializeClassWhitelist($unserializeClassWhitelist)
33+
{
34+
if ($unserializeClassWhitelist !== true && PHP_MAJOR_VERSION < 7) {
35+
throw new Exception\InvalidArgumentException(
36+
'Class whitelist for unserialize() is only available on PHP versions 7.0 or higher.'
37+
);
38+
}
39+
40+
$this->unserializeClassWhitelist = $unserializeClassWhitelist;
41+
}
42+
43+
/**
44+
* @return string[]|bool
45+
*/
46+
public function getUnserializeClassWhitelist()
47+
{
48+
return $this->unserializeClassWhitelist;
49+
}
50+
}

test/Adapter/PhpSerializeTest.php

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<?php
22
/**
3-
* Zend Framework (http://framework.zend.com/)
4-
*
5-
* @link http://github.com/zendframework/zf2 for the canonical source repository
6-
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7-
* @license http://framework.zend.com/license/new-bsd New BSD License
3+
* @see https://github.com/zendframework/zend-serializer for the canonical source repository
4+
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
5+
* @license https://github.com/zendframework/zend-serializer/blob/master/LICENSE.md New BSD License
86
*/
97

108
namespace ZendTest\Serializer\Adapter;
119

1210
use PHPUnit\Framework\TestCase;
11+
use stdClass;
1312
use Zend\Serializer;
13+
use Zend\Serializer\Exception\InvalidArgumentException;
1414

1515
/**
16-
* @group Zend_Serializer
17-
* @covers Zend\Serializer\Adapter\PhpSerialize
16+
* @group Zend_Serializer
17+
* @covers \Zend\Serializer\Adapter\PhpSerialize
1818
*/
1919
class PhpSerializeTest extends TestCase
2020
{
@@ -165,4 +165,60 @@ public function testUnserializingInvalidStringRaisesException($string, $expected
165165
$this->expectExceptionMessage($expected);
166166
$this->adapter->unserialize($string);
167167
}
168+
169+
/**
170+
* @requires PHP 7.0
171+
*/
172+
public function testPhp7WillNotUnserializeObjectsWhenUnserializeWhitelistedClassesIsFalse()
173+
{
174+
$value = 'O:8:"stdClass":0:{}';
175+
$this->adapter->getOptions()->setUnserializeClassWhitelist(false);
176+
177+
$data = $this->adapter->unserialize($value);
178+
179+
$this->assertNotInstanceOf(stdClass::class, $data);
180+
$this->assertInstanceOf('__PHP_Incomplete_Class', $data);
181+
}
182+
183+
public function testWhenUnserializeClassWhiteListIsFalseButPHPIsPriorTo7AnExceptionIsRaised()
184+
{
185+
$value = 'O:8:"stdClass":0:{}';
186+
187+
if (PHP_MAJOR_VERSION >= 7) {
188+
$this->markTestSkipped(sprintf('Test %s is only needed in PHP versions prior to 7.0', __FUNCTION__));
189+
}
190+
191+
self::expectException(InvalidArgumentException::class);
192+
self::expectExceptionMessage('Class whitelist for unserialize() is only available on PHP 7.0 or higher.');
193+
$this->adapter->getOptions()->setUnserializeClassWhitelist(false);
194+
}
195+
196+
/**
197+
* @requires PHP 7.0
198+
*/
199+
public function testUnserializeWillNotUnserializeClassesThatAreNotInTheWhitelist()
200+
{
201+
$value = 'O:8:"stdClass":0:{}';
202+
203+
$this->adapter->getOptions()->setUnserializeClassWhitelist([\My\Dummy::class]);
204+
205+
$data = $this->adapter->unserialize($value);
206+
207+
$this->assertNotInstanceOf(stdClass::class, $data);
208+
$this->assertInstanceOf('__PHP_Incomplete_Class', $data);
209+
}
210+
211+
/**
212+
* @requires PHP 7.0
213+
*/
214+
public function testUnserializeWillUnserializeAnyClassWhenUnserializeWhitelistedClassesIsTrue()
215+
{
216+
$value = 'O:8:"stdClass":0:{}';
217+
218+
$this->adapter->getOptions()->setUnserializeClassWhitelist([stdClass::class]);
219+
220+
$data = $this->adapter->unserialize($value);
221+
$this->assertInstanceOf(stdClass::class, $data);
222+
$this->assertNotInstanceOf('__PHP_Incomplete_Class', $data);
223+
}
168224
}

0 commit comments

Comments
 (0)