This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\Azure; |
||
4 | |||
5 | use League\Flysystem\Adapter\AbstractAdapter; |
||
6 | use League\Flysystem\Adapter\Polyfill\NotSupportingVisibilityTrait; |
||
7 | use League\Flysystem\Config; |
||
8 | use League\Flysystem\Util; |
||
9 | use MicrosoftAzure\Storage\Blob\Internal\IBlob; |
||
10 | use MicrosoftAzure\Storage\Blob\Models\BlobPrefix; |
||
11 | use MicrosoftAzure\Storage\Blob\Models\BlobProperties; |
||
12 | use MicrosoftAzure\Storage\Blob\Models\CopyBlobResult; |
||
13 | use MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions; |
||
14 | use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions; |
||
15 | use MicrosoftAzure\Storage\Blob\Models\ListBlobsResult; |
||
16 | use MicrosoftAzure\Storage\Common\ServiceException; |
||
17 | |||
18 | class AzureAdapter extends AbstractAdapter |
||
19 | { |
||
20 | use NotSupportingVisibilityTrait; |
||
21 | |||
22 | /** |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $container; |
||
26 | |||
27 | /** |
||
28 | * @var IBlob |
||
29 | */ |
||
30 | protected $client; |
||
31 | |||
32 | /** |
||
33 | * @var string[] |
||
34 | */ |
||
35 | protected static $metaOptions = [ |
||
36 | 'CacheControl', |
||
37 | 'ContentType', |
||
38 | 'Metadata', |
||
39 | 'ContentLanguage', |
||
40 | 'ContentEncoding', |
||
41 | ]; |
||
42 | |||
43 | /** |
||
44 | * Constructor. |
||
45 | * |
||
46 | * @param IBlob $azureClient |
||
47 | * @param string $container |
||
48 | * @param string $prefix |
||
49 | */ |
||
50 | public function __construct(IBlob $azureClient, $container, $prefix = null) |
||
51 | { |
||
52 | $this->client = $azureClient; |
||
53 | $this->container = $container; |
||
54 | $this->setPathPrefix($prefix); |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * {@inheritdoc} |
||
59 | */ |
||
60 | public function write($path, $contents, Config $config) |
||
61 | { |
||
62 | return $this->upload($path, $contents, $config); |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * {@inheritdoc} |
||
67 | */ |
||
68 | public function writeStream($path, $resource, Config $config) |
||
69 | { |
||
70 | return $this->upload($path, $resource, $config); |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * {@inheritdoc} |
||
75 | */ |
||
76 | public function update($path, $contents, Config $config) |
||
77 | { |
||
78 | return $this->upload($path, $contents, $config); |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * {@inheritdoc} |
||
83 | */ |
||
84 | public function updateStream($path, $resource, Config $config) |
||
85 | { |
||
86 | return $this->upload($path, $resource, $config); |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * {@inheritdoc} |
||
91 | */ |
||
92 | public function rename($path, $newpath) |
||
93 | { |
||
94 | $this->copy($path, $newpath); |
||
95 | |||
96 | return $this->delete($path); |
||
97 | } |
||
98 | |||
99 | public function copy($path, $newpath) |
||
100 | { |
||
101 | $path = $this->applyPathPrefix($path); |
||
102 | $newpath = $this->applyPathPrefix($newpath); |
||
103 | |||
104 | $this->client->copyBlob($this->container, $newpath, $this->container, $path); |
||
105 | |||
106 | return true; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * {@inheritdoc} |
||
111 | */ |
||
112 | public function delete($path) |
||
113 | { |
||
114 | $path = $this->applyPathPrefix($path); |
||
115 | |||
116 | $this->client->deleteBlob($this->container, $path); |
||
117 | |||
118 | return true; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * {@inheritdoc} |
||
123 | */ |
||
124 | public function deleteDir($dirname) |
||
125 | { |
||
126 | $dirname = $this->applyPathPrefix($dirname); |
||
127 | |||
128 | $options = new ListBlobsOptions(); |
||
129 | $options->setPrefix($dirname . '/'); |
||
130 | |||
131 | /** @var ListBlobsResult $listResults */ |
||
132 | $listResults = $this->client->listBlobs($this->container, $options); |
||
0 ignored issues
–
show
|
|||
133 | |||
134 | foreach ($listResults->getBlobs() as $blob) { |
||
135 | /** @var \MicrosoftAzure\Storage\Blob\Models\Blob $blob */ |
||
136 | $this->client->deleteBlob($this->container, $blob->getName()); |
||
137 | } |
||
138 | |||
139 | return true; |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * {@inheritdoc} |
||
144 | */ |
||
145 | public function createDir($dirname, Config $config) |
||
146 | { |
||
147 | $this->write(rtrim($dirname, '/') . '/', ' ', $config); |
||
148 | |||
149 | return ['path' => $dirname, 'type' => 'dir']; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * {@inheritdoc} |
||
154 | */ |
||
155 | public function has($path) |
||
156 | { |
||
157 | $path = $this->applyPathPrefix($path); |
||
158 | |||
159 | try { |
||
160 | $this->client->getBlobMetadata($this->container, $path); |
||
161 | } catch (ServiceException $e) { |
||
162 | if ($e->getCode() !== 404) { |
||
163 | throw $e; |
||
164 | } |
||
165 | |||
166 | return false; |
||
167 | } |
||
168 | |||
169 | return true; |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * {@inheritdoc} |
||
174 | */ |
||
175 | View Code Duplication | public function read($path) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
176 | { |
||
177 | $path = $this->applyPathPrefix($path); |
||
178 | |||
179 | /** @var \MicrosoftAzure\Storage\Blob\Models\GetBlobResult $blobResult */ |
||
180 | $blobResult = $this->client->getBlob($this->container, $path); |
||
181 | $properties = $blobResult->getProperties(); |
||
182 | $content = $this->streamContentsToString($blobResult->getContentStream()); |
||
183 | |||
184 | return $this->normalizeBlobProperties($path, $properties) + ['contents' => $content]; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * {@inheritdoc} |
||
189 | */ |
||
190 | View Code Duplication | public function readStream($path) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
191 | { |
||
192 | $path = $this->applyPathPrefix($path); |
||
193 | |||
194 | /** @var \MicrosoftAzure\Storage\Blob\Models\GetBlobResult $blobResult */ |
||
195 | $blobResult = $this->client->getBlob($this->container, $path); |
||
196 | $properties = $blobResult->getProperties(); |
||
197 | |||
198 | return $this->normalizeBlobProperties($path, $properties) + ['stream' => $blobResult->getContentStream()]; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * {@inheritdoc} |
||
203 | */ |
||
204 | public function listContents($directory = '', $recursive = false) |
||
205 | { |
||
206 | $directory = $this->applyPathPrefix($directory); |
||
207 | |||
208 | // Append trailing slash only for directory other than root (which after normalization is an empty string). |
||
209 | // Listing for / doesn't work properly otherwise. |
||
210 | if (strlen($directory)) { |
||
211 | $directory = rtrim($directory, '/') . '/'; |
||
212 | } |
||
213 | |||
214 | $options = new ListBlobsOptions(); |
||
215 | $options->setPrefix($directory); |
||
216 | |||
217 | if ( ! $recursive) { |
||
218 | $options->setDelimiter('/'); |
||
219 | } |
||
220 | |||
221 | /** @var ListBlobsResult $listResults */ |
||
222 | $listResults = $this->client->listBlobs($this->container, $options); |
||
0 ignored issues
–
show
$options is of type object<MicrosoftAzure\St...odels\ListBlobsOptions> , but the function expects a object<MicrosoftAzure\St...\ListBlobsOptions>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
223 | |||
224 | $contents = []; |
||
225 | |||
226 | foreach ($listResults->getBlobs() as $blob) { |
||
227 | $contents[] = $this->normalizeBlobProperties($blob->getName(), $blob->getProperties()); |
||
228 | } |
||
229 | |||
230 | if ( ! $recursive) { |
||
231 | $contents = array_merge( |
||
232 | $contents, |
||
233 | array_map([$this, 'normalizeBlobPrefix'], $listResults->getBlobPrefixes()) |
||
234 | ); |
||
235 | } |
||
236 | |||
237 | return Util::emulateDirectories($contents); |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * {@inheritdoc} |
||
242 | */ |
||
243 | public function getMetadata($path) |
||
244 | { |
||
245 | $path = $this->applyPathPrefix($path); |
||
246 | |||
247 | /** @var \MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesResult $result */ |
||
248 | $result = $this->client->getBlobProperties($this->container, $path); |
||
249 | |||
250 | return $this->normalizeBlobProperties($path, $result->getProperties()); |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * {@inheritdoc} |
||
255 | */ |
||
256 | public function getSize($path) |
||
257 | { |
||
258 | return $this->getMetadata($path); |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * {@inheritdoc} |
||
263 | */ |
||
264 | public function getMimetype($path) |
||
265 | { |
||
266 | return $this->getMetadata($path); |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * {@inheritdoc} |
||
271 | */ |
||
272 | public function getTimestamp($path) |
||
273 | { |
||
274 | return $this->getMetadata($path); |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Builds the normalized output array. |
||
279 | * |
||
280 | * @param string $path |
||
281 | * @param int $timestamp |
||
282 | * @param mixed $content |
||
283 | * |
||
284 | * @return array |
||
285 | */ |
||
286 | protected function normalize($path, $timestamp, $content = null) |
||
287 | { |
||
288 | $data = [ |
||
289 | 'path' => $path, |
||
290 | 'timestamp' => (int) $timestamp, |
||
291 | 'dirname' => Util::dirname($path), |
||
292 | 'type' => 'file', |
||
293 | ]; |
||
294 | |||
295 | if (is_string($content)) { |
||
296 | $data['contents'] = $content; |
||
297 | } |
||
298 | |||
299 | return $data; |
||
300 | } |
||
301 | |||
302 | /** |
||
303 | * Builds the normalized output array from a Blob object. |
||
304 | * |
||
305 | * @param string $path |
||
306 | * @param BlobProperties $properties |
||
307 | * |
||
308 | * @return array |
||
309 | */ |
||
310 | protected function normalizeBlobProperties($path, BlobProperties $properties) |
||
311 | { |
||
312 | if (substr($path, -1) === '/') { |
||
313 | return ['type' => 'dir', 'path' => $this->removePathPrefix(rtrim($path, '/'))]; |
||
314 | } |
||
315 | |||
316 | $path = $this->removePathPrefix($path); |
||
317 | |||
318 | return [ |
||
319 | 'path' => $path, |
||
320 | 'timestamp' => (int) $properties->getLastModified()->format('U'), |
||
321 | 'dirname' => Util::dirname($path), |
||
322 | 'mimetype' => $properties->getContentType(), |
||
323 | 'size' => $properties->getContentLength(), |
||
324 | 'type' => 'file', |
||
325 | ]; |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Builds the normalized output array from a BlobPrefix object. |
||
330 | * |
||
331 | * @param BlobPrefix $blobPrefix |
||
332 | * |
||
333 | * @return array |
||
334 | */ |
||
335 | protected function normalizeBlobPrefix(BlobPrefix $blobPrefix) |
||
336 | { |
||
337 | return ['type' => 'dir', 'path' => $this->removePathPrefix(rtrim($blobPrefix->getName(), '/'))]; |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Retrieves content streamed by Azure into a string. |
||
342 | * |
||
343 | * @param resource $resource |
||
344 | * |
||
345 | * @return string |
||
346 | */ |
||
347 | protected function streamContentsToString($resource) |
||
348 | { |
||
349 | return stream_get_contents($resource); |
||
350 | } |
||
351 | |||
352 | /** |
||
353 | * Upload a file. |
||
354 | * |
||
355 | * @param string $path Path |
||
356 | * @param string|resource $contents Either a string or a stream. |
||
357 | * @param Config $config Config |
||
358 | * |
||
359 | * @return array |
||
360 | */ |
||
361 | protected function upload($path, $contents, Config $config) |
||
362 | { |
||
363 | $path = $this->applyPathPrefix($path); |
||
364 | |||
365 | /** @var CopyBlobResult $result */ |
||
366 | $result = $this->client->createBlockBlob( |
||
367 | $this->container, |
||
368 | $path, |
||
369 | $contents, |
||
0 ignored issues
–
show
It seems like
$contents defined by parameter $contents on line 361 can also be of type resource ; however, MicrosoftAzure\Storage\B...Blob::createBlockBlob() does only seem to accept string , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
370 | $this->getOptionsFromConfig($config) |
||
0 ignored issues
–
show
$this->getOptionsFromConfig($config) is of type object<MicrosoftAzure\St...dels\CreateBlobOptions> , but the function expects a object<MicrosoftAzure\St...CreateBlobOptions>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
371 | ); |
||
372 | |||
373 | return $this->normalize($path, $result->getLastModified()->format('U'), $contents); |
||
374 | } |
||
375 | |||
376 | /** |
||
377 | * Retrieve options from a Config instance. |
||
378 | * |
||
379 | * @param Config $config |
||
380 | * |
||
381 | * @return CreateBlobOptions |
||
382 | */ |
||
383 | protected function getOptionsFromConfig(Config $config) |
||
384 | { |
||
385 | $options = new CreateBlobOptions(); |
||
386 | |||
387 | foreach (static::$metaOptions as $option) { |
||
388 | if ( ! $config->has($option)) { |
||
389 | continue; |
||
390 | } |
||
391 | |||
392 | call_user_func([$options, "set$option"], $config->get($option)); |
||
393 | } |
||
394 | |||
395 | if ($mimetype = $config->get('mimetype')) { |
||
396 | $options->setContentType($mimetype); |
||
397 | } |
||
398 | |||
399 | return $options; |
||
400 | } |
||
401 | } |
||
402 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: