Issues (1)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Storage/AbstractCache.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace League\Flysystem\Cached\Storage;
4
5
use League\Flysystem\Cached\CacheInterface;
6
use League\Flysystem\Util;
7
8
abstract class AbstractCache implements CacheInterface
9
{
10
    /**
11
     * @var bool
12
     */
13
    protected $autosave = true;
14
15
    /**
16
     * @var array
17
     */
18
    protected $cache = [];
19
20
    /**
21
     * @var array
22
     */
23
    protected $complete = [];
24
25
    /**
26
     * Destructor.
27
     */
28 147
    public function __destruct()
29
    {
30 147
        if (! $this->autosave) {
31 6
            $this->save();
32 6
        }
33 147
    }
34
35
    /**
36
     * Get the autosave setting.
37
     *
38
     * @return bool autosave
39
     */
40 3
    public function getAutosave()
41
    {
42 3
        return $this->autosave;
43
    }
44
45
    /**
46
     * Get the autosave setting.
47
     *
48
     * @param bool $autosave
49
     */
50 3
    public function setAutosave($autosave)
51
    {
52 3
        $this->autosave = $autosave;
53 3
    }
54
55
    /**
56
     * Store the contents listing.
57
     *
58
     * @param string $directory
59
     * @param array  $contents
60
     * @param bool   $recursive
61
     *
62
     * @return array contents listing
63
     */
64 15
    public function storeContents($directory, array $contents, $recursive = false)
65
    {
66 15
        $directories = [$directory];
67
68 15
        foreach ($contents as $object) {
69 15
            $this->updateObject($object['path'], $object);
70 15
            $object = $this->cache[$object['path']];
71
72 15
            if ($recursive && $this->pathIsInDirectory($directory, $object['path'])) {
73 9
                $directories[] = $object['dirname'];
74 9
            }
75 15
        }
76
77 15
        foreach (array_unique($directories) as $directory) {
78 15
            $this->setComplete($directory, $recursive);
79 15
        }
80
81 15
        $this->autosave();
82 15
    }
83
84
    /**
85
     * Update the metadata for an object.
86
     *
87
     * @param string $path     object path
88
     * @param array  $object   object metadata
89
     * @param bool   $autosave whether to trigger the autosave routine
90
     */
91 48
    public function updateObject($path, array $object, $autosave = false)
92
    {
93 48
        if (! $this->has($path)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->has($path) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
94 48
            $this->cache[$path] = Util::pathinfo($path);
95 48
        }
96
97 48
        $this->cache[$path] = array_merge($this->cache[$path], $object);
98
99 48
        if ($autosave) {
100 21
            $this->autosave();
101 21
        }
102
103 48
        $this->ensureParentDirectories($path);
104 48
    }
105
106
    /**
107
     * Store object hit miss.
108
     *
109
     * @param string $path
110
     */
111 6
    public function storeMiss($path)
112
    {
113 6
        $this->cache[$path] = false;
114 6
        $this->autosave();
115 6
    }
116
117
    /**
118
     * Get the contents listing.
119
     *
120
     * @param string $dirname
121
     * @param bool   $recursive
122
     *
123
     * @return array contents listing
124
     */
125 9
    public function listContents($dirname = '', $recursive = false)
126
    {
127 9
        $result = [];
128
129 9
        foreach ($this->cache as $object) {
130 9
            if ($object === false) {
131 9
                continue;
132 9
            }
133 3
            if ($object['dirname'] === $dirname) {
134 3
                $result[] = $object;
135 9
            } elseif ($recursive && $this->pathIsInDirectory($dirname, $object['path'])) {
136
                $result[] = $object;
137 9
            }
138
        }
139
140
        return $result;
141
    }
142
143 60
    /**
144
     * {@inheritdoc}
145 60
     */
146 18
    public function has($path)
147
    {
148
        if ($path !== false && array_key_exists($path, $this->cache)) {
149 54
            return $this->cache[$path] !== false;
150 3
        }
151
152 51
        if ($this->isComplete(Util::dirname($path), false)) {
153
            return false;
154
        }
155
    }
156
157 12
    /**
158
     * {@inheritdoc}
159 12
     */
160 6
    public function read($path)
161
    {
162
        if (isset($this->cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) {
163 9
            return $this->cache[$path];
164
        }
165
166
        return false;
167
    }
168
169 3
    /**
170
     * {@inheritdoc}
171 3
     */
172
    public function readStream($path)
173
    {
174
        return false;
175
    }
176
177 5
    /**
178
     * {@inheritdoc}
179 3
     */
180 3
    public function rename($path, $newpath)
181 3
    {
182 3
        if ($this->has($path)) {
183 3
            $object = $this->cache[$path];
184 3
            unset($this->cache[$path]);
185 5
            $object['path'] = $newpath;
186 3
            $object = array_merge($object, Util::pathinfo($newpath));
187 3
            $this->cache[$newpath] = $object;
188
            $this->autosave();
189
        }
190
    }
191
192 6
    /**
193
     * {@inheritdoc}
194 6
     */
195 3
    public function copy($path, $newpath)
196 3
    {
197 3
        if ($this->has($path)) {
198 3
            $object = $this->cache[$path];
199 6
            $object = array_merge($object, Util::pathinfo($newpath));
200
            $this->updateObject($newpath, $object, true);
201
        }
202
    }
203
204 3
    /**
205
     * {@inheritdoc}
206 3
     */
207 3
    public function delete($path)
208
    {
209
        $this->storeMiss($path);
210
    }
211
212 6
    /**
213
     * {@inheritdoc}
214 6
     */
215 6
    public function deleteDir($dirname)
216 6
    {
217 6
        foreach ($this->cache as $path => $object) {
218 6
            if ($this->pathIsInDirectory($dirname, $path) || $path === $dirname) {
219
                unset($this->cache[$path]);
220 6
            }
221
        }
222 6
223 6
        unset($this->complete[$dirname]);
224
225
        $this->autosave();
226
    }
227
228 6
    /**
229
     * {@inheritdoc}
230 6
     */
231 3
    public function getMimetype($path)
232
    {
233
        if (isset($this->cache[$path]['mimetype'])) {
234 6
            return $this->cache[$path];
235 3
        }
236
237
        if (! $result = $this->read($path)) {
238 3
            return false;
239 3
        }
240
241 3
        $mimetype = Util::guessMimeType($path, $result['contents']);
242
        $this->cache[$path]['mimetype'] = $mimetype;
243
244
        return $this->cache[$path];
245
    }
246
247 3
    /**
248
     * {@inheritdoc}
249 3
     */
250 3
    public function getSize($path)
251
    {
252
        if (isset($this->cache[$path]['size'])) {
253 3
            return $this->cache[$path];
254
        }
255
256
        return false;
257
    }
258
259 3
    /**
260
     * {@inheritdoc}
261 3
     */
262 3
    public function getTimestamp($path)
263
    {
264
        if (isset($this->cache[$path]['timestamp'])) {
265 3
            return $this->cache[$path];
266
        }
267
268
        return false;
269
    }
270
271 3
    /**
272
     * {@inheritdoc}
273 3
     */
274 3
    public function getVisibility($path)
275
    {
276
        if (isset($this->cache[$path]['visibility'])) {
277 3
            return $this->cache[$path];
278
        }
279
280
        return false;
281
    }
282
283 18
    /**
284
     * {@inheritdoc}
285 18
     */
286 15
    public function getMetadata($path)
287
    {
288
        if (isset($this->cache[$path]['type'])) {
289 3
            return $this->cache[$path];
290
        }
291
292
        return false;
293
    }
294
295 99
    /**
296
     * {@inheritdoc}
297 99
     */
298 75
    public function isComplete($dirname, $recursive)
299
    {
300
        if (! array_key_exists($dirname, $this->complete)) {
301 33
            return false;
302 3
        }
303
304
        if ($recursive && $this->complete[$dirname] !== 'recursive') {
305 33
            return false;
306
        }
307
308
        return true;
309
    }
310
311 24
    /**
312
     * {@inheritdoc}
313 24
     */
314 24
    public function setComplete($dirname, $recursive)
315
    {
316
        $this->complete[$dirname] = $recursive ? 'recursive' : true;
317
    }
318
319
    /**
320
     * Filter the contents from a listing.
321
     *
322
     * @param array $contents object listing
323 39
     *
324
     * @return array filtered contents
325 39
     */
326 39
    public function cleanContents(array $contents)
327 39
    {
328 39
        $cachedProperties = array_flip([
329
            'path', 'dirname', 'basename', 'extension', 'filename',
330 39
            'size', 'mimetype', 'visibility', 'timestamp', 'type',
331 12
            'md5',
332 12
        ]);
333 12
334 39
        foreach ($contents as $path => $object) {
335
            if (is_array($object)) {
336 39
                $contents[$path] = array_intersect_key($object, $cachedProperties);
337
            }
338
        }
339
340
        return $contents;
341
    }
342 3
343
    /**
344 3
     * {@inheritdoc}
345 3
     */
346 3
    public function flush()
347 3
    {
348
        $this->cache = [];
349
        $this->complete = [];
350
        $this->autosave();
351
    }
352 51
353
    /**
354 51
     * {@inheritdoc}
355 51
     */
356 51
    public function autosave()
357 51
    {
358
        if ($this->autosave) {
359
            $this->save();
360
        }
361
    }
362
363
    /**
364 24
     * Retrieve serialized cache data.
365
     *
366 24
     * @return string serialized data
367
     */
368 24
    public function getForStorage()
369
    {
370
        $cleaned = $this->cleanContents($this->cache);
371
372
        return json_encode([$cleaned, $this->complete]);
373
    }
374
375
    /**
376 18
     * Load from serialized cache data.
377
     *
378 18
     * @param string $json
379
     */
380 18
    public function setFromStorage($json)
381 18
    {
382 18
        list($cache, $complete) = json_decode($json, true);
383 18
384 18
        if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) {
385
            $this->cache = $cache;
386
            $this->complete = $complete;
387
        }
388
    }
389
390
    /**
391 48
     * Ensure parent directories of an object.
392
     *
393 48
     * @param string $path object path
394
     */
395 48
    public function ensureParentDirectories($path)
396 12
    {
397 12
        $object = $this->cache[$path];
398 12
399 12
        while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) {
400 48
            $object = Util::pathinfo($object['dirname']);
401
            $object['type'] = 'dir';
402
            $this->cache[$object['path']] = $object;
403
        }
404
    }
405
406
    /**
407
     * Determines if the path is inside the directory.
408
     *
409
     * @param string $directory
410 18
     * @param string $path
411
     *
412 18
     * @return bool
413
     */
414
    protected function pathIsInDirectory($directory, $path)
415
    {
416
        return $directory === '' || strpos($path, $directory . '/') === 0;
417
    }
418
}
419