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 |
||
0 ignored issues
–
show
|
|||
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
|
|||
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
|
|||
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 |
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.