-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #97 from short-pixel-optimizer/updates
- Loading branch information
Showing
13 changed files
with
458 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\Replacer":"replacer\/src","EnableMediaReplace\\FileSystem":"filesystem\/src"}}} | ||
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\FileSystem":"filesystem\/src","EnableMediaReplace\\Replacer":"replacer\/src"}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
178 changes: 178 additions & 0 deletions
178
build/shortpixel/replacer/src/Libraries/Unserialize/DisallowedClassesSubstitutor.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
<?php | ||
namespace EnableMediaReplace\Replacer\Libraries\Unserialize; | ||
|
||
|
||
/** | ||
* 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 DisallowedClassesSubstitutor | ||
{ | ||
const PATTERN_STRING = '#s:(\d+):(")#'; | ||
const PATTERN_OBJECT = '#(^|;)O:\d+:"([^"]*)":(\d+):\{#'; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $serialized; | ||
|
||
/** | ||
* @var string[] | ||
*/ | ||
private $allowedClasses; | ||
|
||
/** | ||
* Each array item consists of `[<offset-start>, <offset-end>]` and | ||
* marks start and end positions of items to be ignored. | ||
* | ||
* @var array[] | ||
*/ | ||
private $ignoreItems = array(); | ||
|
||
/** | ||
* @param string $serialized | ||
* @param string[] $allowedClasses | ||
*/ | ||
public function __construct($serialized, array $allowedClasses) | ||
{ | ||
$this->serialized = $serialized; | ||
$this->allowedClasses = $allowedClasses; | ||
|
||
$this->buildIgnoreItems(); | ||
$this->substituteObjects(); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getSubstitutedSerialized() | ||
{ | ||
return $this->serialized; | ||
} | ||
|
||
/** | ||
* Identifies items to be ignored - like nested serializations in string literals. | ||
*/ | ||
private function buildIgnoreItems() | ||
{ | ||
$offset = 0; | ||
while (preg_match(self::PATTERN_STRING, $this->serialized, $matches, PREG_OFFSET_CAPTURE, $offset)) { | ||
$length = (int)$matches[1][0]; // given length in serialized data (e.g. `s:123:"` --> 123) | ||
$start = $matches[2][1]; // offset position of quote character | ||
$end = $start + $length + 1; | ||
$offset = $end + 1; | ||
|
||
// serialized string nested in outer serialized string | ||
if ($this->ignore($start, $end)) { | ||
continue; | ||
} | ||
|
||
$this->ignoreItems[] = array($start, $end); | ||
} | ||
} | ||
|
||
/** | ||
* Substitutes disallowed object class names and respects items to be ignored. | ||
*/ | ||
private function substituteObjects() | ||
{ | ||
$offset = 0; | ||
while (preg_match(self::PATTERN_OBJECT, $this->serialized, $matches, PREG_OFFSET_CAPTURE, $offset)) { | ||
$completeMatch = (string)$matches[0][0]; | ||
$completeLength = strlen($completeMatch); | ||
$start = $matches[0][1]; | ||
$end = $start + $completeLength; | ||
$leftBorder = (string)$matches[1][0]; | ||
$className = (string)$matches[2][0]; | ||
$objectSize = (int)$matches[3][0]; | ||
$offset = $end + 1; | ||
|
||
// class name is actually allowed - skip this item | ||
if (in_array($className, $this->allowedClasses, true)) { | ||
continue; | ||
} | ||
// serialized object nested in outer serialized string | ||
if ($this->ignore($start, $end)) { | ||
continue; | ||
} | ||
|
||
$incompleteItem = $this->sanitizeItem($className, $leftBorder, $objectSize); | ||
$incompleteItemLength = strlen($incompleteItem); | ||
$offset = $start + $incompleteItemLength + 1; | ||
|
||
$this->replace($incompleteItem, $start, $end); | ||
$this->shift($end, $incompleteItemLength - $completeLength); | ||
} | ||
} | ||
|
||
/** | ||
* Replaces sanitized object class names in serialized data. | ||
* | ||
* @param string $replacement Sanitized object data | ||
* @param int $start Start offset in serialized data | ||
* @param int $end End offset in serialized data | ||
*/ | ||
private function replace($replacement, $start, $end) | ||
{ | ||
$this->serialized = substr($this->serialized, 0, $start) | ||
. $replacement . substr($this->serialized, $end); | ||
} | ||
|
||
/** | ||
* Whether given offset positions should be ignored. | ||
* | ||
* @param int $start | ||
* @param int $end | ||
* @return bool | ||
*/ | ||
private function ignore($start, $end) | ||
{ | ||
foreach ($this->ignoreItems as $ignoreItem) { | ||
if ($ignoreItem[0] <= $start && $ignoreItem[1] >= $end) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Shifts offset positions of ignore items by `$size`. | ||
* This is necessary whenever object class names have been | ||
* substituted which have a different length than before. | ||
* | ||
* @param int $offset | ||
* @param int $size | ||
*/ | ||
private function shift($offset, $size) | ||
{ | ||
foreach ($this->ignoreItems as &$ignoreItem) { | ||
// only focus on items starting after given offset | ||
if ($ignoreItem[0] < $offset) { | ||
continue; | ||
} | ||
$ignoreItem[0] += $size; | ||
$ignoreItem[1] += $size; | ||
} | ||
} | ||
|
||
/** | ||
* Sanitizes object class item. | ||
* | ||
* @param string $className | ||
* @param int $leftBorder | ||
* @param int $objectSize | ||
* @return string | ||
*/ | ||
private function sanitizeItem($className, $leftBorder, $objectSize) | ||
{ | ||
return sprintf( | ||
'%sO:22:"__PHP_Incomplete_Class":%d:{s:27:"__PHP_Incomplete_Class_Name";%s', | ||
$leftBorder, | ||
$objectSize + 1, // size of object + 1 for added string | ||
\serialize($className) | ||
); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
build/shortpixel/replacer/src/Libraries/Unserialize/LICENSE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2016-2019 Denis Brumann | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
153 changes: 153 additions & 0 deletions
153
build/shortpixel/replacer/src/Libraries/Unserialize/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
Polyfill unserialize [![Build Status](https://travis-ci.org/dbrumann/polyfill-unserialize.svg?branch=master)](https://travis-ci.org/dbrumann/polyfill-unserialize) | ||
=== | ||
|
||
Backports unserialize options introduced in PHP 7.0 to older PHP versions. | ||
This was originally designed as a Proof of Concept for Symfony Issue | ||
[#21090](https://github.com/symfony/symfony/pull/21090). | ||
|
||
You can use this package in projects that rely on PHP versions older than | ||
PHP 7.0. In case you are using PHP 7.0+ the original `unserialize()` will be | ||
used instead. | ||
|
||
From the [documentation](https://secure.php.net/manual/en/function.unserialize.php): | ||
|
||
> **Warning** | ||
> | ||
> Do not pass untrusted user input to unserialize() regardless of the options | ||
> value of allowed_classes. Unserialization can result in code being loaded and | ||
> executed due to object instantiation and autoloading, and a malicious user | ||
> may be able to exploit this. Use a safe, standard data interchange format | ||
> such as JSON (via json_decode() and json_encode()) if you need to pass | ||
> serialized data to the user. | ||
Requirements | ||
------------ | ||
|
||
- PHP 5.3+ | ||
|
||
Installation | ||
------------ | ||
|
||
You can install this package via composer: | ||
|
||
```bash | ||
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 | ||
------------ | ||
|
||
There is a mismatch in behavior when `allowed_classes` in `$options` is not | ||
of the correct type (array or boolean). PHP 7.0 will not issue a warning that | ||
an invalid type was provided. This library will trigger a warning, similar to | ||
the one PHP 7.1+ will raise and then continue, assuming `false` to make sure | ||
no classes are deserialized by accident. | ||
|
||
Tests | ||
----- | ||
|
||
You can run the test suite using PHPUnit. It is intentionally not bundled as | ||
dev dependency to make sure this package has the lowest restrictions on the | ||
implementing system as possible. | ||
|
||
Please read the [PHPUnit Manual](https://phpunit.de/manual/current/en/installation.html) | ||
for information how to install it on your system. | ||
|
||
Please make sure to pick a compatible version. If you use PHP 5.6 you should | ||
use PHPUnit 5.7.27 and for older PHP versions you should use PHPUnit 4.8.36. | ||
Older versions of PHPUnit might not support namespaces, meaning they will not | ||
work with the tests. Newer versions only support PHP 7.0+, where this library | ||
is not needed anymore. | ||
|
||
You can run the test suite as follows: | ||
|
||
```bash | ||
phpunit -c phpunit.xml.dist tests/ | ||
``` | ||
|
||
Contributing | ||
------------ | ||
|
||
This package is considered feature complete. As such I will likely not update | ||
it unless there are security issues. | ||
|
||
Should you find any bugs or have questions, feel free to submit an Issue or a | ||
Pull Request on GitHub. | ||
|
||
Development setup | ||
----------------- | ||
|
||
This library contains a docker setup for development purposes. This allows | ||
running the code on an older PHP version without having to install it locally. | ||
|
||
You can use the setup as follows: | ||
|
||
1. Go into the project directory | ||
|
||
1. Build the docker image | ||
|
||
``` | ||
docker build -t polyfill-unserialize . | ||
``` | ||
This will download a debian/jessie container with PHP 5.6 installed. Then | ||
it will download an appropriate version of phpunit for this PHP version. | ||
It will also download composer. It will set the working directory to `/opt/app`. | ||
The resulting image is tagged as `polyfill-unserialize`, which is the name | ||
we will refer to, when running the container. | ||
1. You can then run a container based on the image, which will run your tests | ||
``` | ||
docker run -it --rm --name polyfill-unserialize-dev -v "$PWD":/opt/app polyfill-unserialize | ||
``` | ||
This will run a docker container based on our previously built image. | ||
The container will automatically be removed after phpunit finishes. | ||
We name the image `polyfill-unserialize-dev`. This makes sure only one | ||
instance is running and that we can easily identify a running container by | ||
its name, e.g. in order to remove it manually. | ||
We mount our current directory into the container's working directory. | ||
This ensures that tests run on our current project's state. | ||
You can repeat the final step as often as you like in order to run the tests. | ||
The output should look something like this: | ||
```bash | ||
dbr:polyfill-unserialize/ (improvement/dev_setup*) $ docker run -it --rm --name polyfill-unserialize-dev -v "$PWD":/opt/app polyfill-unserialize | ||
Loading composer repositories with package information | ||
Installing dependencies (including require-dev) from lock file | ||
Nothing to install or update | ||
Generating autoload files | ||
PHPUnit 5.7.27 by Sebastian Bergmann and contributors. | ||
...................... 22 / 22 (100%) | ||
Time: 167 ms, Memory: 13.25MB | ||
OK (22 tests, 31 assertions) | ||
``` | ||
|
||
When you are done working on the project you can free up disk space by removing | ||
the initially built image: | ||
|
||
``` | ||
docker image rm polyfill-unserialize | ||
``` |
Oops, something went wrong.