From a0667182b05d114c9b2ad0338d3608f9e36f64bb Mon Sep 17 00:00:00 2001 From: Denis Brumann <denis.brumann@sensiolabs.de> Date: Fri, 24 Jul 2020 11:38:54 +0200 Subject: [PATCH] Applies some code style changes. * Removes phpunit as dev-dependency * Changes new tests to match style of existing suite * Renames classes and methods in newly add Worker --- README.md | 19 +++++++++++++++- composer.json | 3 --- ...r.php => DisallowedClassesSubstitutor.php} | 22 +++++++++++-------- src/Unserialize.php | 5 +++-- tests/UnserializeTest.php | 20 +++++++---------- 5 files changed, 42 insertions(+), 27 deletions(-) rename src/{Worker.php => DisallowedClassesSubstitutor.php} (89%) diff --git a/README.md b/README.md index 7e14ae2..beff978 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,26 @@ Installation You can install this package via composer: ```bash -composer require brumann/polyfill-unserialize "^1.0" +composer require brumann/polyfill-unserialize "^2.0" ``` +Older versions +-------------- + +You can find the most recent 1.x versions in the branch with the same name: + + * [dbrumann/polyfill-unserialize/tree/1.x](https://github.com/dbrumann/polyfill-unserialize/tree/1.x) + +Upgrading +--------- + +Upgrading from 1.x to 2.0 should be seamless and require no changes to code +using the library. There are no changes to the public API, i.e. the names for +classes, methods and arguments as well as argument order and types remain the +same. Version 2.x uses a completely different approach for substituting +disallowed classes, which is why we chose to use a new major release to prevent +issues from unknown side effects in existing installations. + Known Issues ------------ diff --git a/composer.json b/composer.json index 0b3e098..ec4a2cf 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,5 @@ "minimum-stability": "stable", "require": { "php": "^5.3|^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8" } } diff --git a/src/Worker.php b/src/DisallowedClassesSubstitutor.php similarity index 89% rename from src/Worker.php rename to src/DisallowedClassesSubstitutor.php index 99a2cd3..9740d1a 100644 --- a/src/Worker.php +++ b/src/DisallowedClassesSubstitutor.php @@ -4,8 +4,10 @@ /** * Worker implementation for identifying and skipping false-positives * not to be substituted - like nested serializations in string literals. + * + * @internal This class should only be used by \Brumann\Polyfill\Unserialize */ -final class Worker +final class DisallowedClassesSubstitutor { const PATTERN_STRING = '#s:(\d+):(")#'; const PATTERN_OBJECT = '#(^|;)O:\d+:"([^"]*)":(\d+):\{#'; @@ -36,6 +38,7 @@ public function __construct($serialized, array $allowedClasses) { $this->serialized = $serialized; $this->allowedClasses = $allowedClasses; + $this->buildIgnoreItems(); $this->substituteObjects(); } @@ -43,7 +46,7 @@ public function __construct($serialized, array $allowedClasses) /** * @return string */ - public function get() + public function getSubstitutedSerialized() { return $this->serialized; } @@ -61,7 +64,7 @@ private function buildIgnoreItems() $offset = $end + 1; // serialized string nested in outer serialized string - if ($this->shallIgnore($start, $end)) { + if ($this->ignore($start, $end)) { continue; } @@ -90,7 +93,7 @@ private function substituteObjects() continue; } // serialized object nested in outer serialized string - if ($this->shallIgnore($start, $end)) { + if ($this->ignore($start, $end)) { continue; } @@ -99,7 +102,7 @@ private function substituteObjects() $offset = $start + $incompleteItemLength + 1; $this->replace($incompleteItem, $start, $end); - $this->shiftIgnoreItems($end, $incompleteItemLength - $completeLength); + $this->shift($end, $incompleteItemLength - $completeLength); } } @@ -110,26 +113,27 @@ private function substituteObjects() * @param int $start Start offset in serialized data * @param int $end End offset in serialized data */ - protected function replace($replacement, $start, $end) + private function replace($replacement, $start, $end) { $this->serialized = substr($this->serialized, 0, $start) . $replacement . substr($this->serialized, $end); } /** - * Whether given offset positions shall be ignored. + * Whether given offset positions should be ignored. * * @param int $start * @param int $end * @return bool */ - private function shallIgnore($start, $end) + private function ignore($start, $end) { foreach ($this->ignoreItems as $ignoreItem) { if ($ignoreItem[0] <= $start && $ignoreItem[1] >= $end) { return true; } } + return false; } @@ -141,7 +145,7 @@ private function shallIgnore($start, $end) * @param int $offset * @param int $size */ - private function shiftIgnoreItems($offset, $size) + private function shift($offset, $size) { foreach ($this->ignoreItems as &$ignoreItem) { // only focus on items starting after given offset diff --git a/src/Unserialize.php b/src/Unserialize.php index d78b90f..0a3bea7 100644 --- a/src/Unserialize.php +++ b/src/Unserialize.php @@ -32,7 +32,8 @@ public static function unserialize($serialized, array $options = array()) ); } - $worker = new Worker($serialized, $allowedClasses); - return \unserialize($worker->get()); + $worker = new DisallowedClassesSubstitutor($serialized, $allowedClasses); + + return \unserialize($worker->getSubstitutedSerialized()); } } diff --git a/tests/UnserializeTest.php b/tests/UnserializeTest.php index a42c16f..e9adfb3 100644 --- a/tests/UnserializeTest.php +++ b/tests/UnserializeTest.php @@ -232,32 +232,28 @@ public function test_double_unserialize_double_serialized() $this->assertInstanceOf('__PHP_Incomplete_Class', $unserialized); } - /** - * @test - */ - public function nestedSerializedObjectInSerializedObjectCanBeDeserialized() + public function test_nested_serialized_object_in_serialized_object_can_be_deserialized() { $inner = new \stdClass(); $outer = new \stdClass(); $inner->value = serialize('inner'); $outer->value = serialize(array('item', $inner)); $serialized = serialize($outer); - $options = array('allowed_classes' => false); + $unserialized = Unserialize::unserialize($serialized, $options); - self::assertEquals($outer,$unserialized); + + $this->assertEquals($outer,$unserialized); } - /** - * @test - */ - public function stringContainingSerializedLiteralsCanBeDeserialized() + public function test_string_containing_serialized_literals_can_be_deserialized() { $string = 'A serialized object might look like `...;O:9:"ClassName":0:{};...` - watch out!'; $serialized = serialize($string); - $options = array('allowed_classes' => false); + $unserialized = Unserialize::unserialize($serialized, $options); - self::assertEquals($string, $unserialized); + + $this->assertEquals($string, $unserialized); } }