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 | /** |
||
4 | * @copyright Copyright (C) eZ Systems AS. All rights reserved. |
||
5 | * @license For full copyright and license information view LICENSE file distributed with this source code. |
||
6 | */ |
||
7 | namespace eZ\Bundle\EzPublishIOBundle; |
||
8 | |||
9 | use DateTime; |
||
10 | use eZ\Publish\Core\IO\IOServiceInterface; |
||
11 | use eZ\Publish\Core\IO\Values\BinaryFile; |
||
12 | use LogicException; |
||
13 | use Symfony\Component\HttpFoundation\BinaryFileResponse; |
||
14 | use Symfony\Component\HttpFoundation\Request; |
||
15 | use Symfony\Component\HttpFoundation\Response; |
||
16 | |||
17 | /** |
||
18 | * A modified version of HttpFoundation's BinaryFileResponse that accepts a stream as the input. |
||
19 | */ |
||
20 | class BinaryStreamResponse extends Response |
||
21 | { |
||
22 | protected static $trustXSendfileTypeHeader = false; |
||
23 | |||
24 | /** @var BinaryFile */ |
||
25 | protected $file; |
||
26 | |||
27 | /** @var IOServiceInterface */ |
||
28 | protected $ioService; |
||
29 | |||
30 | protected $offset; |
||
31 | |||
32 | protected $maxlen; |
||
33 | |||
34 | /** |
||
35 | * Constructor. |
||
36 | * |
||
37 | * @param BinaryFile $binaryFile The name of the file to stream |
||
38 | * @param IOServiceInterface $ioService The name of the file to stream |
||
39 | * @param int $status The response status code |
||
40 | * @param array $headers An array of response headers |
||
41 | * @param bool $public Files are public by default |
||
42 | * @param string|null $contentDisposition The type of Content-Disposition to set automatically with the filename |
||
43 | * @param bool $autoEtag Whether the ETag header should be automatically set |
||
0 ignored issues
–
show
|
|||
44 | * @param bool $autoLastModified Whether the Last-Modified header should be automatically set |
||
45 | */ |
||
46 | public function __construct(BinaryFile $binaryFile, IOServiceInterface $ioService, $status = 200, $headers = [], $public = true, $contentDisposition = null, $autoLastModified = true) |
||
47 | { |
||
48 | $this->ioService = $ioService; |
||
49 | |||
50 | parent::__construct(null, $status, $headers); |
||
51 | |||
52 | $this->setFile($binaryFile, $contentDisposition, $autoLastModified); |
||
53 | |||
54 | if ($public) { |
||
55 | $this->setPublic(); |
||
56 | } |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * Sets the file to stream. |
||
61 | * |
||
62 | * @param \SplFileInfo|string $file The file to stream |
||
63 | * @param string $contentDisposition |
||
64 | * @param bool $autoEtag |
||
0 ignored issues
–
show
There is no parameter named
$autoEtag . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
65 | * @param bool $autoLastModified |
||
66 | * |
||
67 | * @return BinaryFileResponse |
||
68 | */ |
||
69 | public function setFile($file, $contentDisposition = null, $autoLastModified = true) |
||
70 | { |
||
71 | $this->file = $file; |
||
0 ignored issues
–
show
It seems like
$file of type object<SplFileInfo> or string is incompatible with the declared type object<eZ\Publish\Core\IO\Values\BinaryFile> of property $file .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
72 | |||
73 | if ($autoLastModified) { |
||
74 | $this->setAutoLastModified(); |
||
75 | } |
||
76 | |||
77 | if ($contentDisposition) { |
||
0 ignored issues
–
show
The expression
$contentDisposition of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
78 | $this->setContentDisposition($contentDisposition); |
||
79 | } |
||
80 | |||
81 | return $this; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * Gets the file. |
||
86 | * |
||
87 | * @return BinaryFile The file to stream |
||
88 | */ |
||
89 | public function getFile() |
||
90 | { |
||
91 | return $this->file; |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Automatically sets the Last-Modified header according the file modification date. |
||
96 | */ |
||
97 | public function setAutoLastModified() |
||
98 | { |
||
99 | $this->setLastModified(DateTime::createFromFormat('U', $this->file->mtime->getTimestamp())); |
||
0 ignored issues
–
show
It seems like
\DateTime::createFromFor...>mtime->getTimestamp()) targeting DateTime::createFromFormat() can also be of type false ; however, Symfony\Component\HttpFo...onse::setLastModified() does only seem to accept null|object<DateTimeInterface> , did you maybe forget to handle an error condition?
![]() |
|||
100 | |||
101 | return $this; |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Sets the Content-Disposition header with the given filename. |
||
106 | * |
||
107 | * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT |
||
108 | * @param string $filename Optionally use this filename instead of the real name of the file |
||
109 | * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename |
||
110 | * |
||
111 | * @return BinaryStreamResponse |
||
112 | */ |
||
113 | public function setContentDisposition($disposition, $filename = '', $filenameFallback = '') |
||
114 | { |
||
115 | if ($filename === '') { |
||
116 | $filename = $this->file->id; |
||
117 | } |
||
118 | |||
119 | if (empty($filenameFallback)) { |
||
120 | $filenameFallback = mb_convert_encoding($filename, 'ASCII'); |
||
121 | } |
||
122 | |||
123 | $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback); |
||
124 | $this->headers->set('Content-Disposition', $dispositionHeader); |
||
125 | |||
126 | return $this; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * {@inheritdoc} |
||
131 | */ |
||
132 | public function prepare(Request $request) |
||
133 | { |
||
134 | $this->headers->set('Content-Length', $this->file->size); |
||
135 | $this->headers->set('Accept-Ranges', 'bytes'); |
||
136 | $this->headers->set('Content-Transfer-Encoding', 'binary'); |
||
137 | |||
138 | if (!$this->headers->has('Content-Type')) { |
||
139 | $this->headers->set( |
||
140 | 'Content-Type', |
||
141 | $this->ioService->getMimeType($this->file->id) ?: 'application/octet-stream' |
||
142 | ); |
||
143 | } |
||
144 | |||
145 | if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) { |
||
146 | $this->setProtocolVersion('1.1'); |
||
147 | } |
||
148 | |||
149 | $this->ensureIEOverSSLCompatibility($request); |
||
150 | |||
151 | $this->offset = 0; |
||
152 | $this->maxlen = -1; |
||
153 | |||
154 | if ($request->headers->has('Range')) { |
||
155 | // Process the range headers. |
||
156 | if (!$request->headers->has('If-Range') || $this->getEtag() == $request->headers->get('If-Range')) { |
||
157 | $range = $request->headers->get('Range'); |
||
158 | $fileSize = $this->file->size; |
||
159 | |||
160 | list($start, $end) = explode('-', substr($range, 6), 2) + [0]; |
||
161 | |||
162 | $end = ('' === $end) ? $fileSize - 1 : (int)$end; |
||
163 | |||
164 | if ('' === $start) { |
||
165 | $start = $fileSize - $end; |
||
166 | $end = $fileSize - 1; |
||
167 | } else { |
||
168 | $start = (int)$start; |
||
169 | } |
||
170 | |||
171 | if ($start <= $end) { |
||
172 | if ($start < 0 || $end > $fileSize - 1) { |
||
173 | $this->setStatusCode(416); // HTTP_REQUESTED_RANGE_NOT_SATISFIABLE |
||
174 | } elseif ($start !== 0 || $end !== $fileSize - 1) { |
||
175 | $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1; |
||
176 | $this->offset = $start; |
||
177 | |||
178 | $this->setStatusCode(206); // HTTP_PARTIAL_CONTENT |
||
179 | $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize)); |
||
180 | $this->headers->set('Content-Length', $end - $start + 1); |
||
181 | } |
||
182 | } |
||
183 | } |
||
184 | } |
||
185 | |||
186 | return $this; |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Sends the file. |
||
191 | */ |
||
192 | public function sendContent() |
||
193 | { |
||
194 | if (!$this->isSuccessful()) { |
||
195 | parent::sendContent(); |
||
196 | |||
197 | return; |
||
198 | } |
||
199 | |||
200 | if (0 === $this->maxlen) { |
||
201 | return; |
||
202 | } |
||
203 | |||
204 | $out = fopen('php://output', 'wb'); |
||
205 | $in = $this->ioService->getFileInputStream($this->file); |
||
206 | stream_copy_to_stream($in, $out, $this->maxlen, $this->offset); |
||
207 | |||
208 | fclose($out); |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * {@inheritdoc} |
||
213 | * |
||
214 | * @throws LogicException when the content is not null |
||
215 | */ |
||
216 | public function setContent($content) |
||
217 | { |
||
218 | if (null !== $content) { |
||
219 | throw new LogicException('The content cannot be set on a BinaryStreamResponse instance.'); |
||
220 | } |
||
221 | } |
||
222 | |||
223 | public function getContent() |
||
224 | { |
||
225 | return null; |
||
226 | } |
||
227 | } |
||
228 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italy
is not defined by the methodfinale(...)
.The most likely cause is that the parameter was removed, but the annotation was not.