GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#10)
by Oliver
01:52
created

Reader::extractData()   C

Complexity

Conditions 15
Paths 2

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 30
nc 2
nop 1
dl 0
loc 45
rs 5.9166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
namespace TYPO3\PharStreamWrapper\Phar;
4
5
/*
6
 * This file is part of the TYPO3 project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under the terms
9
 * of the MIT License (MIT). For the full copyright and license information,
10
 * please read the LICENSE file that was distributed with this source code.
11
 *
12
 * The TYPO3 project - inspiring people to share!
13
 */
14
15
class Reader
16
{
17
    /**
18
     * @var string
19
     */
20
    private $fileName;
21
22
    /**
23
     * @var string
24
     */
25
    private $fileType;
26
27
    /**
28
     * @param string $fileName
29
     */
30
    public function __construct(string $fileName)
31
    {
32
        if (strpos($fileName, '://') !== false) {
33
            throw new \UnexpectedValueException(
34
                'File name must not contain stream prefix',
35
                1539623708
36
            );
37
        }
38
39
        $this->fileName = $fileName;
40
        $this->fileType = $this->determineFileType();
41
    }
42
43
    /**
44
     * @return Container
45
     */
46
    public function resolveContainer(): Container
47
    {
48
        $data = $this->extractData($this->resolveStream() . $this->fileName);
49
50
        if ($data['stubContent'] === null) {
51
            throw new \UnexpectedValueException(
52
                'Cannot resolve stub',
53
                1547807881
54
            );
55
        }
56
        if ($data['manifestContent'] === null || $data['manifestLength'] === null) {
57
            throw new \UnexpectedValueException(
58
                'Cannot resolve manifest',
59
                1547807882
60
            );
61
        }
62
        if (strlen($data['manifestContent']) < $data['manifestLength']) {
63
            throw new \UnexpectedValueException(
64
                sprintf(
65
                    'Exected manifest length %d, got %d',
66
                    strlen($data['manifestContent']),
67
                    $data['manifestLength']
68
                ),
69
                1547807883
70
            );
71
        }
72
73
        return new Container(
74
            Stub::fromContent($data['stubContent']),
75
            Manifest::fromContent($data['manifestContent'])
76
        );
77
    }
78
79
    /**
80
     * @param string $fileName e.g. '/path/file.phar' or 'compress.zlib:///path/file.phar'
81
     * @return array
82
     */
83
    private function extractData(string $fileName): array
84
    {
85
        $stubContent = null;
86
        $manifestContent = null;
87
        $manifestLength = null;
88
89
        $resource = fopen($fileName, 'r');
90
        while (!feof($resource)) {
0 ignored issues
show
Bug introduced by
It seems like $resource can also be of type false; however, parameter $handle of feof() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

90
        while (!feof(/** @scrutinizer ignore-type */ $resource)) {
Loading history...
91
            $line = fgets($resource);
0 ignored issues
show
Bug introduced by
It seems like $resource can also be of type false; however, parameter $handle of fgets() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
            $line = fgets(/** @scrutinizer ignore-type */ $resource);
Loading history...
92
            // stop reading file when manifest can be extracted
93
            if ($manifestLength !== null && $manifestContent !== null && strlen($manifestContent) >= $manifestLength) {
94
                break;
95
            }
96
97
            $stubPosition = strpos($line, '<?php');
98
            $manifestPosition = strpos($line, '__HALT_COMPILER()');
99
100
            // line contains both, start of (empty) stub and start of manifest
101
            if ($stubContent === null && $stubPosition !== false
102
                && $manifestContent === null && $manifestPosition !== false) {
103
                $stubContent = substr($line, $stubPosition, $manifestPosition - $stubPosition - 1);
104
                $manifestContent = preg_replace('#^.*__HALT_COMPILER\(\)[^>]*\?>(\r|\n)*#', '', $line);
105
                $manifestLength = $this->resolveManifestLength($manifestContent);
106
            // line contains start of stub
107
            } elseif ($stubContent === null && $stubPosition !== false) {
108
                $stubContent = substr($line, $stubPosition);
109
            // line contains start of manifest
110
            } elseif ($manifestContent === null && $manifestPosition !== false) {
111
                $manifestContent = preg_replace('#^.*__HALT_COMPILER\(\)[^>]*\?>(\r|\n)*#', '', $line);
112
                $manifestLength = $this->resolveManifestLength($manifestContent);
113
            // manifest has been started (thus is cannot be stub anymore), add content
114
            } elseif ($manifestContent !== null) {
115
                $manifestContent .= $line;
116
                $manifestLength = $this->resolveManifestLength($manifestContent);
117
            // stub has been started (thus cannot be manifest here, yet), add content
118
            } elseif ($stubContent !== null) {
119
                $stubContent .= $line;
120
            }
121
        }
122
        fclose($resource);
0 ignored issues
show
Bug introduced by
It seems like $resource can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
        fclose(/** @scrutinizer ignore-type */ $resource);
Loading history...
123
124
        return [
125
            'stubContent' => $stubContent,
126
            'manifestContent' => $manifestContent,
127
            'manifestLength' => $manifestLength,
128
        ];
129
    }
130
131
    /**
132
     * Resolves stream in order to handle compressed Phar archives.
133
     *
134
     * @return string
135
     */
136
    private function resolveStream(): string
137
    {
138
        if ($this->fileType === 'application/x-gzip') {
139
            return 'compress.zlib://';
140
        } elseif ($this->fileType === 'application/x-bzip2') {
141
            return 'compress.bzip2://';
142
        }
143
        return '';
144
    }
145
146
    /**
147
     * @return string
148
     */
149
    private function determineFileType()
150
    {
151
        $fileInfo = new \finfo();
152
        return $fileInfo->file($this->fileName, FILEINFO_MIME_TYPE);
153
    }
154
155
    /**
156
     * @param string $content
157
     * @return int|null
158
     */
159
    private function resolveManifestLength(string $content)
160
    {
161
        if (strlen($content) < 4) {
162
            return null;
163
        }
164
        return static::resolveFourByteLittleEndian($content, 0);
165
    }
166
167
    /**
168
     * @param string $content
169
     * @param int $start
170
     * @return int
171
     */
172
    public static function resolveFourByteLittleEndian(string $content, int $start): int
173
    {
174
        $payload = substr($content, $start, 4);
175
        if (!is_string($payload)) {
0 ignored issues
show
introduced by
The condition is_string($payload) is always true.
Loading history...
176
            throw new \UnexpectedValueException(
177
                sprintf('Cannot resolve value at offset %d', $start),
178
                1539614260
179
            );
180
        }
181
182
        $value = unpack('V', $payload);
183
        if (!isset($value[1])) {
184
            throw new \UnexpectedValueException(
185
                sprintf('Cannot resolve value at offset %d', $start),
186
                1539614261
187
            );
188
        }
189
        return $value[1];
190
    }
191
192
    /**
193
     * @param string $content
194
     * @param int $start
195
     * @return int
196
     */
197
    public static function resolveTwoByteBigEndian(string $content, int $start): int
198
    {
199
        $payload = substr($content, $start, 2);
200
        if (!is_string($payload)) {
0 ignored issues
show
introduced by
The condition is_string($payload) is always true.
Loading history...
201
            throw new \UnexpectedValueException(
202
                sprintf('Cannot resolve value at offset %d', $start),
203
                1539614263
204
            );
205
        }
206
207
        $value = unpack('n', $payload);
208
        if (!isset($value[1])) {
209
            throw new \UnexpectedValueException(
210
                sprintf('Cannot resolve value at offset %d', $start),
211
                1539614264
212
            );
213
        }
214
        return $value[1];
215
    }
216
}
217