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 PhpConsole; |
||
4 | |||
5 | /** |
||
6 | * Overrides PHP errors and exceptions handlers, so all errors, exceptions and debug messages will be sent to PHP Console client |
||
7 | * By default all handled errors and exceptions will be passed to previously defined handlers |
||
8 | * |
||
9 | * You will need to install Google Chrome extension "PHP Console" |
||
10 | * https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef |
||
11 | * |
||
12 | * @package PhpConsole |
||
13 | * @version 3.1 |
||
14 | * @link http://consle.com |
||
15 | * @author Sergey Barbushin http://linkedin.com/in/barbushin |
||
16 | * @copyright © Sergey Barbushin, 2011-2013. All rights reserved. |
||
17 | * @license http://www.opensource.org/licenses/BSD-3-Clause "The BSD 3-Clause License" |
||
18 | */ |
||
19 | class Handler { |
||
20 | |||
21 | const ERRORS_RECURSION_LIMIT = 3; |
||
22 | |||
23 | /** @var Handler */ |
||
24 | protected static $instance; |
||
25 | |||
26 | /** @var Connector */ |
||
27 | protected $connector; |
||
28 | protected $isStarted = false; |
||
29 | protected $isHandling = false; |
||
30 | protected $errorsHandlerLevel; |
||
31 | protected $handleErrors = true; |
||
32 | protected $handleExceptions = true; |
||
33 | protected $callOldHandlers = true; |
||
34 | protected $oldErrorsHandler; |
||
35 | protected $oldExceptionsHandler; |
||
36 | protected $recursiveHandlingLevel = 0; |
||
37 | |||
38 | /** |
||
39 | * @return static |
||
40 | */ |
||
41 | 22 | public static function getInstance() { |
|
42 | 22 | if(!self::$instance) { |
|
43 | 1 | self::$instance = new static(); |
|
44 | } |
||
45 | 22 | return self::$instance; |
|
46 | } |
||
47 | |||
48 | 1 | protected function __construct() { |
|
49 | 1 | $this->connector = Connector::getInstance(); |
|
50 | 1 | } |
|
51 | |||
52 | /** |
||
53 | * @codeCoverageIgnore |
||
54 | */ |
||
55 | private final function __clone() { |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Start errors & exceptions handlers |
||
60 | * @throws \Exception |
||
61 | */ |
||
62 | 16 | public function start() { |
|
63 | 16 | if($this->isStarted) { |
|
64 | 1 | throw new \Exception(get_called_class() . ' is already started, use ' . get_called_class() . '::getInstance()->isStarted() to check it.'); |
|
65 | } |
||
66 | 16 | $this->isStarted = true; |
|
67 | |||
68 | 16 | if($this->handleErrors) { |
|
69 | 16 | $this->initErrorsHandler(); |
|
70 | } |
||
71 | 16 | if($this->handleExceptions) { |
|
72 | 16 | $this->initExceptionsHandler(); |
|
73 | } |
||
74 | 16 | } |
|
75 | |||
76 | /** |
||
77 | * Validate that method is called before start. Required for handlers configuration methods. |
||
78 | * @throws \Exception |
||
79 | */ |
||
80 | 4 | protected function checkIsCalledBeforeStart() { |
|
81 | 4 | if($this->isStarted) { |
|
82 | 3 | throw new \Exception('This method can be called only before ' . get_class($this) . '::start()'); |
|
83 | } |
||
84 | 1 | } |
|
85 | |||
86 | /** |
||
87 | * Enable or disable errors handler |
||
88 | * @param bool $isEnabled |
||
89 | */ |
||
90 | 1 | public function setHandleErrors($isEnabled) { |
|
91 | 1 | $this->checkIsCalledBeforeStart(); |
|
92 | $this->handleErrors = $isEnabled; // @codeCoverageIgnore |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Enable or disable exceptions handler |
||
97 | * @param bool $isEnabled |
||
98 | */ |
||
99 | 1 | public function setHandleExceptions($isEnabled) { |
|
100 | 1 | $this->checkIsCalledBeforeStart(); |
|
101 | $this->handleExceptions = $isEnabled; // @codeCoverageIgnore |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Enable or disable calling overridden errors & exceptions |
||
106 | * @param bool $isEnabled |
||
107 | */ |
||
108 | 2 | public function setCallOldHandlers($isEnabled) { |
|
109 | 2 | $this->callOldHandlers = $isEnabled; |
|
110 | 2 | } |
|
111 | |||
112 | /** |
||
113 | * @return Connector |
||
114 | */ |
||
115 | 2 | public function getConnector() { |
|
116 | 2 | return $this->connector; |
|
117 | } |
||
118 | |||
119 | /** |
||
120 | * Check if PHP Console handler is started |
||
121 | * @return bool |
||
122 | */ |
||
123 | public function isStarted() { |
||
124 | return $this->isStarted; |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Override PHP exceptions handler to PHP Console handler |
||
129 | */ |
||
130 | 16 | protected function initExceptionsHandler() { |
|
131 | 16 | $this->oldExceptionsHandler = set_exception_handler(array($this, 'handleException')); |
|
132 | 16 | } |
|
133 | |||
134 | /** |
||
135 | * Set custom errors handler level like E_ALL ^ E_STRICT |
||
136 | * But, anyway, it's strongly recommended to configure ignore some errors type in PHP Console extension options |
||
137 | * IMPORTANT: previously old error handler will be called only with new errors level |
||
138 | * @param int $level see http://us1.php.net/manual/ru/function.error-reporting.php |
||
139 | */ |
||
140 | 2 | public function setErrorsHandlerLevel($level) { |
|
141 | 2 | $this->checkIsCalledBeforeStart(); |
|
142 | 1 | $this->errorsHandlerLevel = $level; |
|
143 | 1 | } |
|
144 | |||
145 | /** |
||
146 | * Override PHP errors handler to PHP Console handler |
||
147 | */ |
||
148 | 16 | protected function initErrorsHandler() { |
|
149 | 16 | ini_set('display_errors', false); |
|
150 | 16 | error_reporting($this->errorsHandlerLevel ? : E_ALL | E_STRICT); |
|
151 | 16 | $this->oldErrorsHandler = set_error_handler(array($this, 'handleError')); |
|
152 | 16 | register_shutdown_function(array($this, 'checkFatalErrorOnShutDown')); |
|
153 | 16 | $this->connector->registerFlushOnShutDown(); |
|
154 | 16 | } |
|
155 | |||
156 | /** |
||
157 | * Method is called by register_shutdown_function(), it's required to handle fatal PHP errors. Never call it manually. |
||
158 | * @codeCoverageIgnore |
||
159 | */ |
||
160 | public function checkFatalErrorOnShutDown() { |
||
161 | $error = error_get_last(); |
||
162 | if($error) { |
||
0 ignored issues
–
show
|
|||
163 | ini_set('memory_limit', memory_get_usage(true) + 1000000); // if memory limit exceeded |
||
164 | $this->callOldHandlers = false; |
||
165 | $this->handleError($error['type'], $error['message'], $error['file'], $error['line'], null, 1); |
||
166 | } |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Handle error data |
||
171 | * @param int|null $code |
||
172 | * @param string|null $text |
||
173 | * @param string|null $file |
||
174 | * @param int|null $line |
||
175 | * @param null $context |
||
176 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore |
||
177 | */ |
||
178 | 7 | public function handleError($code = null, $text = null, $file = null, $line = null, $context = null, $ignoreTraceCalls = 0) { |
|
179 | 7 | if(!$this->isStarted || error_reporting() === 0 || $this->isHandlingDisabled() || ($this->errorsHandlerLevel && !($code & $this->errorsHandlerLevel))) { |
|
180 | 4 | return; |
|
181 | } |
||
182 | 5 | $this->onHandlingStart(); |
|
183 | 5 | $this->connector->getErrorsDispatcher()->dispatchError($code, $text, $file, $line, is_numeric($ignoreTraceCalls) ? $ignoreTraceCalls + 1 : $ignoreTraceCalls); |
|
184 | 5 | if($this->oldErrorsHandler && $this->callOldHandlers) { |
|
185 | 4 | call_user_func_array($this->oldErrorsHandler, array($code, $text, $file, $line, $context)); |
|
186 | } |
||
187 | 5 | $this->onHandlingComplete(); |
|
188 | 5 | } |
|
189 | |||
190 | /** |
||
191 | * Method is called before handling any error or exception |
||
192 | */ |
||
193 | 9 | protected function onHandlingStart() { |
|
194 | 9 | $this->recursiveHandlingLevel++; |
|
195 | 9 | } |
|
196 | |||
197 | /** |
||
198 | * Method is called after handling any error or exception |
||
199 | */ |
||
200 | 9 | protected function onHandlingComplete() { |
|
201 | 9 | $this->recursiveHandlingLevel--; |
|
202 | 9 | } |
|
203 | |||
204 | /** |
||
205 | * Check if errors/exception handling is disabled |
||
206 | * @return bool |
||
207 | */ |
||
208 | 10 | protected function isHandlingDisabled() { |
|
209 | 10 | return $this->recursiveHandlingLevel >= static::ERRORS_RECURSION_LIMIT; |
|
210 | } |
||
211 | |||
212 | /** |
||
213 | * Handle exception object |
||
214 | * @param \Exception|\Throwable $exception |
||
215 | */ |
||
216 | 5 | public function handleException($exception) { |
|
217 | 5 | if(!$this->isStarted || $this->isHandlingDisabled()) { |
|
218 | 2 | return; |
|
219 | } |
||
220 | try { |
||
221 | 4 | $this->onHandlingStart(); |
|
222 | 4 | $this->connector->getErrorsDispatcher()->dispatchException($exception); |
|
223 | 4 | if($this->oldExceptionsHandler && $this->callOldHandlers) { |
|
224 | 4 | call_user_func($this->oldExceptionsHandler, $exception); |
|
225 | } |
||
226 | } |
||
227 | catch(\Throwable $internalException) { |
||
228 | $this->handleException($internalException); |
||
229 | } |
||
230 | catch(\Exception $internalException) { |
||
231 | $this->handleException($internalException); |
||
232 | } |
||
233 | 4 | $this->onHandlingComplete(); |
|
234 | 4 | } |
|
235 | |||
236 | /** |
||
237 | * Handle debug data |
||
238 | * @param mixed $data |
||
239 | * @param string|null $tags Tags separated by dot, e.g. "low.db.billing" |
||
240 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore |
||
241 | */ |
||
242 | 1 | public function debug($data, $tags = null, $ignoreTraceCalls = 0) { |
|
243 | 1 | if($this->connector->isActiveClient()) { |
|
244 | 1 | $this->connector->getDebugDispatcher()->dispatchDebug($data, $tags, is_numeric($ignoreTraceCalls) ? $ignoreTraceCalls + 1 : $ignoreTraceCalls); |
|
245 | } |
||
246 | 1 | } |
|
247 | } |
||
248 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.