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 namespace MaartenStaa\Routing; |
||
2 | |||
3 | /** |
||
4 | * Copyright (c) 2015 by Maarten Staa. |
||
5 | * |
||
6 | * Some rights reserved. |
||
7 | * |
||
8 | * Redistribution and use in source and binary forms, with or without |
||
9 | * modification, are permitted provided that the following conditions are |
||
10 | * 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 |
||
16 | * copyright notice, this list of conditions and the following |
||
17 | * disclaimer in the documentation and/or other materials provided |
||
18 | * with the distribution. |
||
19 | * |
||
20 | * * The names of the contributors may not be used to endorse or |
||
21 | * promote products derived from this software without specific |
||
22 | * 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 FOR |
||
27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
28 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||
30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||
31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
35 | */ |
||
36 | |||
37 | use Closure; |
||
38 | use Illuminate\Container\Container; |
||
39 | use Illuminate\Events\Dispatcher; |
||
40 | use Illuminate\Routing\Router as LaravelRouter; |
||
41 | |||
42 | class Router extends LaravelRouter |
||
43 | { |
||
44 | /** |
||
45 | * Version of the cache key |
||
46 | * |
||
47 | * @var string |
||
48 | */ |
||
49 | protected $cacheVersion = 'v1'; |
||
50 | |||
51 | /** |
||
52 | * Create a new Router instance. |
||
53 | * |
||
54 | * @param \Illuminate\Events\Dispatcher $events |
||
55 | * @param \Illuminate\Container\Container|null $container |
||
56 | */ |
||
57 | 44 | public function __construct(Dispatcher $events, Container $container = null) |
|
58 | { |
||
59 | 44 | parent::__construct($events, $container); |
|
60 | |||
61 | 44 | $this->routes = new RouteCollection; |
|
62 | 44 | } |
|
63 | |||
64 | /** |
||
65 | * Indicate that the routes that are defined in the given callback |
||
66 | * should be cached. |
||
67 | * |
||
68 | * @param string $filename |
||
69 | * @param Closure $callback |
||
70 | * @param int $cacheMinutes |
||
71 | * @return string |
||
0 ignored issues
–
show
|
|||
72 | */ |
||
73 | 36 | public function cache($filename, Closure $callback, $cacheMinutes = 1440) |
|
74 | { |
||
75 | // If $cacheMinutes is 0 or lower, there is no need to cache anything. |
||
76 | 36 | if ($cacheMinutes <= 0) { |
|
77 | // Call closure to define routes that should be cached. |
||
78 | 4 | call_user_func($callback, $this); |
|
79 | |||
80 | // No cache key. |
||
81 | 4 | return null; |
|
82 | } |
||
83 | |||
84 | 32 | $cacher = $this->container['cache']; |
|
85 | 32 | $cacheKey = $this->getCacheKey($filename); |
|
86 | |||
87 | // Check if the current route group is cached. |
||
88 | 32 | if (($cache = $cacher->get($cacheKey)) !== null) { |
|
89 | 28 | $this->routes->restoreRouteCache($cache); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Illuminate\Routing\RouteCollection as the method restoreRouteCache() does only exist in the following sub-classes of Illuminate\Routing\RouteCollection : MaartenStaa\Routing\RouteCollection . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
90 | 28 | } else { |
|
91 | // Back up current RouteCollection contents. |
||
92 | 32 | $this->routes->saveRouteCollection(); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Illuminate\Routing\RouteCollection as the method saveRouteCollection() does only exist in the following sub-classes of Illuminate\Routing\RouteCollection : MaartenStaa\Routing\RouteCollection . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
93 | |||
94 | // Call closure to define routes that should be cached. |
||
95 | 32 | call_user_func($callback, $this); |
|
96 | |||
97 | // Put routes in cache. |
||
98 | 32 | $cache = $this->routes->getCacheableRoutes(); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Illuminate\Routing\RouteCollection as the method getCacheableRoutes() does only exist in the following sub-classes of Illuminate\Routing\RouteCollection : MaartenStaa\Routing\RouteCollection . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
99 | 32 | $cacher->put($cacheKey, $cache, $cacheMinutes); |
|
100 | |||
101 | // And restore the routes that shouldn't be cached. |
||
102 | 32 | $this->routes->restoreRouteCollection(); |
|
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Illuminate\Routing\RouteCollection as the method restoreRouteCollection() does only exist in the following sub-classes of Illuminate\Routing\RouteCollection : MaartenStaa\Routing\RouteCollection . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
103 | } |
||
104 | |||
105 | 32 | return $cacheKey; |
|
106 | } |
||
107 | |||
108 | /** |
||
109 | * Clear the cached data for the given routes file. |
||
110 | * |
||
111 | * @param string $filename |
||
112 | */ |
||
113 | 4 | public function clearCache($filename) |
|
114 | { |
||
115 | 4 | $cacher = $this->container['cache']; |
|
116 | |||
117 | 4 | $cacher->forget($this->getCacheKey($filename)); |
|
118 | 4 | } |
|
119 | |||
120 | /** |
||
121 | * Get the key under which the routes cache for the given file should be stored. |
||
122 | * |
||
123 | * @param string $filename |
||
124 | * @return string |
||
125 | */ |
||
126 | 32 | protected function getCacheKey($filename) |
|
127 | { |
||
128 | 32 | return 'routes.cache.'.$this->cacheVersion.'.'.md5($filename).filemtime($filename); |
|
129 | } |
||
130 | |||
131 | /** |
||
132 | * Determine if the action is routing to a controller. |
||
133 | * |
||
134 | * @param array $action |
||
135 | * @return bool |
||
136 | */ |
||
137 | 44 | public function routingToController($action) |
|
138 | { |
||
139 | 44 | return parent::routingToController($action); |
|
140 | } |
||
141 | |||
142 | /** |
||
143 | * Add a controller based route action to the action array. |
||
144 | * |
||
145 | * @param array|string $action |
||
146 | * @return array |
||
147 | */ |
||
148 | 36 | protected function getControllerAction($action) |
|
149 | { |
||
150 | 36 | if (is_string($action) === true) { |
|
151 | 36 | $action = array('uses' => $action); |
|
152 | 36 | } |
|
153 | |||
154 | // Here we'll get an instance of this controller dispatcher and hand it off to |
||
155 | // the Closure so it will be used to resolve the class instances out of our |
||
156 | // IoC container instance and call the appropriate methods on the class. |
||
157 | 36 | if (count($this->groupStack) > 0) { |
|
158 | 4 | $action['uses'] = $this->prependGroupUses($action['uses']); |
|
159 | 4 | } |
|
160 | |||
161 | // Here we'll get an instance of this controller dispatcher and hand it off to |
||
162 | // the Closure so it will be used to resolve the class instances out of our |
||
163 | // IoC container instance and call the appropriate methods on the class. |
||
164 | 36 | $action['controller'] = $action['uses']; |
|
165 | |||
166 | 36 | $closure = $action['uses']; |
|
167 | |||
168 | 36 | return array_set($action, 'uses', $closure); |
|
169 | } |
||
170 | |||
171 | /** |
||
172 | * Replace the string action in the given array with a Closure to call. |
||
173 | * |
||
174 | * @param array $action |
||
175 | * @return array |
||
176 | */ |
||
177 | 8 | public function makeControllerActionClosure(array $action) |
|
178 | { |
||
179 | 8 | $closure = $this->getClassClosure($action['uses']); |
|
180 | |||
181 | 8 | return array_set($action, 'uses', $closure); |
|
182 | } |
||
183 | |||
184 | /** |
||
185 | * Create a new route instance. |
||
186 | * |
||
187 | * @param array|string $methods |
||
188 | * @param string $uri |
||
189 | * @param mixed $action |
||
190 | * @return \Illuminate\Routing\Route |
||
191 | */ |
||
192 | 44 | protected function createRoute($methods, $uri, $action) |
|
193 | { |
||
194 | // If the route is routing to a controller we will parse the route action into |
||
195 | // an acceptable array format before registering it and creating this route |
||
196 | // instance itself. We need to build the Closure that will call this out. |
||
197 | 44 | if ($this->routingToController($action) === true) { |
|
198 | 36 | $action = $this->getControllerAction($action); |
|
199 | 36 | } |
|
200 | |||
201 | 44 | $route = $this->newRoute( |
|
202 | 44 | $methods, |
|
203 | 44 | $uri = $this->prefix($uri), |
|
204 | $action |
||
205 | 44 | ); |
|
206 | |||
207 | // If we have groups that need to be merged, we will merge them now after this |
||
208 | // route has already been created and is ready to go. After we're done with |
||
209 | // the merge we will be ready to return the route back out to the caller. |
||
210 | 44 | if (empty($this->groupStack) === false) { |
|
211 | 4 | $this->mergeController($route); |
|
212 | 4 | } |
|
213 | |||
214 | 44 | $this->addWhereClausesToRoute($route); |
|
215 | |||
216 | 44 | return $route; |
|
217 | } |
||
218 | |||
219 | /** |
||
220 | * Create a new Route object. |
||
221 | * |
||
222 | * @param array|string $methods |
||
223 | * @param string $uri |
||
224 | * @param mixed $action |
||
225 | * @return \Illuminate\Routing\Route |
||
226 | */ |
||
227 | 44 | protected function newRoute($methods, $uri, $action) |
|
228 | { |
||
229 | 44 | return new Route($methods, $uri, $action); |
|
0 ignored issues
–
show
It seems like
$methods defined by parameter $methods on line 227 can also be of type string ; however, Illuminate\Routing\Route::__construct() does only seem to accept array , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Add the necessary where clauses to the route based on its initial registration. |
||
234 | * |
||
235 | * @param \Illuminate\Routing\Route $route |
||
236 | * @return \Illuminate\Routing\Route |
||
237 | */ |
||
238 | 44 | protected function addWhereClausesToRoute($route) |
|
239 | { |
||
240 | 44 | $route->where( |
|
241 | 44 | array_merge($this->patterns, array_get($route->getAction(), 'where', array())) |
|
242 | 44 | ); |
|
243 | 44 | return $route; |
|
244 | } |
||
245 | } |
||
246 |
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.