From 9c7f4d0f41367e8e86e1c5235e8e442671d9ec8c Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Tue, 19 Sep 2023 15:16:33 +0200 Subject: [PATCH] chore: remove opis/closure Signed-off-by: Daniel Kesselberg --- composer.json | 1 - composer.lock | 67 +- composer/autoload_classmap.php | 10 - composer/autoload_files.php | 1 - composer/autoload_psr4.php | 1 - composer/autoload_static.php | 16 - composer/installed.json | 68 -- composer/installed.php | 13 +- opis/closure/LICENSE | 20 - opis/closure/NOTICE | 9 - opis/closure/autoload.php | 39 - opis/closure/functions.php | 41 - opis/closure/src/Analyzer.php | 62 -- opis/closure/src/ClosureContext.php | 34 - opis/closure/src/ClosureScope.php | 25 - opis/closure/src/ClosureStream.php | 99 -- opis/closure/src/ISecurityProvider.php | 25 - opis/closure/src/ReflectionClosure.php | 1093 ---------------------- opis/closure/src/SecurityException.php | 18 - opis/closure/src/SecurityProvider.php | 42 - opis/closure/src/SelfReference.php | 31 - opis/closure/src/SerializableClosure.php | 678 -------------- 22 files changed, 3 insertions(+), 2390 deletions(-) delete mode 100644 opis/closure/LICENSE delete mode 100644 opis/closure/NOTICE delete mode 100644 opis/closure/autoload.php delete mode 100644 opis/closure/functions.php delete mode 100644 opis/closure/src/Analyzer.php delete mode 100644 opis/closure/src/ClosureContext.php delete mode 100644 opis/closure/src/ClosureScope.php delete mode 100644 opis/closure/src/ClosureStream.php delete mode 100644 opis/closure/src/ISecurityProvider.php delete mode 100644 opis/closure/src/ReflectionClosure.php delete mode 100644 opis/closure/src/SecurityException.php delete mode 100644 opis/closure/src/SecurityProvider.php delete mode 100644 opis/closure/src/SelfReference.php delete mode 100644 opis/closure/src/SerializableClosure.php diff --git a/composer.json b/composer.json index 91c2e3e63..03f684727 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,6 @@ "microsoft/azure-storage-blob": "^1.5.4", "mlocati/ip-lib": "^1.18", "nextcloud/lognormalizer": "^1.0", - "opis/closure": "^3.6", "pear/archive_tar": "^1.4.9", "pear/pear-core-minimal": "^v1.10", "php-http/guzzle7-adapter": "^1.0.0", diff --git a/composer.lock b/composer.lock index 4bbe51d03..fa5a3c129 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1d15ddde624555f55fb048226b49cf2d", + "content-hash": "f1da6486273a61eba7ee49a03181a4e7", "packages": [ { "name": "aws/aws-crt-php", @@ -2332,71 +2332,6 @@ ], "time": "2020-12-02T09:34:47+00:00" }, - { - "name": "opis/closure", - "version": "3.6.3", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Opis\\Closure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.3" - }, - "time": "2022-01-27T09:35:39+00:00" - }, { "name": "pear/archive_tar", "version": "1.4.14", diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index 367a8e39b..28c913756 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -1996,16 +1996,6 @@ 'OpenStack\\ObjectStore\\v1\\Params' => $vendorDir . '/php-opencloud/openstack/src/ObjectStore/v1/Params.php', 'OpenStack\\ObjectStore\\v1\\Service' => $vendorDir . '/php-opencloud/openstack/src/ObjectStore/v1/Service.php', 'OpenStack\\OpenStack' => $vendorDir . '/php-opencloud/openstack/src/OpenStack.php', - 'Opis\\Closure\\Analyzer' => $vendorDir . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => $vendorDir . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => $vendorDir . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => $vendorDir . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => $vendorDir . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => $vendorDir . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => $vendorDir . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => $vendorDir . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => $vendorDir . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => $vendorDir . '/opis/closure/src/SerializableClosure.php', 'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php', diff --git a/composer/autoload_files.php b/composer/autoload_files.php index 3b738c3bc..b20dade95 100644 --- a/composer/autoload_files.php +++ b/composer/autoload_files.php @@ -119,7 +119,6 @@ 'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php', '8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php', - '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', ); diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php index c88654b51..524490acd 100644 --- a/composer/autoload_psr4.php +++ b/composer/autoload_psr4.php @@ -60,7 +60,6 @@ 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), - 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'), 'OpenStack\\' => array($vendorDir . '/php-opencloud/openstack/src'), 'Nextcloud\\LogNormalizer\\' => array($vendorDir . '/nextcloud/lognormalizer/src'), 'MicrosoftAzure\\Storage\\Common\\' => array($vendorDir . '/microsoft/azure-storage-common/src/Common'), diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 51aac5982..84ba13284 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -120,7 +120,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php', '8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php', - '538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', ); @@ -215,7 +214,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 ), 'O' => array ( - 'Opis\\Closure\\' => 13, 'OpenStack\\' => 10, ), 'N' => @@ -509,10 +507,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), - 'Opis\\Closure\\' => - array ( - 0 => __DIR__ . '/..' . '/opis/closure/src', - ), 'OpenStack\\' => array ( 0 => __DIR__ . '/..' . '/php-opencloud/openstack/src', @@ -2666,16 +2660,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'OpenStack\\ObjectStore\\v1\\Params' => __DIR__ . '/..' . '/php-opencloud/openstack/src/ObjectStore/v1/Params.php', 'OpenStack\\ObjectStore\\v1\\Service' => __DIR__ . '/..' . '/php-opencloud/openstack/src/ObjectStore/v1/Service.php', 'OpenStack\\OpenStack' => __DIR__ . '/..' . '/php-opencloud/openstack/src/OpenStack.php', - 'Opis\\Closure\\Analyzer' => __DIR__ . '/..' . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => __DIR__ . '/..' . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => __DIR__ . '/..' . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => __DIR__ . '/..' . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => __DIR__ . '/..' . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => __DIR__ . '/..' . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => __DIR__ . '/..' . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => __DIR__ . '/..' . '/opis/closure/src/SerializableClosure.php', 'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php', diff --git a/composer/installed.json b/composer/installed.json index 34fb23462..b12c53aa9 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -2428,74 +2428,6 @@ ], "install-path": "../nextcloud/lognormalizer" }, - { - "name": "opis/closure", - "version": "3.6.3", - "version_normalized": "3.6.3.0", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "time": "2022-01-27T09:35:39+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Opis\\Closure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.3" - }, - "install-path": "../opis/closure" - }, { "name": "pear/archive_tar", "version": "1.4.14", diff --git a/composer/installed.php b/composer/installed.php index d09d27abd..1e57d4b54 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'nextcloud/3rdparty', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '9f53e69990ad79b4e25647c72ffc455918592c24', + 'reference' => 'ed6ea207de9e7649d5f7321497a27f5612d6e100', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -310,7 +310,7 @@ 'nextcloud/3rdparty' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '9f53e69990ad79b4e25647c72ffc455918592c24', + 'reference' => 'ed6ea207de9e7649d5f7321497a27f5612d6e100', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -325,15 +325,6 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'opis/closure' => array( - 'pretty_version' => '3.6.3', - 'version' => '3.6.3.0', - 'reference' => '3d81e4309d2a927abbe66df935f4bb60082805ad', - 'type' => 'library', - 'install_path' => __DIR__ . '/../opis/closure', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'pear/archive_tar' => array( 'pretty_version' => '1.4.14', 'version' => '1.4.14.0', diff --git a/opis/closure/LICENSE b/opis/closure/LICENSE deleted file mode 100644 index 9c0a19ba2..000000000 --- a/opis/closure/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018-2019 Zindex Software - -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. diff --git a/opis/closure/NOTICE b/opis/closure/NOTICE deleted file mode 100644 index ae5caa628..000000000 --- a/opis/closure/NOTICE +++ /dev/null @@ -1,9 +0,0 @@ -Opis Closure -Copyright 2018-2019 Zindex Software - -This product includes software developed at -Zindex Software (http://zindex.software). - -This software was originally developed by Marius Sarca and Sorin Sarca -(Copyright 2014-2018). The copyright info was changed with the permission -of the original authors. \ No newline at end of file diff --git a/opis/closure/autoload.php b/opis/closure/autoload.php deleted file mode 100644 index 2354ea565..000000000 --- a/opis/closure/autoload.php +++ /dev/null @@ -1,39 +0,0 @@ -getClosureScopeClass(); - - $data = [ - 'reflection' => $reflection, - 'code' => $reflection->getCode(), - 'hasThis' => $reflection->isBindingRequired(), - 'context' => $reflection->getUseVariables(), - 'hasRefs' => false, - 'binding' => $reflection->getClosureThis(), - 'scope' => $scope ? $scope->getName() : null, - 'isStatic' => $reflection->isStatic(), - ]; - - return $data; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineCode(array &$data) - { - return null; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineContext(array &$data) - { - return null; - } - -} diff --git a/opis/closure/src/ClosureContext.php b/opis/closure/src/ClosureContext.php deleted file mode 100644 index d8f13d9db..000000000 --- a/opis/closure/src/ClosureContext.php +++ /dev/null @@ -1,34 +0,0 @@ -scope = new ClosureScope(); - $this->locks = 0; - } -} \ No newline at end of file diff --git a/opis/closure/src/ClosureScope.php b/opis/closure/src/ClosureScope.php deleted file mode 100644 index 3afd9b550..000000000 --- a/opis/closure/src/ClosureScope.php +++ /dev/null @@ -1,25 +0,0 @@ -content = "length = strlen($this->content); - return true; - } - - public function stream_read($count) - { - $value = substr($this->content, $this->pointer, $count); - $this->pointer += $count; - return $value; - } - - public function stream_eof() - { - return $this->pointer >= $this->length; - } - - public function stream_set_option($option, $arg1, $arg2) - { - return false; - } - - public function stream_stat() - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function url_stat($path, $flags) - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function stream_seek($offset, $whence = SEEK_SET) - { - $crt = $this->pointer; - - switch ($whence) { - case SEEK_SET: - $this->pointer = $offset; - break; - case SEEK_CUR: - $this->pointer += $offset; - break; - case SEEK_END: - $this->pointer = $this->length + $offset; - break; - } - - if ($this->pointer < 0 || $this->pointer >= $this->length) { - $this->pointer = $crt; - return false; - } - - return true; - } - - public function stream_tell() - { - return $this->pointer; - } - - public static function register() - { - if (!static::$isRegistered) { - static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__); - } - } - -} diff --git a/opis/closure/src/ISecurityProvider.php b/opis/closure/src/ISecurityProvider.php deleted file mode 100644 index 54e2e20ae..000000000 --- a/opis/closure/src/ISecurityProvider.php +++ /dev/null @@ -1,25 +0,0 @@ -isStaticClosure === null) { - $this->isStaticClosure = strtolower(substr($this->getCode(), 0, 6)) === 'static'; - } - - return $this->isStaticClosure; - } - - public function isShortClosure() - { - if ($this->isShortClosure === null) { - $code = $this->getCode(); - if ($this->isStatic()) { - $code = substr($code, 6); - } - $this->isShortClosure = strtolower(substr(trim($code), 0, 2)) === 'fn'; - } - - return $this->isShortClosure; - } - - /** - * @return string - */ - public function getCode() - { - if($this->code !== null){ - return $this->code; - } - - $fileName = $this->getFileName(); - $line = $this->getStartLine() - 1; - - $className = null; - - if (null !== $className = $this->getClosureScopeClass()) { - $className = '\\' . trim($className->getName(), '\\'); - } - - $builtin_types = self::getBuiltinTypes(); - $class_keywords = ['self', 'static', 'parent']; - - $ns = $this->getNamespaceName(); - $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns); - - $_file = var_export($fileName, true); - $_dir = var_export(dirname($fileName), true); - $_namespace = var_export($ns, true); - $_class = var_export(trim($className, '\\'), true); - $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}'; - $_method = ($className == '' ? '' : trim($className, '\\') . '::') . $_function; - $_function = var_export($_function, true); - $_method = var_export($_method, true); - $_trait = null; - - $tokens = $this->getTokens(); - $state = $lastState = 'start'; - $inside_structure = false; - $isShortClosure = false; - $inside_structure_mark = 0; - $open = 0; - $code = ''; - $id_start = $id_start_ci = $id_name = $context = ''; - $classes = $functions = $constants = null; - $use = array(); - $lineAdd = 0; - $isUsingScope = false; - $isUsingThisObject = false; - - for($i = 0, $l = count($tokens); $i < $l; $i++) { - $token = $tokens[$i]; - switch ($state) { - case 'start': - if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) { - $code .= $token[1]; - $state = $token[0] === T_FUNCTION ? 'function' : 'static'; - } elseif ($token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } - break; - case 'static': - if ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_FUNCTION) { - $code .= $token[1]; - if ($token[0] === T_FUNCTION) { - $state = 'function'; - } - } elseif ($token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } else { - $code = ''; - $state = 'start'; - } - break; - case 'function': - switch ($token[0]){ - case T_STRING: - $code = ''; - $state = 'named_function'; - break; - case '(': - $code .= '('; - $state = 'closure_args'; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'named_function': - if($token[0] === T_FUNCTION || $token[0] === T_STATIC){ - $code = $token[1]; - $state = $token[0] === T_FUNCTION ? 'function' : 'static'; - } elseif ($token[0] === T_FN) { - $isShortClosure = true; - $code .= $token[1]; - $state = 'closure_args'; - } - break; - case 'closure_args': - switch ($token[0]){ - case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); - $context = 'args'; - $state = 'id_name'; - $lastState = 'closure_args'; - break; - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'args'; - $state = 'id_name'; - $lastState = 'closure_args'; - break; - case T_USE: - $code .= $token[1]; - $state = 'use'; - break; - case T_DOUBLE_ARROW: - $code .= $token[1]; - if ($isShortClosure) { - $state = 'closure'; - } - break; - case ':': - $code .= ':'; - $state = 'return'; - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'use': - switch ($token[0]){ - case T_VARIABLE: - $use[] = substr($token[1], 1); - $code .= $token[1]; - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - case ':': - $code .= ':'; - $state = 'return'; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - break; - } - break; - case 'return': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'return_type'; - $state = 'id_name'; - $lastState = 'return'; - break 2; - case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); - $context = 'return_type'; - $state = 'id_name'; - $lastState = 'return'; - break 2; - case T_DOUBLE_ARROW: - $code .= $token[1]; - if ($isShortClosure) { - $state = 'closure'; - } - break; - case '{': - $code .= '{'; - $state = 'closure'; - $open++; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - break; - } - break; - case 'closure': - switch ($token[0]){ - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - case '{': - $code .= is_array($token) ? $token[1] : $token; - $open++; - break; - case '}': - $code .= '}'; - if(--$open === 0 && !$isShortClosure){ - break 3; - } elseif ($inside_structure) { - $inside_structure = !($open === $inside_structure_mark); - } - break; - case '(': - case '[': - $code .= $token[0]; - if ($isShortClosure) { - $open++; - } - break; - case ')': - case ']': - if ($isShortClosure) { - if ($open === 0) { - break 3; - } - --$open; - } - $code .= $token[0]; - break; - case ',': - case ';': - if ($isShortClosure && $open === 0) { - break 3; - } - $code .= $token[0]; - break; - case T_LINE: - $code .= $token[2] - $line + $lineAdd; - break; - case T_FILE: - $code .= $_file; - break; - case T_DIR: - $code .= $_dir; - break; - case T_NS_C: - $code .= $_namespace; - break; - case T_CLASS_C: - $code .= $inside_structure ? $token[1] : $_class; - break; - case T_FUNC_C: - $code .= $inside_structure ? $token[1] : $_function; - break; - case T_METHOD_C: - $code .= $inside_structure ? $token[1] : $_method; - break; - case T_COMMENT: - if (substr($token[1], 0, 8) === '#trackme') { - $timestamp = time(); - $code .= '/**' . PHP_EOL; - $code .= '* Date : ' . date(DATE_W3C, $timestamp) . PHP_EOL; - $code .= '* Timestamp : ' . $timestamp . PHP_EOL; - $code .= '* Line : ' . ($line + 1) . PHP_EOL; - $code .= '* File : ' . $_file . PHP_EOL . '*/' . PHP_EOL; - $lineAdd += 5; - } else { - $code .= $token[1]; - } - break; - case T_VARIABLE: - if($token[1] == '$this' && !$inside_structure){ - $isUsingThisObject = true; - } - $code .= $token[1]; - break; - case T_STATIC: - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $context = 'root'; - $state = 'id_name'; - $lastState = 'closure'; - break 2; - case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); - $context = 'root'; - $state = 'id_name'; - $lastState = 'closure'; - break 2; - case T_NEW: - $code .= $token[1]; - $context = 'new'; - $state = 'id_start'; - $lastState = 'closure'; - break 2; - case T_USE: - $code .= $token[1]; - $context = 'use'; - $state = 'id_start'; - $lastState = 'closure'; - break; - case T_INSTANCEOF: - case T_INSTEADOF: - $code .= $token[1]; - $context = 'instanceof'; - $state = 'id_start'; - $lastState = 'closure'; - break; - case T_OBJECT_OPERATOR: - case T_DOUBLE_COLON: - $code .= $token[1]; - $lastState = 'closure'; - $state = 'ignore_next'; - break; - case T_FUNCTION: - $code .= $token[1]; - $state = 'closure_args'; - if (!$inside_structure) { - $inside_structure = true; - $inside_structure_mark = $open; - } - break; - case T_TRAIT_C: - if ($_trait === null) { - $startLine = $this->getStartLine(); - $endLine = $this->getEndLine(); - $structures = $this->getStructures(); - - $_trait = ''; - - foreach ($structures as &$struct) { - if ($struct['type'] === 'trait' && - $struct['start'] <= $startLine && - $struct['end'] >= $endLine - ) { - $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name']; - break; - } - } - - $_trait = var_export($_trait, true); - } - - $code .= $_trait; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - case 'ignore_next': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_CLASS: - case T_NEW: - case T_STATIC: - case T_VARIABLE: - case T_STRING: - case T_CLASS_C: - case T_FILE: - case T_DIR: - case T_METHOD_C: - case T_FUNC_C: - case T_FUNCTION: - case T_INSTANCEOF: - case T_LINE: - case T_NS_C: - case T_TRAIT_C: - case T_USE: - $code .= $token[1]; - $state = $lastState; - break; - default: - $state = $lastState; - $i--; - } - break; - case 'id_start': - switch ($token[0]){ - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $code .= $token[1]; - break; - case T_NS_SEPARATOR: - case T_NAME_FULLY_QUALIFIED: - case T_STRING: - case T_STATIC: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $state = 'id_name'; - break 2; - case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); - $state = 'id_name'; - break 2; - case T_VARIABLE: - $code .= $token[1]; - $state = $lastState; - break; - case T_CLASS: - $code .= $token[1]; - $state = 'anonymous'; - break; - default: - $i--;//reprocess last - $state = 'id_name'; - } - break; - case 'id_name': - switch ($token[0]){ - case T_NAME_QUALIFIED: - case T_NS_SEPARATOR: - case T_STRING: - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - $id_name .= $token[1]; - break; - case '(': - if ($isShortClosure) { - $open++; - } - if($context === 'new' || false !== strpos($id_name, '\\')){ - if($id_start_ci === 'self' || $id_start_ci === 'static') { - if (!$inside_structure) { - $isUsingScope = true; - } - } elseif ($id_start !== '\\' && !in_array($id_start_ci, $class_keywords)) { - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } else { - if($id_start !== '\\'){ - if($functions === null){ - $functions = $this->getFunctions(); - } - if(isset($functions[$id_start_ci])){ - $id_start = $functions[$id_start_ci]; - } elseif ($nsf !== '\\' && function_exists($nsf . '\\' . $id_start)) { - $id_start = $nsf . '\\' . $id_start; - // Cache it to functions array - $functions[$id_start_ci] = $id_start; - } - } - } - $code .= $id_start . $id_name . '('; - $state = $lastState; - break; - case T_VARIABLE: - case T_DOUBLE_COLON: - if($id_start !== '\\') { - if($id_start_ci === 'self' || $id_start_ci === 'parent'){ - if (!$inside_structure) { - $isUsingScope = true; - } - } elseif ($id_start_ci === 'static') { - if (!$inside_structure) { - $isUsingScope = $token[0] === T_DOUBLE_COLON; - } - } elseif (!(\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))){ - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } - - $code .= $id_start . $id_name . $token[1]; - $state = $token[0] === T_DOUBLE_COLON ? 'ignore_next' : $lastState; - break; - default: - if($id_start !== '\\' && !defined($id_start)){ - if($constants === null){ - $constants = $this->getConstants(); - } - if(isset($constants[$id_start])){ - $id_start = $constants[$id_start]; - } elseif($context === 'new'){ - if(in_array($id_start_ci, $class_keywords)) { - if (!$inside_structure) { - $isUsingScope = true; - } - } else { - if ($classes === null) { - $classes = $this->getClasses(); - } - if (isset($classes[$id_start_ci])) { - $id_start = $classes[$id_start_ci]; - } - if ($id_start[0] !== '\\') { - $id_start = $nsf . '\\' . $id_start; - } - } - } elseif($context === 'use' || - $context === 'instanceof' || - $context === 'args' || - $context === 'return_type' || - $context === 'extends' || - $context === 'root' - ){ - if(in_array($id_start_ci, $class_keywords)){ - if (!$inside_structure && !$id_start_ci === 'static') { - $isUsingScope = true; - } - } elseif (!(\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))){ - if($classes === null){ - $classes = $this->getClasses(); - } - if(isset($classes[$id_start_ci])){ - $id_start = $classes[$id_start_ci]; - } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; - } - } - } - } - $code .= $id_start . $id_name; - $state = $lastState; - $i--;//reprocess last token - } - break; - case 'anonymous': - switch ($token[0]) { - case T_NS_SEPARATOR: - case T_STRING: - $id_start = $token[1]; - $id_start_ci = strtolower($id_start); - $id_name = ''; - $state = 'id_name'; - $context = 'extends'; - $lastState = 'anonymous'; - break; - case '{': - $state = 'closure'; - if (!$inside_structure) { - $inside_structure = true; - $inside_structure_mark = $open; - } - $i--; - break; - default: - $code .= is_array($token) ? $token[1] : $token; - } - break; - } - } - - if ($isShortClosure) { - $this->useVariables = $this->getStaticVariables(); - } else { - $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); - } - - $this->isShortClosure = $isShortClosure; - $this->isBindingRequired = $isUsingThisObject; - $this->isScopeRequired = $isUsingScope; - $this->code = $code; - - return $this->code; - } - - /** - * @return array - */ - private static function getBuiltinTypes() - { - // PHP 5 - if (\PHP_MAJOR_VERSION === 5) { - return ['array', 'callable']; - } - - // PHP 8 - if (\PHP_MAJOR_VERSION === 8) { - return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null']; - } - - // PHP 7 - switch (\PHP_MINOR_VERSION) { - case 0: - return ['array', 'callable', 'string', 'int', 'bool', 'float']; - case 1: - return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void']; - default: - return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object']; - } - } - - /** - * @return array - */ - public function getUseVariables() - { - if($this->useVariables !== null){ - return $this->useVariables; - } - - $tokens = $this->getTokens(); - $use = array(); - $state = 'start'; - - foreach ($tokens as &$token) { - $is_array = is_array($token); - - switch ($state) { - case 'start': - if ($is_array && $token[0] === T_USE) { - $state = 'use'; - } - break; - case 'use': - if ($is_array) { - if ($token[0] === T_VARIABLE) { - $use[] = substr($token[1], 1); - } - } elseif ($token == ')') { - break 2; - } - break; - } - } - - $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); - - return $this->useVariables; - } - - /** - * return bool - */ - public function isBindingRequired() - { - if($this->isBindingRequired === null){ - $this->getCode(); - } - - return $this->isBindingRequired; - } - - /** - * return bool - */ - public function isScopeRequired() - { - if($this->isScopeRequired === null){ - $this->getCode(); - } - - return $this->isScopeRequired; - } - - /** - * @return string - */ - protected function getHashedFileName() - { - if ($this->hashedName === null) { - $this->hashedName = sha1($this->getFileName()); - } - - return $this->hashedName; - } - - /** - * @return array - */ - protected function getFileTokens() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$files[$key])) { - static::$files[$key] = token_get_all(file_get_contents($this->getFileName())); - } - - return static::$files[$key]; - } - - /** - * @return array - */ - protected function getTokens() - { - if ($this->tokens === null) { - $tokens = $this->getFileTokens(); - $startLine = $this->getStartLine(); - $endLine = $this->getEndLine(); - $results = array(); - $start = false; - - foreach ($tokens as &$token) { - if (!is_array($token)) { - if ($start) { - $results[] = $token; - } - - continue; - } - - $line = $token[2]; - - if ($line <= $endLine) { - if ($line >= $startLine) { - $start = true; - $results[] = $token; - } - - continue; - } - - break; - } - - $this->tokens = $results; - } - - return $this->tokens; - } - - /** - * @return array - */ - protected function getClasses() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$classes[$key])) { - $this->fetchItems(); - } - - return static::$classes[$key]; - } - - /** - * @return array - */ - protected function getFunctions() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$functions[$key])) { - $this->fetchItems(); - } - - return static::$functions[$key]; - } - - /** - * @return array - */ - protected function getConstants() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$constants[$key])) { - $this->fetchItems(); - } - - return static::$constants[$key]; - } - - /** - * @return array - */ - protected function getStructures() - { - $key = $this->getHashedFileName(); - - if (!isset(static::$structures[$key])) { - $this->fetchItems(); - } - - return static::$structures[$key]; - } - - protected function fetchItems() - { - $key = $this->getHashedFileName(); - - $classes = array(); - $functions = array(); - $constants = array(); - $structures = array(); - $tokens = $this->getFileTokens(); - - $open = 0; - $state = 'start'; - $lastState = ''; - $prefix = ''; - $name = ''; - $alias = ''; - $isFunc = $isConst = false; - - $startLine = $endLine = 0; - $structType = $structName = ''; - $structIgnore = false; - - foreach ($tokens as $token) { - - switch ($state) { - case 'start': - switch ($token[0]) { - case T_CLASS: - case T_INTERFACE: - case T_TRAIT: - $state = 'before_structure'; - $startLine = $token[2]; - $structType = $token[0] == T_CLASS - ? 'class' - : ($token[0] == T_INTERFACE ? 'interface' : 'trait'); - break; - case T_USE: - $state = 'use'; - $prefix = $name = $alias = ''; - $isFunc = $isConst = false; - break; - case T_FUNCTION: - $state = 'structure'; - $structIgnore = true; - break; - case T_NEW: - $state = 'new'; - break; - case T_OBJECT_OPERATOR: - case T_DOUBLE_COLON: - $state = 'invoke'; - break; - } - break; - case 'use': - switch ($token[0]) { - case T_FUNCTION: - $isFunc = true; - break; - case T_CONST: - $isConst = true; - break; - case T_NS_SEPARATOR: - $name .= $token[1]; - break; - case T_STRING: - $name .= $token[1]; - $alias = $token[1]; - break; - case T_NAME_QUALIFIED: - $name .= $token[1]; - $pieces = explode('\\', $token[1]); - $alias = end($pieces); - break; - case T_AS: - $lastState = 'use'; - $state = 'alias'; - break; - case '{': - $prefix = $name; - $name = $alias = ''; - $state = 'use-group'; - break; - case ',': - case ';': - if ($name === '' || $name[0] !== '\\') { - $name = '\\' . $name; - } - - if ($alias !== '') { - if ($isFunc) { - $functions[strtolower($alias)] = $name; - } elseif ($isConst) { - $constants[$alias] = $name; - } else { - $classes[strtolower($alias)] = $name; - } - } - $name = $alias = ''; - $state = $token === ';' ? 'start' : 'use'; - break; - } - break; - case 'use-group': - switch ($token[0]) { - case T_NS_SEPARATOR: - $name .= $token[1]; - break; - case T_NAME_QUALIFIED: - $name .= $token[1]; - $pieces = explode('\\', $token[1]); - $alias = end($pieces); - break; - case T_STRING: - $name .= $token[1]; - $alias = $token[1]; - break; - case T_AS: - $lastState = 'use-group'; - $state = 'alias'; - break; - case ',': - case '}': - - if ($prefix === '' || $prefix[0] !== '\\') { - $prefix = '\\' . $prefix; - } - - if ($alias !== '') { - if ($isFunc) { - $functions[strtolower($alias)] = $prefix . $name; - } elseif ($isConst) { - $constants[$alias] = $prefix . $name; - } else { - $classes[strtolower($alias)] = $prefix . $name; - } - } - $name = $alias = ''; - $state = $token === '}' ? 'use' : 'use-group'; - break; - } - break; - case 'alias': - if ($token[0] === T_STRING) { - $alias = $token[1]; - $state = $lastState; - } - break; - case 'new': - switch ($token[0]) { - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - break 2; - case T_CLASS: - $state = 'structure'; - $structIgnore = true; - break; - default: - $state = 'start'; - } - break; - case 'invoke': - switch ($token[0]) { - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - break 2; - default: - $state = 'start'; - } - break; - case 'before_structure': - if ($token[0] == T_STRING) { - $structName = $token[1]; - $state = 'structure'; - } - break; - case 'structure': - switch ($token[0]) { - case '{': - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - $open++; - break; - case '}': - if (--$open == 0) { - if(!$structIgnore){ - $structures[] = array( - 'type' => $structType, - 'name' => $structName, - 'start' => $startLine, - 'end' => $endLine, - ); - } - $structIgnore = false; - $state = 'start'; - } - break; - default: - if (is_array($token)) { - $endLine = $token[2]; - } - } - break; - } - } - - static::$classes[$key] = $classes; - static::$functions[$key] = $functions; - static::$constants[$key] = $constants; - static::$structures[$key] = $structures; - } - - private function parseNameQualified($token) - { - $pieces = explode('\\', $token); - - $id_start = array_shift($pieces); - - $id_start_ci = strtolower($id_start); - - $id_name = '\\' . implode('\\', $pieces); - - return [$id_start, $id_start_ci, $id_name]; - } -} diff --git a/opis/closure/src/SecurityException.php b/opis/closure/src/SecurityException.php deleted file mode 100644 index b65f5cb83..000000000 --- a/opis/closure/src/SecurityException.php +++ /dev/null @@ -1,18 +0,0 @@ -secret = $secret; - } - - /** - * @inheritdoc - */ - public function sign($closure) - { - return array( - 'closure' => $closure, - 'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)), - ); - } - - /** - * @inheritdoc - */ - public function verify(array $data) - { - return base64_encode(hash_hmac('sha256', $data['closure'], $this->secret, true)) === $data['hash']; - } -} \ No newline at end of file diff --git a/opis/closure/src/SelfReference.php b/opis/closure/src/SelfReference.php deleted file mode 100644 index 425edf275..000000000 --- a/opis/closure/src/SelfReference.php +++ /dev/null @@ -1,31 +0,0 @@ -hash = $hash; - } -} \ No newline at end of file diff --git a/opis/closure/src/SerializableClosure.php b/opis/closure/src/SerializableClosure.php deleted file mode 100644 index 1025ff51b..000000000 --- a/opis/closure/src/SerializableClosure.php +++ /dev/null @@ -1,678 +0,0 @@ -closure = $closure; - if (static::$context !== null) { - $this->scope = static::$context->scope; - $this->scope->toserialize++; - } - } - - /** - * Get the Closure object - * - * @return Closure The wrapped closure - */ - public function getClosure() - { - return $this->closure; - } - - /** - * Get the reflector for closure - * - * @return ReflectionClosure - */ - public function getReflector() - { - if ($this->reflector === null) { - $this->reflector = new ReflectionClosure($this->closure); - $this->code = null; - } - - return $this->reflector; - } - - /** - * Implementation of magic method __invoke() - */ - public function __invoke() - { - return call_user_func_array($this->closure, func_get_args()); - } - - /** - * Implementation of Serializable::serialize() - * - * @return string The serialized closure - */ - public function serialize() - { - if ($this->scope === null) { - $this->scope = new ClosureScope(); - $this->scope->toserialize++; - } - - $this->scope->serializations++; - - $scope = $object = null; - $reflector = $this->getReflector(); - - if($reflector->isBindingRequired()){ - $object = $reflector->getClosureThis(); - static::wrapClosures($object, $this->scope); - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } else { - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } - - $this->reference = spl_object_hash($this->closure); - - $this->scope[$this->closure] = $this; - - $use = $this->transformUseVariables($reflector->getUseVariables()); - $code = $reflector->getCode(); - - $this->mapByReference($use); - - $ret = \serialize(array( - 'use' => $use, - 'function' => $code, - 'scope' => $scope, - 'this' => $object, - 'self' => $this->reference, - )); - - if (static::$securityProvider !== null) { - $data = static::$securityProvider->sign($ret); - $ret = '@' . $data['hash'] . '.' . $data['closure']; - } - - if (!--$this->scope->serializations && !--$this->scope->toserialize) { - $this->scope = null; - } - - return $ret; - } - - /** - * Transform the use variables before serialization. - * - * @param array $data The Closure's use variables - * @return array - */ - protected function transformUseVariables($data) - { - return $data; - } - - /** - * Implementation of Serializable::unserialize() - * - * @param string $data Serialized data - * @throws SecurityException - */ - public function unserialize($data) - { - ClosureStream::register(); - - if (static::$securityProvider !== null) { - if ($data[0] !== '@') { - throw new SecurityException("The serialized closure is not signed. ". - "Make sure you use a security provider for both serialization and unserialization."); - } - - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !static::$securityProvider->verify($data)) { - throw new SecurityException("Your serialized closure might have been modified and it's unsafe to be unserialized. " . - "Make sure you use the same security provider, with the same settings, " . - "both for serialization and unserialization."); - } - - $data = $data['closure']; - } elseif ($data[0] === '@') { - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !isset($data['closure']) || !isset($data['hash'])) { - throw new SecurityException('Invalid signed closure'); - } - - $data = $data['closure']; - } - - $this->code = \unserialize($data); - - // unset data - unset($data); - - $this->code['objects'] = array(); - - if ($this->code['use']) { - $this->scope = new ClosureScope(); - $this->code['use'] = $this->resolveUseVariables($this->code['use']); - $this->mapPointers($this->code['use']); - extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); - $this->scope = null; - } - - $this->closure = include(ClosureStream::STREAM_PROTO . '://' . $this->code['function']); - - if($this->code['this'] === $this){ - $this->code['this'] = null; - } - - $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); - - if(!empty($this->code['objects'])){ - foreach ($this->code['objects'] as $item){ - $item['property']->setValue($item['instance'], $item['object']->getClosure()); - } - } - - $this->code = $this->code['function']; - } - - /** - * Resolve the use variables after unserialization. - * - * @param array $data The Closure's transformed use variables - * @return array - */ - protected function resolveUseVariables($data) - { - return $data; - } - - /** - * Wraps a closure and sets the serialization context (if any) - * - * @param Closure $closure Closure to be wrapped - * - * @return self The wrapped closure - */ - public static function from(Closure $closure) - { - if (static::$context === null) { - $instance = new static($closure); - } elseif (isset(static::$context->scope[$closure])) { - $instance = static::$context->scope[$closure]; - } else { - $instance = new static($closure); - static::$context->scope[$closure] = $instance; - } - - return $instance; - } - - /** - * Increments the context lock counter or creates a new context if none exist - */ - public static function enterContext() - { - if (static::$context === null) { - static::$context = new ClosureContext(); - } - - static::$context->locks++; - } - - /** - * Decrements the context lock counter and destroy the context when it reaches to 0 - */ - public static function exitContext() - { - if (static::$context !== null && !--static::$context->locks) { - static::$context = null; - } - } - - /** - * @param string $secret - */ - public static function setSecretKey($secret) - { - if(static::$securityProvider === null){ - static::$securityProvider = new SecurityProvider($secret); - } - } - - /** - * @param ISecurityProvider $securityProvider - */ - public static function addSecurityProvider(ISecurityProvider $securityProvider) - { - static::$securityProvider = $securityProvider; - } - - /** - * Remove security provider - */ - public static function removeSecurityProvider() - { - static::$securityProvider = null; - } - - /** - * @return null|ISecurityProvider - */ - public static function getSecurityProvider() - { - return static::$securityProvider; - } - - /** - * Wrap closures - * - * @internal - * @param $data - * @param ClosureScope|SplObjectStorage|null $storage - */ - public static function wrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof Closure){ - $data = static::from($data); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::wrapClosures($value, $storage); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif($data instanceof \stdClass){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $data = $storage[$data] = clone($data); - foreach ($data as &$value){ - static::wrapClosures($value, $storage); - } - unset($value); - } elseif (is_object($data) && ! $data instanceof static){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $instance = $data; - $reflection = new ReflectionObject($instance); - if(!$reflection->isUserDefined()){ - $storage[$instance] = $data; - return; - } - $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - static::wrapClosures($value, $storage); - } - $property->setValue($data, $value); - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Unwrap closures - * - * @internal - * @param $data - * @param SplObjectStorage|null $storage - */ - public static function unwrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof static){ - $data = $data->getClosure(); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::unwrapClosures($value, $storage); - } - unset($data[self::ARRAY_RECURSIVE_KEY]); - }elseif ($data instanceof \stdClass){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - foreach ($data as &$property){ - static::unwrapClosures($property, $storage); - } - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - $reflection = new ReflectionObject($data); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $value = $property->getValue($data); - if(is_array($value) || is_object($value)){ - static::unwrapClosures($value, $storage); - $property->setValue($data, $value); - } - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Creates a new closure from arbitrary code, - * emulating create_function, but without using eval - * - * @param string$args - * @param string $code - * @return Closure - */ - public static function createClosure($args, $code) - { - ClosureStream::register(); - return include(ClosureStream::STREAM_PROTO . '://function(' . $args. '){' . $code . '};'); - } - - /** - * Internal method used to map closure pointers - * @internal - * @param $data - */ - protected function mapPointers(&$data) - { - $scope = $this->scope; - - if ($data instanceof static) { - $data = &$data->closure; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } elseif ($value instanceof static) { - $data[$key] = &$value->closure; - } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data[$key] = &$this->closure; - } else { - $this->mapPointers($value); - } - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - foreach ($data as $key => &$value){ - if ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data->{$key} = &$this->closure; - } elseif(is_array($value) || is_object($value)) { - $this->mapPointers($value); - } - } - unset($value); - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - $reflection = new ReflectionObject($data); - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $item = $property->getValue($data); - if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { - $this->code['objects'][] = array( - 'instance' => $data, - 'property' => $property, - 'object' => $item instanceof SelfReference ? $this : $item, - ); - } elseif (is_array($item) || is_object($item)) { - $this->mapPointers($item); - $property->setValue($data, $item); - } - } - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Internal method used to map closures by reference - * - * @internal - * @param mixed &$data - */ - protected function mapByReference(&$data) - { - if ($data instanceof Closure) { - if($data === $this->closure){ - $data = new SelfReference($this->reference); - return; - } - - if (isset($this->scope[$data])) { - $data = $this->scope[$data]; - return; - } - - $instance = new static($data); - - if (static::$context !== null) { - static::$context->scope->toserialize--; - } else { - $instance->scope = $this->scope; - } - - $data = $this->scope[$data] = $instance; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - $this->mapByReference($value); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - $instance = $data; - $this->scope[$instance] = $data = clone($data); - - foreach ($data as &$value){ - $this->mapByReference($value); - } - unset($value); - } elseif (is_object($data) && !$data instanceof SerializableClosure){ - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - - $instance = $data; - $reflection = new ReflectionObject($data); - if(!$reflection->isUserDefined()){ - $this->scope[$instance] = $data; - return; - } - $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - $this->mapByReference($value); - } - $property->setValue($data, $value); - } - } while($reflection = $reflection->getParentClass()); - } - } - -}