Issues (245)

Security Analysis    no request data  

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/AutoLoader.php (3 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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 35 and the first side effect is on line 24.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * \AppserverIo\Doppelgaenger\AutoLoader
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Bernhard Wick <[email protected]>
15
 * @copyright 2015 TechDivision GmbH - <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/doppelgaenger
18
 * @link      http://www.appserver.io/
19
 */
20
21
namespace AppserverIo\Doppelgaenger;
22
23
// Load the placeholder constants if not already done
24
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Dictionaries' . DIRECTORY_SEPARATOR . 'Placeholders.php';
25
26
/**
27
 * Will provide autoloader functionality as an entry point for parsing and code generation
28
 *
29
 * @author    Bernhard Wick <[email protected]>
30
 * @copyright 2015 TechDivision GmbH - <[email protected]>
31
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
 * @link      https://github.com/appserver-io/doppelgaenger
33
 * @link      http://www.appserver.io/
34
 */
35
class AutoLoader
36
{
37
    /**
38
     * The register for any known aspects
39
     *
40
     * @var \AppserverIo\Doppelgaenger\AspectRegister $aspectRegister
41
     */
42
    protected $aspectRegister;
43
44
    /**
45
     * @var \AppserverIo\Doppelgaenger\Config $config The configuration we base our actions on
46
     */
47
    protected $config;
48
49
    /**
50
     * @var \AppserverIo\Doppelgaenger\CacheMap $cache Cache map to keep track of already processed files
51
     */
52
    protected $cache;
53
54
    /**
55
     * @var \AppserverIo\Doppelgaenger\Generator $generator Generator instance if we need to create a new definition
56
     */
57
    protected $generator;
58
59
    /**
60
     * In some cases the autoloader instance is not thrown away, saving the structure map might be a benefit here
61
     *
62
     * @var \AppserverIo\Doppelgaenger\StructureMap $structureMap
63
     */
64
    protected $structureMap;
65
66
    /**
67
     * @const string OUR_LOADER Name of our class loading method as we will register it
68
     */
69
    const OUR_LOADER = 'loadClass';
70
71
    /**
72
     * Default constructor
73
     *
74
     * @param \AppserverIo\Doppelgaenger\Config|null $config An already existing config instance
75
     */
76
    public function __construct(Config $config = null)
77
    {
78
        // If we got a config we can use it, if not we will get a context less config instance
79
        if (is_null($config)) {
80
            $this->config = new Config();
81
0 ignored issues
show
Blank line found at end of control structure
Loading history...
82
        } else {
83
            $this->config = $config;
84
        }
85
86
        // Now that we got the config we can create a structure map to load from
87
        $this->structureMap = new StructureMap(
88
            $this->config->getValue('autoloader/dirs'),
89
            $this->config->getValue('enforcement/dirs'),
90
            $this->config
91
        );
92
93
        $this->cache = null;
94
        $this->aspectRegister = new AspectRegister();
95
    }
96
97
    /**
98
     * Getter for the $aspectRegister property
99
     *
100
     * @return \AppserverIo\Doppelgaenger\AspectRegister
101
     */
102
    public function getAspectRegister()
103
    {
104
        return $this->aspectRegister;
105
    }
106
107
    /**
108
     * Getter for the config member
109
     *
110
     * @return \AppserverIo\Doppelgaenger\Config
111
     */
112
    public function getConfig()
113
    {
114
        return $this->config;
115
    }
116
117
    /**
118
     * Getter for the structureMap member
119
     *
120
     * @return \AppserverIo\Doppelgaenger\StructureMap
121
     */
122
    public function getStructureMap()
123
    {
124
        return $this->structureMap;
125
    }
126
127
    /**
128
     * Will inject an AspectRegister instance into the generator
129
     *
130
     * @param \AppserverIo\Doppelgaenger\AspectRegister $aspectRegister The AspectRegister instance to inject
131
     *
132
     * @return null
133
     */
134
    public function injectAspectRegister(AspectRegister $aspectRegister)
135
    {
136
        $this->aspectRegister = $aspectRegister;
137
    }
138
139
    /**
140
     * Will load any given structure based on it's availability in our structure map which depends on the configured
141
     * project directories.
142
     * If the structure cannot be found we will redirect to the composer autoloader which we registered as a fallback
143
     *
144
     * @param string $className The name of the structure we will try to load
145
     *
146
     * @return boolean
147
     */
148
    public function loadClass($className)
149
    {
150
151
        // Might the class be a omitted one? If so we can require the original.
152
        if ($this->config->hasValue('autoloader/omit')) {
153
            $omittedNamespaces = $this->config->getValue('autoloader/omit');
154
155
            foreach ($omittedNamespaces as $omitted) {
156
                // If our class name begins with the omitted part e.g. it's namespace
157
                if (strpos($className, str_replace('\\\\', '\\', $omitted)) === 0) {
158
                    return false;
159
                }
160
            }
161
        }
162
163
        // Do we have the file in our cache dir? If we are in development mode we have to ignore this.
164
        if ($this->config->getValue('environment') !== 'development') {
165
            $cachePath = $this->config->getValue('cache/dir') . DIRECTORY_SEPARATOR . str_replace('\\', '_', $className) . '.php';
166
167
            if (is_readable($cachePath)) {
168
                $res = fopen($cachePath, 'r');
169
                $str = fread($res, 384);
170
171
                $success = preg_match(
172
                    '/' . Dictionaries\Placeholders::ORIGINAL_PATH_HINT . '(.+)' .
173
                    Dictionaries\Placeholders::ORIGINAL_PATH_HINT . '/',
174
                    $str,
175
                    $tmp
176
                );
177
178
                if ($success > 0) {
179
                    $tmp = explode('#', $tmp[1]);
180
181
                    $path = $tmp[0];
182
                    $mTime = $tmp[1];
183
184
                    if (filemtime($path) == $mTime) {
185
                        // the cached file is recent, load it
186
                        require $cachePath;
187
                        return true;
188
                    }
189
                }
190
            }
191
        }
192
193
        // If we are loading something that the autoloader needs to function, then we have to skip to composer
194
        if ((strpos($className, 'AppserverIo\Doppelgaenger') === 0 && strpos($className, 'AppserverIo\Doppelgaenger\Tests') === false) ||
195
            strpos($className, 'PHP') === 0 || strpos($className, 'AppserverIo\Psr\MetaobjectProtocol') === 0 ||
196
            strpos($className, 'AppserverIo\Lang\\') === 0
197
        ) {
198
            return false;
199
        }
200
201
        // If the structure map did not get filled by now we will do so here
202
        if ($this->structureMap->isEmpty()) {
203
            $this->structureMap->fill();
204
        }
205
206
        // Get the file from the map
207
        $file = $this->structureMap->getEntry($className);
208
209
        // Did we get something? If not return false.
210
        if ($file === false) {
211
            return false;
212
        }
213
214
        // We are still here, so we know the class and it is not omitted. Does it contain annotations then?
215
        if (!$file->hasAnnotations() || !$file->isEnforced()) {
216
            // on un-enforced classes we will require the original
217
            require $file->getPath();
218
219
            return true;
220
        }
221
222
        // So we have to create a new class definition for this original class.
223
        // Get a current cache instance if we do not have one already.
224
        if ($this->cache === null) {
225
            // We also require the classes of our maps as we do not have proper autoloading in place
226
            $this->cache = new CacheMap($this->getConfig()->getValue('cache/dir'), array(), $this->config);
227
        }
228
        $this->generator = new Generator($this->structureMap, $this->cache, $this->config, $this->aspectRegister);
229
230
        // Create the new class definition
231
        if ($this->generator->create($file, $this->config->getValue('enforcement/contract-inheritance')) === true) {
232
            // Require the new class, it should have been created now
233
            $file = $this->generator->getFileName($className);
234
235
            if ($file !== false && is_readable($file) === true) {
236
                require $file;
237
238
                return true;
239
            }
240
0 ignored issues
show
Blank line found at end of control structure
Loading history...
241
        } else {
242
            return false;
243
        }
244
245
        // Still here? That sounds like bad news!
246
        return false;
247
    }
248
249
    /**
250
     * Will register our autoloading method at the beginning of the spl autoloader stack
251
     *
252
     * @param boolean $throw   Should we throw an exception on error?
253
     * @param boolean $prepend If you want to NOT prepend you might, but you should not
254
     *
255
     * @return null
256
     */
257
    public function register($throw = true, $prepend = true)
258
    {
259
        // Now we have a config no matter what, we can store any instance we might need
260
        $this->config->storeInstances();
261
262
        // We want to let our autoloader be the first in line so we can react on loads
263
        // and create/return our contracted definitions.
264
        // So lets use the prepend parameter here.
265
        spl_autoload_register(array($this, self::OUR_LOADER), $throw, $prepend);
266
    }
267
268
    /**
269
     * Uninstalls this class loader from the SPL autoloader stack.
270
     *
271
     * @return void
272
     */
273
    public function unregister()
274
    {
275
        spl_autoload_unregister(array($this, self::OUR_LOADER));
276
    }
277
}
278