Projet

Général

Profil

Révision fbb66ca6

Ajouté par Assos Assos il y a presque 5 ans

Udpate to 7.67

Voir les différences:

drupal7/CHANGELOG.txt
1 1
Drupal 7.xx, xxxx-xx-xx (development version)
2 2
-----------------------
3 3

  
4
Drupal 7.67, 2019-05-08
5
-----------------------
6
- Fixed security issues:
7
   - SA-CORE-2019-007
8

  
4 9
Drupal 7.66, 2019-04-17
5 10
-----------------------
6 11
- Fixed security issues:
drupal7/includes/bootstrap.inc
8 8
/**
9 9
 * The current system version.
10 10
 */
11
define('VERSION', '7.66');
11
define('VERSION', '7.67');
12 12

  
13 13
/**
14 14
 * Core API compatibility.
drupal7/includes/file.phar.inc
18 18
  include_once $directory . '/Helper.php';
19 19
  include_once $directory . '/Manager.php';
20 20
  include_once $directory . '/PharStreamWrapper.php';
21
  include_once $directory . '/Collectable.php';
22
  include_once $directory . '/Interceptor/ConjunctionInterceptor.php';
23
  include_once $directory . '/Interceptor/PharMetaDataInterceptor.php';
24
  include_once $directory . '/Phar/Container.php';
25
  include_once $directory . '/Phar/DeserializationException.php';
26
  include_once $directory . '/Phar/Manifest.php';
27
  include_once $directory . '/Phar/Reader.php';
28
  include_once $directory . '/Phar/ReaderException.php';
29
  include_once $directory . '/Phar/Stub.php';
30
  include_once $directory . '/Resolvable.php';
31
  include_once $directory . '/Resolver/PharInvocation.php';
32
  include_once $directory . '/Resolver/PharInvocationCollection.php';
33
  include_once $directory . '/Resolver/PharInvocationResolver.php';
21 34
  include_once DRUPAL_ROOT . '/misc/typo3/drupal-security/PharExtensionInterceptor.php';
35
  include_once DRUPAL_ROOT . '/misc/brumann/polyfill-unserialize/src/Unserialize.php';
22 36

  
23 37
  // Set up a stream wrapper to handle insecurities due to PHP's built-in
24 38
  // phar stream wrapper.
drupal7/misc/brumann/polyfill-unserialize/LICENSE
1
MIT License
2

  
3
Copyright (c) 2016 Denis Brumann
4

  
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
of this software and associated documentation files (the "Software"), to deal
7
in the Software without restriction, including without limitation the rights
8
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
copies of the Software, and to permit persons to whom the Software is
10
furnished to do so, subject to the following conditions:
11

  
12
The above copyright notice and this permission notice shall be included in all
13
copies or substantial portions of the Software.
14

  
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
SOFTWARE.
drupal7/misc/brumann/polyfill-unserialize/README.md
1
Polyfill unserialize [![Build Status](https://travis-ci.org/dbrumann/polyfill-unserialize.svg?branch=master)](https://travis-ci.org/dbrumann/polyfill-unserialize)
2
===
3

  
4
Backports unserialize options introduced in PHP 7.0 to older PHP versions.
5
This was originally designed as a Proof of Concept for Symfony Issue [#21090](https://github.com/symfony/symfony/pull/21090).
6

  
7
You can use this package in projects that rely on PHP versions older than PHP 7.0.
8
In case you are using PHP 7.0+ the original `unserialize()` will be used instead.
9

  
10
From the [documentation](https://secure.php.net/manual/en/function.unserialize.php):
11

  
12
> Warning: Do not pass untrusted user input to unserialize(). Unserialization can
13
> result in code being loaded and executed due to object instantiation
14
> and autoloading, and a malicious user may be able to exploit this.
15

  
16
This warning holds true even when `allowed_classes` is used.
17

  
18
Requirements
19
------------
20

  
21
 - PHP 5.3+
22

  
23
Installation
24
------------
25

  
26
You can install this package via composer:
27

  
28
```
29
composer require brumann/polyfill-unserialize "^1.0"
30
```
31

  
32
Known Issues
33
------------
34

  
35
There is a mismatch in behavior when `allowed_classes` in `$options` is not
36
of the correct type (array or boolean). PHP 7.1 will issue a warning, whereas
37
PHP 7.0 will not. I opted to copy the behavior of the former.
38

  
39
Tests
40
-----
41

  
42
You can run the test suite using PHPUnit. It is intentionally not bundled as
43
dev dependency to make sure this package has the lowest restrictions on the
44
implementing system as possible.
45

  
46
Please read the [PHPUnit Manual](https://phpunit.de/manual/current/en/installation.html)
47
for information how to install it on your system.
48

  
49
You can run the test suite as follows:
50

  
51
```
52
phpunit -c phpunit.xml.dist tests/
53
```
54

  
55
Contributing
56
------------
57

  
58
This package is considered feature complete. As such I will likely not update it
59
unless there are security issues.
60

  
61
Should you find any bugs or have questions, feel free to submit an Issue or a Pull Request.
drupal7/misc/brumann/polyfill-unserialize/composer.json
1
{
2
    "name": "brumann/polyfill-unserialize",
3
    "description": "Backports unserialize options introduced in PHP 7.0 to older PHP versions.",
4
    "type": "library",
5
    "license": "MIT",
6
    "authors": [
7
        {
8
            "name": "Denis Brumann",
9
            "email": "denis.brumann@sensiolabs.de"
10
        }
11
    ],
12
    "autoload": {
13
        "psr-4": {
14
            "Brumann\\Polyfill\\": "src/"
15
        }
16
    },
17
    "autoload-dev": {
18
        "psr-4": {
19
            "Tests\\Brumann\\Polyfill\\": "tests/"
20
        }
21
    },
22
    "minimum-stability": "stable",
23
    "require": {
24
        "php": "^5.3|^7.0"
25
    }
26
}
drupal7/misc/brumann/polyfill-unserialize/phpunit.xml.dist
1
<?xml version="1.0" encoding="UTF-8"?>
2

  
3
<phpunit
4
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
    xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
6
    backupGlobals="false"
7
    colors="true"
8
    bootstrap="vendor/autoload.php"
9
>
10
    <php>
11
        <ini name="error_reporting" value="-1" />
12
    </php>
13

  
14
    <testsuites>
15
        <testsuite name="Brumann\Polyfill Test Suite">
16
            <directory>./tests/</directory>
17
        </testsuite>
18
    </testsuites>
19

  
20
    <filter>
21
        <whitelist>
22
            <directory>./src/</directory>
23
        </whitelist>
24
    </filter>
25
</phpunit>
drupal7/misc/brumann/polyfill-unserialize/src/Unserialize.php
1
<?php
2

  
3
namespace Brumann\Polyfill;
4

  
5
final class Unserialize
6
{
7
    /**
8
     * @see https://secure.php.net/manual/en/function.unserialize.php
9
     *
10
     * @param string $serialized Serialized data
11
     * @param array $options Associative array containing options
12
     *
13
     * @return mixed
14
     */
15
    public static function unserialize($serialized, array $options = array())
16
    {
17
        if (PHP_VERSION_ID >= 70000) {
18
            return \unserialize($serialized, $options);
19
        }
20
        if (!array_key_exists('allowed_classes', $options)) {
21
            $options['allowed_classes'] = true;
22
        }
23
        $allowedClasses = $options['allowed_classes'];
24
        if (true === $allowedClasses) {
25
            return \unserialize($serialized);
26
        }
27
        if (false === $allowedClasses) {
28
            $allowedClasses = array();
29
        }
30
        if (!is_array($allowedClasses)) {
31
            trigger_error(
32
                'unserialize(): allowed_classes option should be array or boolean',
33
                E_USER_WARNING
34
            );
35
            $allowedClasses = array();
36
        }
37

  
38
        $sanitizedSerialized = preg_replace_callback(
39
            '/(^|;)O:\d+:"([^"]*)":(\d+):{/',
40
            function ($match) use ($allowedClasses) {
41
                list($completeMatch, $leftBorder, $className, $objectSize) = $match;
42
                if (in_array($className, $allowedClasses)) {
43
                    return $completeMatch;
44
                } else {
45
                    return sprintf(
46
                        '%sO:22:"__PHP_Incomplete_Class":%d:{s:27:"__PHP_Incomplete_Class_Name";%s',
47
                        $leftBorder,
48
                        $objectSize + 1, // size of object + 1 for added string
49
                        \serialize($className)
50
                    );
51
                }
52
            },
53
            $serialized
54
        );
55

  
56
        return \unserialize($sanitizedSerialized);
57
    }
58
}
drupal7/misc/typo3/phar-stream-wrapper/README.md
63 63

  
64 64
```
65 65
$behavior = new \TYPO3\PharStreamWrapper\Behavior();
66
Manager::initialize(
66
\TYPO3\PharStreamWrapper\Manager::initialize(
67 67
    $behavior->withAssertion(new PharExtensionInterceptor())
68 68
);
69 69

  
......
90 90
  + `COMMAND_UNLINK`
91 91
  + `COMMAND_URL_STAT`
92 92

  
93
## Interceptor
93
## Interceptors
94 94

  
95 95
The following interceptor is shipped with the package and ready to use in order
96 96
to block any Phar invocation of files not having a `.phar` suffix. Besides that
......
137 137
}
138 138
```
139 139

  
140
### ConjunctionInterceptor
141

  
142
This interceptor combines multiple interceptors implementing `Assertable`.
143
It succeeds when all nested interceptors succeed as well (logical `AND`).
144

  
145
```
146
$behavior = new \TYPO3\PharStreamWrapper\Behavior();
147
\TYPO3\PharStreamWrapper\Manager::initialize(
148
    $behavior->withAssertion(new ConjunctionInterceptor(array(
149
        new PharExtensionInterceptor(),
150
        new PharMetaDataInterceptor()
151
    )))
152
);
153
```
154

  
155
### PharExtensionInterceptor
156

  
157
This (basic) interceptor just checks whether the invoked Phar archive has
158
an according `.phar` file extension. Resolving symbolic links as well as
159
Phar internal alias resolving are considered as well.
160

  
161
```
162
$behavior = new \TYPO3\PharStreamWrapper\Behavior();
163
\TYPO3\PharStreamWrapper\Manager::initialize(
164
    $behavior->withAssertion(new PharExtensionInterceptor())
165
);
166
```
167

  
168
### PharMetaDataInterceptor
169

  
170
This interceptor is actually checking serialized Phar meta-data against
171
PHP objects and would consider a Phar archive malicious in case not only
172
scalar values are found. A custom low-level `Phar\Reader` is used in order to
173
avoid using PHP's `Phar` object which would trigger the initial vulnerability.
174

  
175
```
176
$behavior = new \TYPO3\PharStreamWrapper\Behavior();
177
\TYPO3\PharStreamWrapper\Manager::initialize(
178
    $behavior->withAssertion(new PharMetaDataInterceptor())
179
);
180
```
181

  
182
## Reader
183

  
184
* `Phar\Reader::__construct(string $fileName)`: Creates low-level reader for Phar archive
185
* `Phar\Reader::resolveContainer(): Phar\Container`: Resolves model representing Phar archive
186
* `Phar\Container::getStub(): Phar\Stub`: Resolves (plain PHP) stub section of Phar archive
187
* `Phar\Container::getManifest(): Phar\Manifest`: Resolves parsed Phar archive manifest as
188
  documented at http://php.net/manual/en/phar.fileformat.manifestfile.php
189
* `Phar\Stub::getMappedAlias(): string`: Resolves internal Phar archive alias defined in stub
190
  using `Phar::mapPhar('alias.phar')` - actually the plain PHP source is analyzed here
191
* `Phar\Manifest::getAlias(): string` - Resolves internal Phar archive alias defined in manifest
192
  using `Phar::setAlias('alias.phar')`
193
* `Phar\Manifest::getMetaData(): string`: Resolves serialized Phar archive meta-data
194
* `Phar\Manifest::deserializeMetaData(): mixed`: Resolves deserialized Phar archive meta-data
195
  containing only scalar values - in case an object is determined, an according
196
  `Phar\DeserializationException` will be thrown
197

  
198
```
199
$reader = new Phar\Reader('example.phar');
200
var_dump($reader->resolveContainer()->getManifest()->deserializeMetaData());
201
```
202

  
140 203
## Helper
141 204

  
142
* `Helper::determineBaseFile(string $path)`: Determines base file that can be
205
* `Helper::determineBaseFile(string $path): string`: Determines base file that can be
143 206
  accessed using the regular file system. For instance the following path
144 207
  `phar:///home/user/bundle.phar/content.txt` would be resolved to
145 208
  `/home/user/bundle.phar`.
drupal7/misc/typo3/phar-stream-wrapper/composer.json
6 6
    "homepage": "https://typo3.org/",
7 7
    "keywords": ["php", "phar", "stream-wrapper", "security"],
8 8
    "require": {
9
        "php": "^5.3.3|^7.0"
9
        "php": "^5.3.3|^7.0",
10
        "ext-fileinfo": "*",
11
        "ext-json": "*",
12
        "brumann/polyfill-unserialize": "^1.0"
10 13
    },
11 14
    "require-dev": {
15
        "ext-xdebug": "*",
12 16
        "phpunit/phpunit": "^4.8.36"
13 17
    },
14 18
    "autoload": {
drupal7/misc/typo3/phar-stream-wrapper/src/Collectable.php
1
<?php
2
namespace TYPO3\PharStreamWrapper;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Resolver\PharInvocation;
15

  
16
interface Collectable
17
{
18
    /**
19
     * @param PharInvocation $invocation
20
     * @return bool
21
     */
22
    public function has(PharInvocation $invocation);
23

  
24
    /**
25
     * @param PharInvocation $invocation
26
     * @param null $flags
27
     * @return bool
28
     */
29
    public function collect(PharInvocation $invocation, $flags = null);
30

  
31
    /**
32
     * @param callable $callback
33
     * @param bool $reverse
34
     * @return null|PharInvocation
35
     */
36
    public function findByCallback($callback, $reverse = false);
37
}
drupal7/misc/typo3/phar-stream-wrapper/src/Helper.php
11 11
 * The TYPO3 project - inspiring people to share!
12 12
 */
13 13

  
14
/**
15
 * Helper provides low-level tools on file name resolving. However it does not
16
 * (and should not) maintain any runtime state information. In order to resolve
17
 * Phar archive paths according resolvers have to be used.
18
 *
19
 * @see \TYPO3\PharStreamWrapper\Resolvable::resolve()
20
 */
14 21
class Helper
15 22
{
16 23
    /*
......
54 61
        return null;
55 62
    }
56 63

  
64
    /**
65
     * @param string $path
66
     * @return bool
67
     */
68
    public static function hasPharPrefix($path)
69
    {
70
        return stripos($path, 'phar://') === 0;
71
    }
72

  
57 73
    /**
58 74
     * @param string $path
59 75
     * @return string
......
61 77
    public static function removePharPrefix($path)
62 78
    {
63 79
        $path = trim($path);
64
        if (stripos($path, 'phar://') !== 0) {
80
        if (!static::hasPharPrefix($path)) {
65 81
            return $path;
66 82
        }
67 83
        return substr($path, 7);
......
77 93
    public static function normalizePath($path)
78 94
    {
79 95
        return rtrim(
80
            static::getCanonicalPath(
96
            static::normalizeWindowsPath(
81 97
                static::removePharPrefix($path)
82 98
            ),
83 99
            '/'
drupal7/misc/typo3/phar-stream-wrapper/src/Interceptor/ConjunctionInterceptor.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Interceptor;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Assertable;
15
use TYPO3\PharStreamWrapper\Exception;
16

  
17
class ConjunctionInterceptor implements Assertable
18
{
19
    /**
20
     * @var Assertable[]
21
     */
22
    private $assertions;
23

  
24
    public function __construct(array $assertions)
25
    {
26
        $this->assertAssertions($assertions);
27
        $this->assertions = $assertions;
28
    }
29

  
30
    /**
31
     * Executes assertions based on all contained assertions.
32
     *
33
     * @param string $path
34
     * @param string $command
35
     * @return bool
36
     * @throws Exception
37
     */
38
    public function assert($path, $command)
39
    {
40
        if ($this->invokeAssertions($path, $command)) {
41
            return true;
42
        }
43
        throw new Exception(
44
            sprintf(
45
                'Assertion failed in "%s"',
46
                $path
47
            ),
48
            1539625084
49
        );
50
    }
51

  
52
    /**
53
     * @param Assertable[] $assertions
54
     */
55
    private function assertAssertions(array $assertions)
56
    {
57
        foreach ($assertions as $assertion) {
58
            if (!$assertion instanceof Assertable) {
59
                throw new \InvalidArgumentException(
60
                    sprintf(
61
                        'Instance %s must implement Assertable',
62
                        get_class($assertion)
63
                    ),
64
                    1539624719
65
                );
66
            }
67
        }
68
    }
69

  
70
    /**
71
     * @param string $path
72
     * @param string $command
73
     * @return bool
74
     */
75
    private function invokeAssertions($path, $command)
76
    {
77
        try {
78
            foreach ($this->assertions as $assertion) {
79
                if (!$assertion->assert($path, $command)) {
80
                    return false;
81
                }
82
            }
83
        } catch (Exception $exception) {
84
            return false;
85
        }
86
        return true;
87
    }
88
}
drupal7/misc/typo3/phar-stream-wrapper/src/Interceptor/PharExtensionInterceptor.php
12 12
 */
13 13

  
14 14
use TYPO3\PharStreamWrapper\Assertable;
15
use TYPO3\PharStreamWrapper\Helper;
16 15
use TYPO3\PharStreamWrapper\Exception;
16
use TYPO3\PharStreamWrapper\Manager;
17 17

  
18 18
class PharExtensionInterceptor implements Assertable
19 19
{
......
45 45
     */
46 46
    private function baseFileContainsPharExtension($path)
47 47
    {
48
        $baseFile = Helper::determineBaseFile($path);
49
        if ($baseFile === null) {
48
        $invocation = Manager::instance()->resolve($path);
49
        if ($invocation === null) {
50 50
            return false;
51 51
        }
52
        $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION);
52
        $fileExtension = pathinfo($invocation->getBaseName(), PATHINFO_EXTENSION);
53 53
        return strtolower($fileExtension) === 'phar';
54 54
    }
55 55
}
drupal7/misc/typo3/phar-stream-wrapper/src/Interceptor/PharMetaDataInterceptor.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Interceptor;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Assertable;
15
use TYPO3\PharStreamWrapper\Exception;
16
use TYPO3\PharStreamWrapper\Manager;
17
use TYPO3\PharStreamWrapper\Phar\DeserializationException;
18
use TYPO3\PharStreamWrapper\Phar\Reader;
19

  
20
/**
21
 * @internal Experimental implementation of checking against serialized objects in Phar meta-data
22
 * @internal This functionality has not been 100% pentested...
23
 */
24
class PharMetaDataInterceptor implements Assertable
25
{
26
    /**
27
     * Determines whether the according Phar archive contains
28
     * (potential insecure) serialized objects.
29
     *
30
     * @param string $path
31
     * @param string $command
32
     * @return bool
33
     * @throws Exception
34
     */
35
    public function assert($path, $command)
36
    {
37
        if ($this->baseFileDoesNotHaveMetaDataIssues($path)) {
38
            return true;
39
        }
40
        throw new Exception(
41
            sprintf(
42
                'Problematic meta-data in "%s"',
43
                $path
44
            ),
45
            1539632368
46
        );
47
    }
48

  
49
    /**
50
     * @param string $path
51
     * @return bool
52
     */
53
    private function baseFileDoesNotHaveMetaDataIssues($path)
54
    {
55
        $invocation = Manager::instance()->resolve($path);
56
        if ($invocation === null) {
57
            return false;
58
        }
59
        // directly return in case invocation was checked before
60
        if ($invocation->getVariable(__CLASS__) === true) {
61
            return true;
62
        }
63
        // otherwise analyze meta-data
64
        try {
65
            $reader = new Reader($invocation->getBaseName());
66
            $reader->resolveContainer()->getManifest()->deserializeMetaData();
67
            $invocation->setVariable(__CLASS__, true);
68
        } catch (DeserializationException $exception) {
69
            return false;
70
        }
71
        return true;
72
    }
73
}
drupal7/misc/typo3/phar-stream-wrapper/src/Manager.php
11 11
 * The TYPO3 project - inspiring people to share!
12 12
 */
13 13

  
14
class Manager implements Assertable
14
use TYPO3\PharStreamWrapper\Resolver\PharInvocation;
15
use TYPO3\PharStreamWrapper\Resolver\PharInvocationCollection;
16
use TYPO3\PharStreamWrapper\Resolver\PharInvocationResolver;
17

  
18
class Manager
15 19
{
16 20
    /**
17 21
     * @var self
......
23 27
     */
24 28
    private $behavior;
25 29

  
30
    /**
31
     * @var Resolvable
32
     */
33
    private $resolver;
34

  
35
    /**
36
     * @var Collectable
37
     */
38
    private $collection;
39

  
26 40
    /**
27 41
     * @param Behavior $behaviour
42
     * @param Resolvable $resolver
43
     * @param Collectable $collection
28 44
     * @return self
29 45
     */
30
    public static function initialize(Behavior $behaviour)
31
    {
46
    public static function initialize(
47
        Behavior $behaviour,
48
        Resolvable $resolver = null,
49
        Collectable $collection = null
50
    ) {
32 51
        if (self::$instance === null) {
33
            self::$instance = new self($behaviour);
52
            self::$instance = new self($behaviour, $resolver, $collection);
34 53
            return self::$instance;
35 54
        }
36 55
        throw new \LogicException(
......
67 86

  
68 87
    /**
69 88
     * @param Behavior $behaviour
89
     * @param Resolvable $resolver
90
     * @param Collectable $collection
70 91
     */
71
    private function __construct(Behavior $behaviour)
72
    {
92
    private function __construct(
93
        Behavior $behaviour,
94
        Resolvable $resolver = null,
95
        Collectable $collection = null
96
    ) {
97
        if ($collection === null) {
98
            $collection = new PharInvocationCollection();
99
        }
100
        if ($resolver === null) {
101
            $resolver = new PharInvocationResolver();
102
        }
103
        $this->collection = $collection;
104
        $this->resolver = $resolver;
73 105
        $this->behavior = $behaviour;
74 106
    }
75 107

  
......
82 114
    {
83 115
        return $this->behavior->assert($path, $command);
84 116
    }
117

  
118
    /**
119
     * @param string $path
120
     * @param null|int $flags
121
     * @return null|PharInvocation
122
     */
123
    public function resolve($path, $flags = null)
124
    {
125
        return $this->resolver->resolve($path, $flags);
126
    }
127

  
128
    /**
129
     * @return Collectable
130
     */
131
    public function getCollection()
132
    {
133
        return $this->collection;
134
    }
85 135
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/Container.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
class Container
15
{
16
    /**
17
     * @var Stub
18
     */
19
    private $stub;
20

  
21
    /**
22
     * @var Manifest
23
     */
24
    private $manifest;
25

  
26
    /**
27
     * @param Stub $stub
28
     * @param Manifest $manifest
29
     */
30
    public function __construct(Stub $stub, Manifest $manifest)
31
    {
32
        $this->stub = $stub;
33
        $this->manifest = $manifest;
34
    }
35

  
36
    /**
37
     * @return Stub
38
     */
39
    public function getStub()
40
    {
41
        return $this->stub;
42
    }
43

  
44
    /**
45
     * @return Manifest
46
     */
47
    public function getManifest()
48
    {
49
        return $this->manifest;
50
    }
51

  
52
    /**
53
     * @return string
54
     */
55
    public function getAlias()
56
    {
57
        return $this->manifest->getAlias() ?: $this->stub->getMappedAlias();
58
    }
59
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/DeserializationException.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Exception;
15

  
16
class DeserializationException extends Exception
17
{
18
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/Manifest.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use Brumann\Polyfill\Unserialize;
15

  
16
class Manifest
17
{
18
    /**
19
     * @param string $content
20
     * @return self
21
     * @see http://php.net/manual/en/phar.fileformat.phar.php
22
     */
23
    public static function fromContent($content)
24
    {
25
        $target = new static();
26
        $target->manifestLength = Reader::resolveFourByteLittleEndian($content, 0);
27
        $target->amountOfFiles = Reader::resolveFourByteLittleEndian($content, 4);
28
        $target->flags = Reader::resolveFourByteLittleEndian($content, 10);
29
        $target->aliasLength = Reader::resolveFourByteLittleEndian($content, 14);
30
        $target->alias = substr($content, 18, $target->aliasLength);
31
        $target->metaDataLength = Reader::resolveFourByteLittleEndian($content, 18 + $target->aliasLength);
32
        $target->metaData = substr($content, 22 + $target->aliasLength, $target->metaDataLength);
33

  
34
        $apiVersionNibbles = Reader::resolveTwoByteBigEndian($content, 8);
35
        $target->apiVersion = implode('.', array(
36
            ($apiVersionNibbles & 0xf000) >> 12,
37
            ($apiVersionNibbles & 0x0f00) >> 8,
38
            ($apiVersionNibbles & 0x00f0) >> 4,
39
        ));
40

  
41
        return $target;
42
    }
43

  
44
    /**
45
     * @var int
46
     */
47
    private $manifestLength;
48

  
49
    /**
50
     * @var int
51
     */
52
    private $amountOfFiles;
53

  
54
    /**
55
     * @var string
56
     */
57
    private $apiVersion;
58

  
59
    /**
60
     * @var int
61
     */
62
    private $flags;
63

  
64
    /**
65
     * @var int
66
     */
67
    private $aliasLength;
68

  
69
    /**
70
     * @var string
71
     */
72
    private $alias;
73

  
74
    /**
75
     * @var int
76
     */
77
    private $metaDataLength;
78

  
79
    /**
80
     * @var string
81
     */
82
    private $metaData;
83

  
84
    /**
85
     * Avoid direct instantiation.
86
     */
87
    private function __construct()
88
    {
89
    }
90

  
91
    /**
92
     * @return int
93
     */
94
    public function getManifestLength()
95
    {
96
        return $this->manifestLength;
97
    }
98

  
99
    /**
100
     * @return int
101
     */
102
    public function getAmountOfFiles()
103
    {
104
        return $this->amountOfFiles;
105
    }
106

  
107
    /**
108
     * @return string
109
     */
110
    public function getApiVersion()
111
    {
112
        return $this->apiVersion;
113
    }
114

  
115
    /**
116
     * @return int
117
     */
118
    public function getFlags()
119
    {
120
        return $this->flags;
121
    }
122

  
123
    /**
124
     * @return int
125
     */
126
    public function getAliasLength()
127
    {
128
        return $this->aliasLength;
129
    }
130

  
131
    /**
132
     * @return string
133
     */
134
    public function getAlias()
135
    {
136
        return $this->alias;
137
    }
138

  
139
    /**
140
     * @return int
141
     */
142
    public function getMetaDataLength()
143
    {
144
        return $this->metaDataLength;
145
    }
146

  
147
    /**
148
     * @return string
149
     */
150
    public function getMetaData()
151
    {
152
        return $this->metaData;
153
    }
154

  
155
    /**
156
     * @return mixed|null
157
     */
158
    public function deserializeMetaData()
159
    {
160
        if (empty($this->metaData)) {
161
            return null;
162
        }
163

  
164
        $result = Unserialize::unserialize($this->metaData, array('allowed_classes' => false));
165

  
166
        $serialized = json_encode($result);
167
        if (strpos($serialized, '__PHP_Incomplete_Class_Name') !== false) {
168
            throw new DeserializationException(
169
                'Meta-data contains serialized object',
170
                1539623382
171
            );
172
        }
173

  
174
        return $result;
175
    }
176
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/Reader.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
class Reader
15
{
16
    /**
17
     * @var string
18
     */
19
    private $fileName;
20

  
21
    /**
22
     * @var string
23
     */
24
    private $fileType;
25

  
26
    /**
27
     * @param string $fileName
28
     */
29
    public function __construct($fileName)
30
    {
31
        if (strpos($fileName, '://') !== false) {
32
            throw new ReaderException(
33
                'File name must not contain stream prefix',
34
                1539623708
35
            );
36
        }
37

  
38
        $this->fileName = $fileName;
39
        $this->fileType = $this->determineFileType();
40
    }
41

  
42
    /**
43
     * @return Container
44
     */
45
    public function resolveContainer()
46
    {
47
        $data = $this->extractData($this->resolveStream() . $this->fileName);
48

  
49
        if ($data['stubContent'] === null) {
50
            throw new ReaderException(
51
                'Cannot resolve stub',
52
                1547807881
53
            );
54
        }
55
        if ($data['manifestContent'] === null || $data['manifestLength'] === null) {
56
            throw new ReaderException(
57
                'Cannot resolve manifest',
58
                1547807882
59
            );
60
        }
61
        if (strlen($data['manifestContent']) < $data['manifestLength']) {
62
            throw new ReaderException(
63
                sprintf(
64
                    'Exected manifest length %d, got %d',
65
                    strlen($data['manifestContent']),
66
                    $data['manifestLength']
67
                ),
68
                1547807883
69
            );
70
        }
71

  
72
        return new Container(
73
            Stub::fromContent($data['stubContent']),
74
            Manifest::fromContent($data['manifestContent'])
75
        );
76
    }
77

  
78
    /**
79
     * @param string $fileName e.g. '/path/file.phar' or 'compress.zlib:///path/file.phar'
80
     * @return array
81
     */
82
    private function extractData($fileName)
83
    {
84
        $stubContent = null;
85
        $manifestContent = null;
86
        $manifestLength = null;
87

  
88
        $resource = fopen($fileName, 'r');
89
        if (!is_resource($resource)) {
90
            throw new ReaderException(
91
                sprintf('Resource %s could not be opened', $fileName),
92
                1547902055
93
            );
94
        }
95

  
96
        while (!feof($resource)) {
97
            $line = fgets($resource);
98
            // stop reading file when manifest can be extracted
99
            if ($manifestLength !== null && $manifestContent !== null && strlen($manifestContent) >= $manifestLength) {
100
                break;
101
            }
102

  
103
            $manifestPosition = strpos($line, '__HALT_COMPILER();');
104

  
105
            // first line contains start of manifest
106
            if ($stubContent === null && $manifestContent === null && $manifestPosition !== false) {
107
                $stubContent = substr($line, 0, $manifestPosition - 1);
108
                $manifestContent = preg_replace('#^.*__HALT_COMPILER\(\);(?>[ \n]\?>(?>\r\n|\n)?)?#', '', $line);
109
                $manifestLength = $this->resolveManifestLength($manifestContent);
110
            // line contains start of stub
111
            } elseif ($stubContent === null) {
112
                $stubContent = $line;
113
            // line contains start of manifest
114
            } elseif ($manifestContent === null && $manifestPosition !== false) {
115
                $manifestContent = preg_replace('#^.*__HALT_COMPILER\(\);(?>[ \n]\?>(?>\r\n|\n)?)?#', '', $line);
116
                $manifestLength = $this->resolveManifestLength($manifestContent);
117
            // manifest has been started (thus is cannot be stub anymore), add content
118
            } elseif ($manifestContent !== null) {
119
                $manifestContent .= $line;
120
                $manifestLength = $this->resolveManifestLength($manifestContent);
121
            // stub has been started (thus cannot be manifest here, yet), add content
122
            } elseif ($stubContent !== null) {
123
                $stubContent .= $line;
124
            }
125
        }
126
        fclose($resource);
127

  
128
        return array(
129
            'stubContent' => $stubContent,
130
            'manifestContent' => $manifestContent,
131
            'manifestLength' => $manifestLength,
132
        );
133
    }
134

  
135
    /**
136
     * Resolves stream in order to handle compressed Phar archives.
137
     *
138
     * @return string
139
     */
140
    private function resolveStream()
141
    {
142
        if ($this->fileType === 'application/x-gzip') {
143
            return 'compress.zlib://';
144
        } elseif ($this->fileType === 'application/x-bzip2') {
145
            return 'compress.bzip2://';
146
        }
147
        return '';
148
    }
149

  
150
    /**
151
     * @return string
152
     */
153
    private function determineFileType()
154
    {
155
        $fileInfo = new \finfo();
156
        return $fileInfo->file($this->fileName, FILEINFO_MIME_TYPE);
157
    }
158

  
159
    /**
160
     * @param string $content
161
     * @return int|null
162
     */
163
    private function resolveManifestLength($content)
164
    {
165
        if (strlen($content) < 4) {
166
            return null;
167
        }
168
        return static::resolveFourByteLittleEndian($content, 0);
169
    }
170

  
171
    /**
172
     * @param string $content
173
     * @param int $start
174
     * @return int
175
     */
176
    public static function resolveFourByteLittleEndian($content, $start)
177
    {
178
        $payload = substr($content, $start, 4);
179
        if (!is_string($payload)) {
180
            throw new ReaderException(
181
                sprintf('Cannot resolve value at offset %d', $start),
182
                1539614260
183
            );
184
        }
185

  
186
        $value = unpack('V', $payload);
187
        if (!isset($value[1])) {
188
            throw new ReaderException(
189
                sprintf('Cannot resolve value at offset %d', $start),
190
                1539614261
191
            );
192
        }
193
        return $value[1];
194
    }
195

  
196
    /**
197
     * @param string $content
198
     * @param int $start
199
     * @return int
200
     */
201
    public static function resolveTwoByteBigEndian($content, $start)
202
    {
203
        $payload = substr($content, $start, 2);
204
        if (!is_string($payload)) {
205
            throw new ReaderException(
206
                sprintf('Cannot resolve value at offset %d', $start),
207
                1539614263
208
            );
209
        }
210

  
211
        $value = unpack('n', $payload);
212
        if (!isset($value[1])) {
213
            throw new ReaderException(
214
                sprintf('Cannot resolve value at offset %d', $start),
215
                1539614264
216
            );
217
        }
218
        return $value[1];
219
    }
220
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/ReaderException.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Exception;
15

  
16
class ReaderException extends Exception
17
{
18
}
drupal7/misc/typo3/phar-stream-wrapper/src/Phar/Stub.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Phar;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
/**
15
 * @internal Experimental implementation of Phar archive internals
16
 */
17
class Stub
18
{
19
    /**
20
     * @param string $content
21
     * @return self
22
     */
23
    public static function fromContent($content)
24
    {
25
        $target = new static();
26
        $target->content = $content;
27

  
28
        if (
29
            stripos($content, 'Phar::mapPhar(') !== false
30
            && preg_match('#Phar\:\:mapPhar\(([^)]+)\)#', $content, $matches)
31
        ) {
32
            // remove spaces, single & double quotes
33
            // @todo `'my' . 'alias' . '.phar'` is not evaluated here
34
            $target->mappedAlias = trim($matches[1], ' \'"');
35
        }
36

  
37
        return $target;
38
    }
39

  
40
    /**
41
     * @var string
42
     */
43
    private $content;
44

  
45
    /**
46
     * @var string
47
     */
48
    private $mappedAlias = '';
49

  
50
    /**
51
     * @return string
52
     */
53
    public function getContent()
54
    {
55
        return $this->content;
56
    }
57

  
58
    /**
59
     * @return string
60
     */
61
    public function getMappedAlias()
62
    {
63
        return $this->mappedAlias;
64
    }
65
}
drupal7/misc/typo3/phar-stream-wrapper/src/PharStreamWrapper.php
11 11
 * The TYPO3 project - inspiring people to share!
12 12
 */
13 13

  
14
use TYPO3\PharStreamWrapper\Resolver\PharInvocation;
15

  
14 16
class PharStreamWrapper
15 17
{
16 18
    /**
......
29 31
     */
30 32
    protected $internalResource;
31 33

  
34
    /**
35
     * @var PharInvocation
36
     */
37
    protected $invocation;
38

  
32 39
    /**
33 40
     * @return bool
34 41
     */
......
409 416
     */
410 417
    protected function assert($path, $command)
411 418
    {
412
        if ($this->resolveAssertable()->assert($path, $command) === true) {
419
        if (Manager::instance()->assert($path, $command) === true) {
420
            $this->collectInvocation($path);
413 421
            return;
414 422
        }
415 423

  
......
424 432
    }
425 433

  
426 434
    /**
427
     * @return Assertable
435
     * @param string $path
436
     */
437
    protected function collectInvocation($path)
438
    {
439
        if (isset($this->invocation)) {
440
            return;
441
        }
442

  
443
        $manager = Manager::instance();
444
        $this->invocation = $manager->resolve($path);
445
        if ($this->invocation === null) {
446
            throw new Exception(
447
                'Expected invocation could not be resolved',
448
                1556389591
449
            );
450
        }
451
        // confirm, previous interceptor(s) validated invocation
452
        $this->invocation->confirm();
453
        $collection = $manager->getCollection();
454
        if (!$collection->has($this->invocation)) {
455
            $collection->collect($this->invocation);
456
        }
457
    }
458

  
459
    /**
460
     * @return Manager|Assertable
461
     * @deprecated Use Manager::instance() directly
428 462
     */
429 463
    protected function resolveAssertable()
430 464
    {
drupal7/misc/typo3/phar-stream-wrapper/src/Resolvable.php
1
<?php
2
namespace TYPO3\PharStreamWrapper;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

  
14
use TYPO3\PharStreamWrapper\Resolver\PharInvocation;
15

  
16
interface Resolvable
17
{
18
    /**
19
     * @param string $path
20
     * @param null|int $flags
21
     * @return null|PharInvocation
22
     */
23
    public function resolve($path, $flags = null);
24
}
drupal7/misc/typo3/phar-stream-wrapper/src/Resolver/PharInvocation.php
1
<?php
2
namespace TYPO3\PharStreamWrapper\Resolver;
3

  
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff