Issues (4069)

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.

jssource/Minifier.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
 * JShrink
4
 *
5
 * Copyright (c) 2009-2012, Robert Hafner <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 *   * Redistributions of source code must retain the above copyright
13
 *     notice, this list of conditions and the following disclaimer.
14
 *
15
 *   * Redistributions in binary form must reproduce the above copyright
16
 *     notice, this list of conditions and the following disclaimer in
17
 *     the documentation and/or other materials provided with the
18
 *     distribution.
19
 *
20
 *   * Neither the name of Robert Hafner nor the names of his
21
 *     contributors may be used to endorse or promote products derived
22
 *     from this software without specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
 * POSSIBILITY OF SUCH DAMAGE.
36
 *
37
 * @package    JShrink
38
 * @author     Robert Hafner <[email protected]>
39
 * @copyright  2009-2012 Robert Hafner <[email protected]>
40
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link       https://github.com/tedivm/JShrink
42
 * @version    Release: 0.4
43
 */
44
45
// Some changes done by Akshay Joshi to preserve compatibility with PHP 5.2.
46
47
/**
48
 * Minifier
49
 *
50
 * Usage - Minifier::minify($js);
51
 * Usage - Minifier::minify($js, $options);
52
 * Usage - Minifier::minify($js, array('flaggedComments' => false));
53
 *
54
 * @version 0.4
55
 * @package JShrink
56
 * @author  Robert Hafner <[email protected]>
57
 * @license http://www.opensource.org/licenses/bsd-license.php  BSD License
58
 */
59
class Minifier
60
{
61
    /**
62
     * The input javascript to be minified.
63
     *
64
     * @var string
65
     */
66
    protected $input;
67
68
    /**
69
     * The location of the character (in the input string) that is next to be processed.
70
     *
71
     * @var int
72
     */
73
    protected $index = 0;
74
75
    /**
76
     * The first of the characters currently being looked at.
77
     *
78
     * @var string
79
     */
80
    protected $a = '';
81
82
83
    /**
84
     * The next character being looked at (after a);
85
     *
86
     * @var string
87
     */
88
    protected $b = '';
89
90
    /**
91
     * This character is only active when certain look ahead actions take place.
92
     *
93
     *  @var string
94
     */
95
    protected $c;
96
97
    /**
98
     * Contains the options for the current minification process.
99
     *
100
     * @var array
101
     */
102
    protected $options;
103
104
    /**
105
     * Contains the default options for minification. This array is merged with the one passed in by the user to create
106
     * the request specific set of options (stored in the $options attribute).
107
     *
108
     * @var array
109
     */
110
    static protected $defaultOptions = array('flaggedComments' => true);
111
112
    /**
113
     * Contains a copy of the JShrink object used to run minification. This is only used internally, and is only stored
114
     * for performance reasons. There is no internal data shared between minification requests.
115
     */
116
    static protected $jshrink;
117
118
    /**
119
     * Minifier::minify takes a string containing javascript and removes unneeded characters in order to shrink the code
120
     * without altering it's functionality.
121
     */
122 1
    static public function minify($js, $options = array())
0 ignored issues
show
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
123
    {
124
        try{
125 1
            ob_start();
126 1
            $currentOptions = array_merge(self::$defaultOptions, $options);
127
128 1
            if(!isset(self::$jshrink))
129 1
                self::$jshrink = new Minifier();
130
131 1
            self::$jshrink->breakdownScript($js, $currentOptions);
132 1
            return ob_get_clean();
133
134
        }catch(Exception $e){
135
            if(isset(self::$jshrink))
136
                self::$jshrink->clean();
137
138
            ob_end_clean();
139
            throw $e;
140
        }
141
    }
142
143
    /**
144
     * Processes a javascript string and outputs only the required characters, stripping out all unneeded characters.
145
     *
146
     * @param string $js The raw javascript to be minified
147
     * @param array $currentOptions Various runtime options in an associative array
148
     */
149 1
    protected function breakdownScript($js, $currentOptions)
150
    {
151
        // reset work attributes in case this isn't the first run.
152 1
        $this->clean();
153
154 1
        $this->options = $currentOptions;
155
156 1
        $js = str_replace("\r\n", "\n", $js);
157 1
        $this->input = str_replace("\r", "\n", $js);
158 1
        $this->input = preg_replace('/\h/u', ' ', $this->input);
159
160
161 1
        $this->a = $this->getReal();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getReal() can also be of type false. However, the property $a is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
162
163
        // the only time the length can be higher than 1 is if a conditional comment needs to be displayed
164
        // and the only time that can happen for $a is on the very first run
165 1
        while(strlen($this->a) > 1)
166
        {
167
            echo $this->a;
168
            $this->a = $this->getReal();
169
        }
170
171 1
        $this->b = $this->getReal();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getReal() can also be of type false. However, the property $b is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
172
173 1
        while($this->a !== false && !is_null($this->a) && $this->a !== '')
174
        {
175
176
            // now we give $b the same check for conditional comments we gave $a before we began looping
177 1
            if(strlen($this->b) > 1)
178
            {
179
                echo $this->a . $this->b;
180
                $this->a = $this->getReal();
181
                $this->b = $this->getReal();
182
                continue;
183
            }
184
185 1
            switch($this->a)
186
            {
187
                // new lines
188 1
                case "\n":
189
                    // if the next line is something that can't stand alone preserve the newline
190 1
                    if($this->b != '' && strpos('(-+{[@', $this->b) !== false)
191
                    {
192 1
                        echo $this->a;
193 1
                        $this->saveString();
194 1
                        break;
195
                    }
196
197
                    // if its a space we move down to the string test below
198 1
                    if($this->b === ' ')
199 1
                        break;
200
201
                    // otherwise we treat the newline like a space
202
203 1
                case ' ':
204 1
                    if(self::isAlphaNumeric($this->b))
205 1
                        echo $this->a;
206
207 1
                    $this->saveString();
208 1
                    break;
209
210
                default:
211 1
                    switch($this->b)
212
                    {
213 1
                        case "\n":
214 1
                            if(strpos('}])+-"\'', $this->a) !== false)
215
                            {
216 1
                                echo $this->a;
217 1
                                $this->saveString();
218 1
                                break;
219
                            }else{
220 1
                                if(self::isAlphaNumeric($this->a))
221
                                {
222 1
                                    echo $this->a;
223 1
                                    $this->saveString();
224
                                }
225
                            }
226 1
                            break;
227
228 1
                        case ' ':
0 ignored issues
show
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
229 1
                            if(!self::isAlphaNumeric($this->a))
230 1
                                break;
231
232
                        default:
233
                            // check for some regex that breaks stuff
234 1
                            if($this->a == '/' && ($this->b == '\'' || $this->b == '"'))
235
                            {
236
                                $this->saveRegex();
237
                                continue;
238
                            }
239
240 1
                            echo $this->a;
241 1
                            $this->saveString();
242 1
                            break;
243
                    }
244
            }
245
246
            // do reg check of doom
247 1
            $this->b = $this->getReal();
248
249 1
            if(($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false))
250 1
                $this->saveRegex();
251
        }
252 1
        $this->clean();
253 1
    }
254
255
    /**
256
     * Returns the next string for processing based off of the current index.
257
     *
258
     * @return string
259
     */
260 1
    protected function getChar()
261
    {
262 1
        if(isset($this->c))
263
        {
264 1
            $char = $this->c;
265 1
            unset($this->c);
266
        }else{
267 1
            $tchar = substr($this->input, $this->index, 1);
268 1
            if(isset($tchar) && $tchar !== false)
269
            {
270 1
                $char = $tchar;
271 1
                $this->index++;
272
            }else{
273 1
                return false;
274
            }
275
        }
276
277 1
        if($char !== "\n" && ord($char) < 32)
278 1
            return ' ';
279
280 1
        return $char;
281
    }
282
283
    /**
284
     * This function gets the next "real" character. It is essentially a wrapper around the getChar function that skips
285
     * comments. This has signifigant peformance benefits as the skipping is done using native functions (ie, c code)
286
     * rather than in script php.
287
     *
288
     * @return string Next 'real' character to be processed.
289
     */
290 1
    protected function getReal()
291
    {
292 1
        $startIndex = $this->index;
293 1
        $char = $this->getChar();
294
295 1
        if($char == '/')
296
        {
297 1
            $this->c = $this->getChar();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getChar() can also be of type false. However, the property $c is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
298
299 1
            if($this->c == '/')
300
            {
301 1
                $thirdCommentString = substr($this->input, $this->index, 1);
302
303
                // kill rest of line
304 1
                $char = $this->getNext("\n");
305
306 1
                if($thirdCommentString == '@')
307
                {
308
                    $endPoint = ($this->index) - $startIndex;
309
                    unset($this->c);
310
                    $char = "\n" . substr($this->input, $startIndex, $endPoint);// . "\n";
311
                }else{
312 1
                    $char = $this->getChar();
313 1
                    $char = $this->getChar();
314
                }
315
316 1
            }elseif($this->c == '*'){
317
318 1
                $this->getChar(); // current C
319 1
                $thirdCommentString = $this->getChar();
320
321 1
                if($thirdCommentString == '@')
322
                {
323
                    // conditional comment
324
325
                    // we're gonna back up a bit and and send the comment back, where the first
326
                    // char will be echoed and the rest will be treated like a string
327
                    $this->index = $this->index-2;
328
                    return '/';
329
330 1
                }elseif($this->getNext('*/')){
331
                // kill everything up to the next */
332
333 1
                    $this->getChar(); // get *
334 1
                    $this->getChar(); // get /
335
336 1
                    $char = $this->getChar(); // get next real character
337
338
                    // if YUI-style comments are enabled we reinsert it into the stream
339 1
                    if($this->options['flaggedComments'] && $thirdCommentString == '!')
340
                    {
341
                        $endPoint = ($this->index - 1) - $startIndex;
342 1
                        echo "\n" . substr($this->input, $startIndex, $endPoint) . "\n";
343
                    }
344
345
                }else{
346
                    $char = false;
347
                }
348
349 1
                if($char === false)
350
                    throw new RuntimeException('Stray comment. ' . $this->index);
351
352
                // if we're here c is part of the comment and therefore tossed
353 1
                if(isset($this->c))
354
                    unset($this->c);
355
            }
356
        }
357 1
        return $char;
358
    }
359
360
    /**
361
     * Pushes the index ahead to the next instance of the supplied string. If it is found the first character of the
362
     * string is returned.
363
     *
364
     * @return string|false Returns the first character of the string if found, false otherwise.
365
     */
366 1
    protected function getNext($string)
367
    {
368 1
        $pos = strpos($this->input, $string, $this->index);
369
370 1
        if($pos === false)
371
            return false;
372
373 1
        $this->index = $pos;
374 1
        return substr($this->input, $this->index, 1);
375
    }
376
377
    /**
378
     * When a javascript string is detected this function crawls for the end of it and saves the whole string.
379
     *
380
     */
381 1
    protected function saveString()
382
    {
383 1
        $this->a = $this->b;
384 1
        if($this->a == "'" || $this->a == '"') // is the character a quote
385
        {
386
            // save literal string
387 1
            $stringType = $this->a;
388
389 1
            while(1)
390
            {
391 1
                echo $this->a;
392 1
                $this->a = $this->getChar();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getChar() can also be of type false. However, the property $a is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
393
394 1
                switch($this->a)
395
                {
396 1
                    case $stringType:
397 1
                        break 2;
398
399 1
                    case "\n":
400
                        throw new RuntimeException('Unclosed string. ' . $this->index);
401
                        break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
402
403 1
                    case '\\':
404
                        echo $this->a;
405
                        $this->a = $this->getChar();
406
                }
407
            }
408
        }
409 1
    }
410
411
    /**
412
     * When a regular expression is detected this funcion crawls for the end of it and saves the whole regex.
413
     */
414 1
    protected function saveRegex()
415
    {
416 1
        echo $this->a . $this->b;
417
418 1
        while(($this->a = $this->getChar()) !== false)
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getChar() can also be of type false. However, the property $a is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
419
        {
420 1
            if($this->a == '/')
421 1
                break;
422
423 1
            if($this->a == '\\')
424
            {
425
                echo $this->a;
426
                $this->a = $this->getChar();
427
            }
428
429 1
            if($this->a == "\n")
430
                throw new RuntimeException('Stray regex pattern. ' . $this->index);
431
432 1
            echo $this->a;
433
        }
434 1
        $this->b = $this->getReal();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getReal() can also be of type false. However, the property $b is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
435 1
    }
436
437
    /**
438
     * Resets attributes that do not need to be stored between requests so that the next request is ready to go.
439
     */
440 1
    protected function clean()
441
    {
442 1
        unset($this->input);
443 1
        $this->index = 0;
444 1
        $this->a = $this->b = '';
445 1
        unset($this->c);
446 1
        unset($this->options);
447 1
    }
448
449
    /**
450
     * Checks to see if a character is alphanumeric.
451
     *
452
     * @return bool
453
     */
454 1
    static protected function isAlphaNumeric($char)
0 ignored issues
show
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
455
    {
456 1
        return preg_match('/^[\w\$]$/', $char) === 1 || $char == '/';
457
    }
458
459
}
460