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 Psr7Middlewares\Middleware; |
||
4 | |||
5 | use Psr7Middlewares\Utils; |
||
6 | use Psr\Http\Message\ServerRequestInterface; |
||
7 | use Psr\Http\Message\ResponseInterface; |
||
8 | |||
9 | /** |
||
10 | * Middleware to handle php errors and exceptions. |
||
11 | */ |
||
12 | class ErrorHandler |
||
13 | { |
||
14 | const KEY = 'EXCEPTION'; |
||
15 | |||
16 | use Utils\CallableTrait; |
||
17 | use Utils\AttributeTrait; |
||
18 | use Utils\StreamTrait; |
||
19 | |||
20 | /** |
||
21 | * @var callable|string The handler used |
||
22 | */ |
||
23 | private $handler; |
||
24 | |||
25 | /** |
||
26 | * @var callable|null The status code validator |
||
27 | */ |
||
28 | private $statusCodeValidator; |
||
29 | |||
30 | /** |
||
31 | * @var bool Whether or not catch exceptions |
||
32 | */ |
||
33 | private $catchExceptions = false; |
||
34 | |||
35 | /** |
||
36 | * Returns the exception throwed. |
||
37 | * |
||
38 | * @param ServerRequestInterface $request |
||
39 | * |
||
40 | * @return \Exception|null |
||
41 | */ |
||
42 | public static function getException(ServerRequestInterface $request) |
||
43 | { |
||
44 | return self::getAttribute($request, self::KEY); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Constructor. |
||
49 | * |
||
50 | * @param callable|string|null $handler |
||
51 | */ |
||
52 | public function __construct($handler = null) |
||
53 | { |
||
54 | $this->handler = $handler; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Configure the catchExceptions. |
||
59 | * |
||
60 | * @param bool $catch |
||
61 | * |
||
62 | * @return self |
||
63 | */ |
||
64 | public function catchExceptions($catch = true) |
||
65 | { |
||
66 | $this->catchExceptions = (bool) $catch; |
||
67 | |||
68 | return $this; |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Configure the status code validator. |
||
73 | * |
||
74 | * @param callable $statusCodeValidator |
||
75 | * |
||
76 | * @return self |
||
77 | */ |
||
78 | public function statusCode(callable $statusCodeValidator) |
||
79 | { |
||
80 | $this->statusCodeValidator = $statusCodeValidator; |
||
81 | |||
82 | return $this; |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Execute the middleware. |
||
87 | * |
||
88 | * @param ServerRequestInterface $request |
||
89 | * @param ResponseInterface $response |
||
90 | * @param callable $next |
||
91 | * |
||
92 | * @return ResponseInterface |
||
93 | */ |
||
94 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) |
||
95 | { |
||
96 | ob_start(); |
||
97 | $level = ob_get_level(); |
||
98 | |||
99 | try { |
||
100 | $response = $next($request, $response); |
||
101 | } catch (\Throwable $exception) { |
||
0 ignored issues
–
show
|
|||
102 | if (!$this->catchExceptions) { |
||
103 | throw $exception; |
||
104 | } |
||
105 | |||
106 | $request = self::setAttribute($request, self::KEY, $exception); |
||
107 | $response = $response->withStatus(500); |
||
108 | } catch (\Exception $exception) { |
||
109 | if (!$this->catchExceptions) { |
||
110 | throw $exception; |
||
111 | } |
||
112 | |||
113 | $request = self::setAttribute($request, self::KEY, $exception); |
||
114 | $response = $response->withStatus(500); |
||
115 | } finally { |
||
116 | Utils\Helpers::getOutput($level); |
||
117 | } |
||
118 | |||
119 | if ($this->isError($response->getStatusCode())) { |
||
120 | $callable = $this->handler ?: [$this, 'defaultHandler']; |
||
121 | $body = self::createStream($response->getBody()); |
||
122 | |||
123 | return $this->executeCallable($callable, $request, $response->withBody($body)); |
||
124 | } |
||
125 | |||
126 | return $response; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Check whether the status code represents an error or not. |
||
131 | * |
||
132 | * @param int $statusCode |
||
133 | * |
||
134 | * @return bool |
||
135 | */ |
||
136 | private function isError($statusCode) |
||
137 | { |
||
138 | if ($this->statusCodeValidator) { |
||
139 | return call_user_func($this->statusCodeValidator, $statusCode); |
||
140 | } |
||
141 | |||
142 | return $statusCode >= 400 && $statusCode < 600; |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * Default handler. |
||
147 | * |
||
148 | * @param ServerRequestInterface $request |
||
149 | * @param ResponseInterface $response |
||
150 | * |
||
151 | * @return string |
||
152 | */ |
||
153 | private function defaultHandler(ServerRequestInterface $request, ResponseInterface $response) |
||
154 | { |
||
155 | $statusCode = $response->getStatusCode(); |
||
156 | $exception = self::getException($request); |
||
157 | $message = $exception ? $exception->getMessage() : ''; |
||
158 | |||
159 | switch (Utils\Helpers::getMimeType($response)) { |
||
160 | case 'text/plain': |
||
161 | case 'text/css': |
||
162 | case 'text/javascript': |
||
163 | return self::errorText($statusCode, $message); |
||
164 | |||
165 | case 'image/jpeg': |
||
166 | return self::errorImage($statusCode, $message, 'imagejpeg'); |
||
167 | |||
168 | case 'image/gif': |
||
169 | return self::errorImage($statusCode, $message, 'imagegif'); |
||
170 | |||
171 | case 'image/png': |
||
172 | return self::errorImage($statusCode, $message, 'imagepng'); |
||
173 | |||
174 | case 'image/svg+xml': |
||
175 | return self::errorSvg($statusCode, $message); |
||
176 | |||
177 | case 'application/json': |
||
178 | return self::errorJson($statusCode, $message); |
||
179 | |||
180 | case 'text/xml': |
||
181 | return self::errorXml($statusCode, $message); |
||
182 | |||
183 | default: |
||
184 | return self::errorHtml($statusCode, $message); |
||
185 | } |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Print the error as plain text. |
||
190 | * |
||
191 | * @param int $statusCode |
||
192 | * @param string $message |
||
193 | * |
||
194 | * @return string |
||
195 | */ |
||
196 | private static function errorText($statusCode, $message) |
||
197 | { |
||
198 | return sprintf("Error %s\n%s", $statusCode, $message); |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Print the error as svg image. |
||
203 | * |
||
204 | * @param int $statusCode |
||
205 | * @param string $message |
||
206 | * |
||
207 | * @return string |
||
208 | */ |
||
209 | private static function errorSvg($statusCode, $message) |
||
210 | { |
||
211 | return <<<EOT |
||
212 | <svg xmlns="http://www.w3.org/2000/svg" width="200" height="50" viewBox="0 0 200 50"> |
||
213 | <text x="20" y="30" font-family="sans-serif" title="{$message}"> |
||
214 | Error {$statusCode} |
||
215 | </text> |
||
216 | </svg> |
||
217 | EOT; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * Print the error as html. |
||
222 | * |
||
223 | * @param int $statusCode |
||
224 | * @param string $message |
||
225 | * |
||
226 | * @return string |
||
227 | */ |
||
228 | private static function errorHtml($statusCode, $message) |
||
229 | { |
||
230 | return <<<EOT |
||
231 | <!DOCTYPE html> |
||
232 | <html> |
||
233 | <head> |
||
234 | <meta charset="utf-8"> |
||
235 | <title>Error {$statusCode}</title> |
||
236 | <style>html{font-family: sans-serif;}</style> |
||
237 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
||
238 | </head> |
||
239 | <body> |
||
240 | <h1>Error {$statusCode}</h1> |
||
241 | {$message} |
||
242 | </body> |
||
243 | </html> |
||
244 | EOT; |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Print the error as image. |
||
249 | * |
||
250 | * @param int $statusCode |
||
251 | * @param string $message |
||
252 | * @param string $output |
||
253 | * |
||
254 | * @return string |
||
255 | */ |
||
256 | private static function errorImage($statusCode, $message, $output) |
||
257 | { |
||
258 | $size = 200; |
||
259 | $image = imagecreatetruecolor($size, $size); |
||
260 | $textColor = imagecolorallocate($image, 255, 255, 255); |
||
261 | imagestring($image, 5, 10, 10, "Error {$statusCode}", $textColor); |
||
262 | |||
263 | foreach (str_split($message, intval($size / 10)) as $line => $text) { |
||
264 | imagestring($image, 5, 10, ($line * 18) + 28, $text, $textColor); |
||
265 | } |
||
266 | |||
267 | ob_start(); |
||
268 | $output($image); |
||
269 | |||
270 | return ob_get_clean(); |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Print the error as json. |
||
275 | * |
||
276 | * @param int $statusCode |
||
277 | * @param string $message |
||
278 | * |
||
279 | * @return string |
||
280 | */ |
||
281 | private static function errorJson($statusCode, $message) |
||
282 | { |
||
283 | $output = ['error' => $statusCode]; |
||
284 | |||
285 | if (!empty($message)) { |
||
286 | $output['message'] = $message; |
||
287 | } |
||
288 | |||
289 | return json_encode($output); |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Print the error as xml. |
||
294 | * |
||
295 | * @param int $statusCode |
||
296 | * @param string $message |
||
297 | * |
||
298 | * @return string |
||
299 | */ |
||
300 | private static function errorXml($statusCode, $message) |
||
301 | { |
||
302 | return <<<EOT |
||
303 | <?xml version="1.0" encoding="UTF-8"?> |
||
304 | <error> |
||
305 | <code>{$statusCode}</code> |
||
306 | <message>{$message}</message> |
||
307 | </error> |
||
308 | EOT; |
||
309 | } |
||
310 | } |
||
311 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.