Issues (1131)

Security Analysis    not enabled

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/exception/AgaviException.class.php (10 issues)

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
// +---------------------------------------------------------------------------+
4
// | This file is part of the Agavi package.                                   |
5
// | Copyright (c) 2005-2011 the Agavi Project.                                |
6
// | Based on the Mojavi3 MVC Framework, Copyright (c) 2003-2005 Sean Kerr.    |
7
// |                                                                           |
8
// | For the full copyright and license information, please view the LICENSE   |
9
// | file that was distributed with this source code. You can also view the    |
10
// | LICENSE file online at http://www.agavi.org/LICENSE.txt                   |
11
// |   vi: set noexpandtab:                                                    |
12
// |   Local Variables:                                                        |
13
// |   indent-tabs-mode: t                                                     |
14
// |   End:                                                                    |
15
// +---------------------------------------------------------------------------+
16
17
18
namespace Agavi\Exception;
19
20
use Agavi\Config\Config;
21
use Agavi\Core\Context;
22
use Agavi\Dispatcher\ExecutionContainer;
23
24
/**
25
 * AgaviException is the base class for all Agavi related exceptions and
26
 * provides an additional method for printing up a detailed view of an
27
 * exception.
28
 *
29
 * @package    agavi
30
 * @subpackage exception
31
 *
32
 * @author     David Zülke <[email protected]>
33
 * @author     Sean Kerr <[email protected]>
34
 * @author     Bob Zoller <[email protected]>
35
 * @copyright  Authors
36
 * @copyright  The Agavi Project
37
 *
38
 * @since      0.9.0
39
 *
40
 * @version    $Id$
41
 */
42
class AgaviException extends \Exception
43
{
44
    /**
45
     * Print the stack trace for this exception.
46
     *
47
     * @param      \Exception         $e         The original exception.
48
     * @param      Context            $context   The context instance.
49
     * @param      ExecutionContainer $container The execution container instance
50
     *
51
     * @author     David Zülke <[email protected]>
52
     * @since      0.9.0
53
     *
54
     * @deprecated Superseded by AgaviException::render()
55
     */
56
    public static function printStackTrace(\Exception $e, Context $context = null, ExecutionContainer $container = null)
57
    {
58
        return self::render($e, $context, $container);
59
    }
60
    
61
    /**
62
     * Returns a fixed stack trace in case the original one from the exception
63
     * does not contain the origin as the first entry in the trace array, which
64
     * appears to happen from time to time or with certain PHP/XDebug versions.
65
     *
66
     * @param      \Exception $e    The exception to pull the trace from.
67
     * @param      \Exception $next Optionally, the next exception to display (pulled
68
     *                             from Exception::getPrevious() and displayed in
69
     *                             reverse order), which will then result in identical
70
     *                             parts of the stack trace not being returned.
71
     *
72
     * @return     array The trace containing the exception origin as first item.
73
     *
74
     * @author     David Zülke <[email protected]>
75
     * @since      1.0.3
76
     */
77
    public static function getFixedTrace(\Exception $e, \Exception $next = null)
78
    {
79
        // fix stack trace in case it doesn't contain the exception origin as the first entry
80
        $fixedTrace = $e->getTrace();
81
        
82
        if (!isset($fixedTrace[0]['file']) || !($fixedTrace[0]['file'] == $e->getFile() && $fixedTrace[0]['line'] == $e->getLine())) {
83
            $fixedTrace = array_merge(array(array('file' => $e->getFile(), 'line' => $e->getLine())), $fixedTrace);
84
        }
85
        
86
        if ($next) {
87
            $nextTrace = self::getFixedTrace($next);
88
            foreach ($fixedTrace as $i => $fixedTraceItem) {
89
                if ($fixedTraceItem == $nextTrace[1]) {
90
                    $fixedTrace = array_slice($fixedTrace, 0, $i);
91
                    break;
92
                }
93
            }
94
        }
95
        
96
        return $fixedTrace;
97
    }
98
    
99
    /**
100
     * Build a list of parameters passed to a method. Example:
101
     * array([object AgaviFilter], 'baz' => array(1, 2), 'log' => [resource stream])
102
     *
103
     * @param      array $params An (associative) array of variables.
104
     * @param      bool  $html   Whether or not to style and encode for HTML output.
105
     * @param      int   $level
106
     *
107
     * @return     string A string, possibly formatted using HTML "em" tags.
108
     *
109
     * @author     David Zülke <[email protected]>
110
     * @since      0.11.0
111
     */
112
    public static function buildParamList($params, $html = true, $level = 1)
113
    {
114
        $retval = array();
115
        foreach ($params as $key => $param) {
116
            if (is_string($key)) {
117 View Code Duplication
                if (preg_match('/^(.{5}).{2,}(.{5})$/us', $key, $matches)) {
0 ignored issues
show
This code seems to be duplicated across 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.

Loading history...
118
                    $key = $matches[1] . '…' . $matches[2];
119
                }
120
                $key = var_export($key, true) . ' => ';
121
                if ($html) {
122
                    $key = htmlspecialchars($key);
123
                }
124
            } else {
125
                $key = '';
126
            }
127
            switch (gettype($param)) {
128
                case 'array':
129
                    $retval[] = $key . 'array(' . ($level < 2 ? self::buildParamList($param, $html, ++$level) : (count($param) ? '…' : '')) . ')';
130
                    break;
131
                case 'object':
132
                    if ($html) {
133
                        $retval[] = $key . '[object <em>' . get_class($param) . '</em>]';
134
                    } else {
135
                        $retval[] = $key . '[object ' . get_class($param) . ']';
136
                    }
137
                    break;
138
                case 'resource':
139
                    if ($html) {
140
                        $retval[] = $key . '[resource <em>' . htmlspecialchars(get_resource_type($param)) . '</em>]';
141
                    } else {
142
                        $retval[] = $key . '[resource ' . get_resource_type($param) . ']';
143
                    }
144
                    break;
145
                case 'string':
146
                    $val = $param;
147 View Code Duplication
                    if (preg_match('/^(.{20}).{3,}(.{20})$/us', $val, $matches)) {
0 ignored issues
show
This code seems to be duplicated across 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.

Loading history...
148
                        $val = $matches[1] . ' … ' . $matches[2];
149
                    }
150
                    $val = var_export($val, true);
151
                    if ($html) {
152
                        $retval[] = $key . htmlspecialchars($val);
153
                    } else {
154
                        $retval[] = $key . $val;
155
                    }
156
                    break;
157
                default:
158
                    if ($html) {
159
                        $retval[] = $key . htmlspecialchars(var_export($param, true));
160
                    } else {
161
                        $retval[] = $key . var_export($param, true);
162
                    }
163
            }
164
        }
165
        return implode(', ', $retval);
166
    }
167
    
168
    /**
169
     * Perform PHP syntax highlighting on the given file.
170
     *
171
     * @param      string $filepath The path of the file to highlight.
172
     *
173
     * @return     array An 0-indexed array of HTML-highlighted code lines.
174
     *
175
     * @author     David Zülke <[email protected]>
176
     * @since      1.0.3
177
     */
178
    public static function highlightFile($filepath)
179
    {
180
        return self::highlightString(file_get_contents($filepath));
181
    }
182
    
183
    /**
184
     * Perform PHP syntax highlighting on the given code string.
185
     *
186
     * @param      string $code The PHP code to highlight.
187
     *
188
     * @return     array An 0-indexed array of HTML-highlighted code lines.
189
     *
190
     * @author     David Zülke <[email protected]>
191
     * @since      1.0.3
192
     */
193
    public static function highlightString($code)
194
    {
195
        $code = highlight_string(str_replace('	', '  ', $code), true);
196
        // time to cleanup this highlighted string
197
        // first, drop all newlines (we'll explode by "<br />")
198
        $code = str_replace(array("\r\n", "\n", "\r"), array('', '', ''), $code);
199
        // second, remove start and end wrappers and replace &nbsp; with numeric entity
200
        $code = str_replace(array(sprintf('<code><span style="color: %s">', ini_get('highlight.html')), '</span></code>', '&nbsp;'), array('', '', '&#160;'), $code);
201
        // make an array of lines
202
        $code = explode('<br />', $code);
203
        // iterate and cleanup each line
204
        $remember = null;
205
        foreach ($code as &$line) {
206
            // we need at least an nbsp for empty lines
207
            if ($line == '') {
208
                $line = '&#160;';
209
            }
210
            
211
            // drop leading </span>
212
            if (strpos($line, '</span>') === 0) {
213
                $line = substr($line, 7);
214
                // no style to carry over from previous line(s)
215
                $remember = null;
216
            }
217
            
218
            // prepend style from previous line if we have one
219
            if ($remember) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $remember 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 ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
220
                $line = sprintf('<span style="color: %s">%s', $remember, $line);
221
            }
222
            
223
            $openingSpanPos = strpos($line, '<span');
224
            $openingSpanRPos = strrpos($line, '<span');
225
            $closingSpanPos = strpos($line, '</span>');
226
            $closingSpanRPos = strrpos($line, '</span>');
0 ignored issues
show
$closingSpanRPos is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
227
            
228
            $balanced = (($openingSpanCount = preg_match_all('#<span#', $line, $matches)) == ($closingSpanCount = preg_match_all('#</span>#', $line, $matches)));
229
            if ($balanced && $openingSpanPos !== false && $openingSpanPos < $closingSpanPos) {
230
                // already balanced, no further cleanup necessary
231
                $remember = null;
232
                continue;
233
            }
234
            
235
            if (substr($line, -7) == '</span>') {
236
                // discard previous style if style terminates in this line
237
                $remember = null;
238
            } else {
239
                // otherwise, remember last style from this line if there is one
240
                if ($openingSpanRPos !== false) {
241
                    // must remember previous color; 20 is the length of '<span style="color: '
242
                    // we're using strpos since someone could set the colors to "#333" or "red" through php.ini, so we don't know the length
243
                    $remember = substr($line, $openingSpanRPos + 20, strpos($line, '"', $openingSpanRPos + 20) - ($openingSpanRPos + 20));
244
                }
245
                // append closing tag
246
                $line .= '</span>';
247
                $closingSpanCount++;
248
            }
249
            
250
            // in case things still are not right...
251
            // can happen for instance when the first line of the file is HTML and we drop the first span, since that is a wrapper for everything
252
            if ($openingSpanCount < $closingSpanCount) {
253
                $line = sprintf('%1$s%2$s', str_repeat('<span color="%3s">', $closingSpanCount - $openingSpanCount), $line, ini_get('highlight.html'));
254
            }
255
            if ($closingSpanCount < $openingSpanCount) {
256
                $line = sprintf('%s%s', $line, str_repeat('</span>', $openingSpanCount - $closingSpanCount), $line);
257
            }
258
        }
259
        
260
        return $code;
261
    }
262
    
263
    /**
264
     * Pretty-print this exception using a template.
265
     *
266
     * @param      \Exception         $exception The original exception.
0 ignored issues
show
There is no parameter named $exception. 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 $italy is not defined by the method finale(...).

/**
 * @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.

Loading history...
267
     * @param      Context            $context   The context instance.
268
     * @param      ExecutionContainer $container The response instance.
269
     *
270
     * @author     David Zülke <[email protected]>
271
     * @since      1.0.0
272
     */
273
    public static function render(\Exception $e, Context $context = null, ExecutionContainer $container = null)
274
    {
275
        // exit code is 70, EX_SOFTWARE, according to /usr/include/sysexits.h: http://cvs.opensolaris.org/source/xref/on/usr/src/head/sysexits.h
276
        // nice touch: an exception template can change this value :)
277
        $exitCode = 70;
278
        
279
        $exceptions = array();
280
        // reverse order of exceptions for linking
281
        $ce = $e;
282
        while ($ce) {
283
            array_unshift($exceptions, $ce);
284
            $ce = $ce->getPrevious();
285
        }
286
        
287
        // discard any previous output waiting in the buffer
288
        while (@ob_end_clean()) {
0 ignored issues
show
This while loop is empty and can be removed.

This check looks for while loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
289
        }
290
        
291
        if ($container !== null && $container->getOutputType() !== null && $container->getOutputType()->getExceptionTemplate() !== null) {
292
            // an exception template was defined for the container's output type
293
            include($container->getOutputType()->getExceptionTemplate());
294
            exit($exitCode);
0 ignored issues
show
Coding Style Compatibility introduced by
The method render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
295
        }
296
        
297
        if ($context !== null && $context->getDispatcher() !== null) {
298
            try {
299
                // check if an exception template was defined for the default output type
300
                if ($context->getDispatcher()->getOutputType()->getExceptionTemplate() !== null) {
301
                    include($context->getDispatcher()->getOutputType()->getExceptionTemplate());
302
                    exit($exitCode);
0 ignored issues
show
Coding Style Compatibility introduced by
The method render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
303
                }
304
            } catch (\Exception $e2) {
305
                unset($e2);
306
            }
307
        }
308
        
309
        if ($context !== null && Config::get('exception.templates.' . $context->getName()) !== null) {
310
            // a template was set for this context
311
            include(Config::get('exception.templates.' . $context->getName()));
312
            exit($exitCode);
0 ignored issues
show
Coding Style Compatibility introduced by
The method render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
313
        }
314
        
315
        // include default exception template
316
        include(Config::get('exception.default_template'));
317
        
318
        // bail out
319
        exit($exitCode);
0 ignored issues
show
Coding Style Compatibility introduced by
The method render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
320
    }
321
}
322