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.
Completed
Pull Request — 3.x (#1899)
by
unknown
02:32
created

UploadedFile::createFromGlobals()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 0
1
<?php
2
/**
3
 * Slim Framework (http://slimframework.com)
4
 *
5
 * @link      https://github.com/slimphp/Slim
6
 * @copyright Copyright (c) 2011-2016 Josh Lockhart
7
 * @license   https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
8
 */
9
namespace Slim\Http;
10
11
use RuntimeException;
12
use InvalidArgumentException;
13
use Psr\Http\Message\StreamInterface;
14
use Psr\Http\Message\UploadedFileInterface;
15
16
/**
17
 * Represents Uploaded Files.
18
 *
19
 * It manages and normalizes uploaded files according to the PSR-7 standard.
20
 *
21
 * @link https://github.com/php-fig/http-message/blob/master/src/UploadedFileInterface.php
22
 * @link https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php
23
 */
24
class UploadedFile implements UploadedFileInterface
25
{
26
    /**
27
     * The client-provided full path to the file
28
     *
29
     * @note this is public to maintain BC with 3.1.0 and earlier.
30
     *
31
     * @var string
32
     */
33
    public $file;
34
    /**
35
     * The client-provided file name.
36
     *
37
     * @var string
38
     */
39
    protected $name;
40
    /**
41
     * The client-provided media type of the file.
42
     *
43
     * @var string
44
     */
45
    protected $type;
46
    /**
47
     * The size of the file in bytes.
48
     *
49
     * @var int
50
     */
51
    protected $size;
52
    /**
53
     * A valid PHP UPLOAD_ERR_xxx code for the file upload.
54
     *
55
     * @var int
56
     */
57
    protected $error = UPLOAD_ERR_OK;
58
    /**
59
     * Indicates if the upload is from a SAPI environment.
60
     *
61
     * @var bool
62
     */
63
    protected $sapi = false;
64
    /**
65
     * An optional StreamInterface wrapping the file resource.
66
     *
67
     * @var StreamInterface
68
     */
69
    protected $stream;
70
    /**
71
     * Indicates if the uploaded file has already been moved.
72
     *
73
     * @var bool
74
     */
75
    protected $moved = false;
76
77
    /**
78
     * Parses the $_FILES global
79
     * @return array A normalized tree of UploadedFile instances or null if none are provided.
80
     */
81
    public static function createFromGlobals()
0 ignored issues
show
Coding Style introduced by
createFromGlobals uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
82
    {
83
        return isset($_FILES) ? static::parseUploadedFiles($_FILES) : [];
0 ignored issues
show
Bug introduced by
Since parseUploadedFiles() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseUploadedFiles() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
84
    }
85
86
    /**
87
     * Parse a non-normalized, i.e. $_FILES superglobal, tree of uploaded file data.
88
     *
89
     * @param array $uploadedFiles The non-normalized tree of uploaded file data.
90
     *
91
     * @return array A normalized tree of UploadedFile instances.
92
     */
93
    private static function parseUploadedFiles(array $uploadedFiles)
94
    {
95
        $parsed = [];
96
        foreach ($uploadedFiles as $field => $uploadedFile) {
97
            if (!isset($uploadedFile['error'])) {
98
                if (is_array($uploadedFile)) {
99
                    $parsed[$field] = static::parseUploadedFiles($uploadedFile);
0 ignored issues
show
Bug introduced by
Since parseUploadedFiles() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseUploadedFiles() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
100
                }
101
                continue;
102
            }
103
104
            $parsed[$field] = [];
105
            if (!is_array($uploadedFile['error'])) {
106
                $parsed[$field] = new static(
107
                    $uploadedFile['tmp_name'],
108
                    isset($uploadedFile['name']) ? $uploadedFile['name'] : null,
109
                    isset($uploadedFile['type']) ? $uploadedFile['type'] : null,
110
                    isset($uploadedFile['size']) ? $uploadedFile['size'] : null,
111
                    $uploadedFile['error'],
112
                    true
113
                );
114
            } else {
115
                $subArray = [];
116
                foreach ($uploadedFile['error'] as $fileIdx => $error) {
117
                    // normalise subarray and re-parse to move the input's keyname up a level
118
                    $subArray[$fileIdx]['name'] = $uploadedFile['name'][$fileIdx];
119
                    $subArray[$fileIdx]['type'] = $uploadedFile['type'][$fileIdx];
120
                    $subArray[$fileIdx]['tmp_name'] = $uploadedFile['tmp_name'][$fileIdx];
121
                    $subArray[$fileIdx]['error'] = $uploadedFile['error'][$fileIdx];
122
                    $subArray[$fileIdx]['size'] = $uploadedFile['size'][$fileIdx];
123
124
                    $parsed[$field] = static::parseUploadedFiles($subArray);
0 ignored issues
show
Bug introduced by
Since parseUploadedFiles() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseUploadedFiles() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
125
                }
126
            }
127
        }
128
129
        return $parsed;
130
    }
131
132
    /**
133
     * Construct a new UploadedFile instance.
134
     *
135
     * @param string      $file The full path to the uploaded file provided by the client.
136
     * @param string|null $name The file name.
137
     * @param string|null $type The file media type.
138
     * @param int|null    $size The file size in bytes.
139
     * @param int         $error The UPLOAD_ERR_XXX code representing the status of the upload.
140
     * @param bool        $sapi Indicates if the upload is in a SAPI environment.
141
     */
142
    public function __construct($file, $name = null, $type = null, $size = null, $error = UPLOAD_ERR_OK, $sapi = false)
143
    {
144
        $this->file = $file;
145
        $this->name = $name;
146
        $this->type = $type;
147
        $this->size = $size;
148
        $this->error = $error;
149
        $this->sapi = $sapi;
150
    }
151
152
    /**
153
     * Retrieve a stream representing the uploaded file.
154
     *
155
     * This method MUST return a StreamInterface instance, representing the
156
     * uploaded file. The purpose of this method is to allow utilizing native PHP
157
     * stream functionality to manipulate the file upload, such as
158
     * stream_copy_to_stream() (though the result will need to be decorated in a
159
     * native PHP stream wrapper to work with such functions).
160
     *
161
     * If the moveTo() method has been called previously, this method MUST raise
162
     * an exception.
163
     *
164
     * @return StreamInterface Stream representation of the uploaded file.
165
     * @throws \RuntimeException in cases when no stream is available or can be
166
     *     created.
167
     */
168
    public function getStream()
169
    {
170
        if ($this->moved) {
171
            throw new \RuntimeException(sprintf('Uploaded file %1s has already been moved', $this->name));
172
        }
173
        if ($this->stream === null) {
174
            $this->stream = new Stream(fopen($this->file, 'r'));
175
        }
176
177
        return $this->stream;
178
    }
179
180
    /**
181
     * Move the uploaded file to a new location.
182
     *
183
     * Use this method as an alternative to move_uploaded_file(). This method is
184
     * guaranteed to work in both SAPI and non-SAPI environments.
185
     * Implementations must determine which environment they are in, and use the
186
     * appropriate method (move_uploaded_file(), rename(), or a stream
187
     * operation) to perform the operation.
188
     *
189
     * $targetPath may be an absolute path, or a relative path. If it is a
190
     * relative path, resolution should be the same as used by PHP's rename()
191
     * function.
192
     *
193
     * The original file or stream MUST be removed on completion.
194
     *
195
     * If this method is called more than once, any subsequent calls MUST raise
196
     * an exception.
197
     *
198
     * When used in an SAPI environment where $_FILES is populated, when writing
199
     * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
200
     * used to ensure permissions and upload status are verified correctly.
201
     *
202
     * If you wish to move to a stream, use getStream(), as SAPI operations
203
     * cannot guarantee writing to stream destinations.
204
     *
205
     * @see http://php.net/is_uploaded_file
206
     * @see http://php.net/move_uploaded_file
207
     *
208
     * @param string $targetPath Path to which to move the uploaded file.
209
     *
210
     * @throws InvalidArgumentException if the $path specified is invalid.
211
     * @throws RuntimeException on any error during the move operation, or on
212
     *     the second or subsequent call to the method.
213
     */
214
    public function moveTo($targetPath)
215
    {
216
        if ($this->moved) {
217
            throw new RuntimeException('Uploaded file already moved');
218
        }
219
220
        if (!is_writable(dirname($targetPath))) {
221
            throw new InvalidArgumentException('Upload target path is not writable');
222
        }
223
224
        $targetIsStream = strpos($targetPath, '://') > 0;
225
        if ($targetIsStream) {
226
            if (!copy($this->file, $targetPath)) {
227
                throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath));
228
            }
229
            if (!unlink($this->file)) {
230
                throw new RuntimeException(sprintf('Error removing uploaded file %1s', $this->name));
231
            }
232
        } elseif ($this->sapi) {
233
            if (!is_uploaded_file($this->file)) {
234
                throw new RuntimeException(sprintf('%1s is not a valid uploaded file', $this->file));
235
            }
236
237
            if (!move_uploaded_file($this->file, $targetPath)) {
238
                throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath));
239
            }
240
        } else {
241
            if (!rename($this->file, $targetPath)) {
242
                throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath));
243
            }
244
        }
245
246
        $this->moved = true;
247
    }
248
249
    /**
250
     * Retrieve the error associated with the uploaded file.
251
     *
252
     * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
253
     *
254
     * If the file was uploaded successfully, this method MUST return
255
     * UPLOAD_ERR_OK.
256
     *
257
     * Implementations SHOULD return the value stored in the "error" key of
258
     * the file in the $_FILES array.
259
     *
260
     * @see http://php.net/manual/en/features.file-upload.errors.php
261
     *
262
     * @return int One of PHP's UPLOAD_ERR_XXX constants.
263
     */
264
    public function getError()
265
    {
266
        return $this->error;
267
    }
268
269
    /**
270
     * Retrieve the filename sent by the client.
271
     *
272
     * Do not trust the value returned by this method. A client could send
273
     * a malicious filename with the intention to corrupt or hack your
274
     * application.
275
     *
276
     * Implementations SHOULD return the value stored in the "name" key of
277
     * the file in the $_FILES array.
278
     *
279
     * @return string|null The filename sent by the client or null if none
280
     *     was provided.
281
     */
282
    public function getClientFilename()
283
    {
284
        return $this->name;
285
    }
286
287
    /**
288
     * Retrieve the media type sent by the client.
289
     *
290
     * Do not trust the value returned by this method. A client could send
291
     * a malicious media type with the intention to corrupt or hack your
292
     * application.
293
     *
294
     * Implementations SHOULD return the value stored in the "type" key of
295
     * the file in the $_FILES array.
296
     *
297
     * @return string|null The media type sent by the client or null if none
298
     *     was provided.
299
     */
300
    public function getClientMediaType()
301
    {
302
        return $this->type;
303
    }
304
305
    /**
306
     * Retrieve the file size.
307
     *
308
     * Implementations SHOULD return the value stored in the "size" key of
309
     * the file in the $_FILES array if available, as PHP calculates this based
310
     * on the actual size transmitted.
311
     *
312
     * @return int|null The file size in bytes or null if unknown.
313
     */
314
    public function getSize()
315
    {
316
        return $this->size;
317
    }
318
}
319