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 |
||
2 | |||
3 | /** |
||
4 | * \AppserverIo\Doppelgaenger\Parser\AbstractParser |
||
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\Parser; |
||
22 | |||
23 | use AppserverIo\Doppelgaenger\Config; |
||
24 | use AppserverIo\Doppelgaenger\Interfaces\ParserInterface; |
||
25 | use AppserverIo\Doppelgaenger\StructureMap; |
||
26 | use AppserverIo\Doppelgaenger\Entities\Definitions\StructureDefinitionHierarchy; |
||
27 | use AppserverIo\Doppelgaenger\Exceptions\ParserException; |
||
28 | use AppserverIo\Doppelgaenger\Interfaces\StructureDefinitionInterface; |
||
29 | |||
30 | /** |
||
31 | * The abstract class AbstractParser which provides a basic implementation other parsers can inherit from |
||
32 | * |
||
33 | * @author Bernhard Wick <[email protected]> |
||
34 | * @copyright 2015 TechDivision GmbH - <[email protected]> |
||
35 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
||
36 | * @link https://github.com/appserver-io/doppelgaenger |
||
37 | * @link http://www.appserver.io/ |
||
38 | */ |
||
39 | abstract class AbstractParser implements ParserInterface |
||
40 | { |
||
41 | |||
42 | /** |
||
43 | * The aspect of the configuration we need |
||
44 | * |
||
45 | * @var \AppserverIo\Doppelgaenger\Config $config |
||
46 | */ |
||
47 | protected $config; |
||
48 | |||
49 | /** |
||
50 | * The path of the file we want to parse |
||
51 | * |
||
52 | * @var string $file |
||
53 | */ |
||
54 | protected $file; |
||
55 | |||
56 | /** |
||
57 | * The token array representing the whole file |
||
58 | * |
||
59 | * @var array $tokens |
||
60 | */ |
||
61 | protected $tokens = array(); |
||
62 | |||
63 | /** |
||
64 | * The count of our main token array, so we do not have to calculate it over and over again |
||
65 | * |
||
66 | * @var integer $tokenCount |
||
67 | */ |
||
68 | protected $tokenCount; |
||
69 | |||
70 | /** |
||
71 | * The current definition we are working on. |
||
72 | * This should be filled during parsing and should be passed down to whatever parser we need so we know about |
||
73 | * the current "parent" definition parts. |
||
74 | * |
||
75 | * @var \AppserverIo\Doppelgaenger\Interfaces\StructureDefinitionInterface $currentDefinition |
||
76 | */ |
||
77 | protected $currentDefinition; |
||
78 | |||
79 | /** |
||
80 | * The list of structures (within this hierarchy) which we already parsed. |
||
81 | * |
||
82 | * @var \AppserverIo\Doppelgaenger\Entities\Definitions\StructureDefinitionHierarchy $structureDefinitionHierarchy |
||
83 | */ |
||
84 | protected $structureDefinitionHierarchy; |
||
85 | |||
86 | /** |
||
87 | * Our structure map instance |
||
88 | * |
||
89 | * @var \AppserverIo\Doppelgaenger\StructureMap $structureMap |
||
90 | */ |
||
91 | protected $structureMap; |
||
92 | |||
93 | /** |
||
94 | * Default constructor |
||
95 | * |
||
96 | * @param string $file The path of the file we want to parse |
||
97 | * @param \AppserverIo\Doppelgaenger\Config $config Configuration |
||
98 | * @param StructureDefinitionHierarchy $structureDefinitionHierarchy List of already parsed structures |
||
99 | * @param \AppserverIo\Doppelgaenger\StructureMap|null $structureMap Our structure map instance |
||
100 | * @param StructureDefinitionInterface|null $currentDefinition The current definition we are working on |
||
101 | * @param array $tokens The array of tokens taken from the file |
||
102 | * |
||
103 | * @throws \AppserverIo\Doppelgaenger\Exceptions\ParserException |
||
104 | */ |
||
105 | public function __construct( |
||
106 | $file, |
||
107 | Config $config, |
||
108 | StructureDefinitionHierarchy $structureDefinitionHierarchy = null, |
||
109 | StructureMap $structureMap = null, |
||
110 | StructureDefinitionInterface $currentDefinition = null, |
||
111 | array $tokens = array() |
||
112 | ) { |
||
113 | $this->config = $config; |
||
114 | |||
115 | if (empty($tokens)) { |
||
116 | // Check if we can use the file |
||
117 | if (!is_readable($file)) { |
||
118 | throw new ParserException(sprintf('Could not read input file %s', $file)); |
||
119 | } |
||
120 | |||
121 | // Get all the tokens and count them |
||
122 | $this->tokens = token_get_all(file_get_contents($file)); |
||
123 | |||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||
124 | } else { |
||
125 | $this->tokens = $tokens; |
||
126 | } |
||
127 | |||
128 | // We need the file saved |
||
129 | $this->file = $file; |
||
130 | |||
131 | // We also need the token count |
||
132 | $this->tokenCount = count($this->tokens); |
||
133 | |||
134 | $this->currentDefinition = $currentDefinition; |
||
135 | |||
136 | $this->structureMap = is_null($structureMap) ? new StructureMap($config->getValue('autoloader/dirs'), $config->getValue('enforcement/dirs'), $config) : $structureMap; |
||
137 | $this->structureDefinitionHierarchy = is_null($structureDefinitionHierarchy) ? new StructureDefinitionHierarchy() : $structureDefinitionHierarchy; |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Does a certain block of code contain a certain keyword |
||
142 | * |
||
143 | * @param string $docBlock The code block to search in |
||
144 | * @param string $keyword The keyword to search for |
||
145 | * |
||
146 | * @return boolean |
||
147 | */ |
||
148 | protected function usesKeyword( |
||
149 | $docBlock, |
||
150 | $keyword |
||
151 | ) { |
||
152 | if (strpos($docBlock, $keyword) === false) { |
||
153 | return false; |
||
154 | } else { |
||
155 | return true; |
||
156 | } |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * Get the starting line of the structure, FALSE if unknown |
||
161 | * |
||
162 | * @param array $tokens The token array |
||
163 | * |
||
164 | * @return integer|boolean |
||
165 | */ |
||
166 | protected function getStartLine($tokens) |
||
167 | { |
||
168 | // Check the tokens |
||
169 | $targetToken = $this->getToken(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
AppserverIo\Doppelgaenger\Parser\AbstractParser as the method getToken() does only exist in the following sub-classes of AppserverIo\Doppelgaenger\Parser\AbstractParser : AppserverIo\Doppelgaenge...AbstractStructureParser , AppserverIo\Doppelgaenger\Parser\AspectParser , AppserverIo\Doppelgaenger\Parser\ClassParser , AppserverIo\Doppelgaenger\Parser\FunctionParser , AppserverIo\Doppelgaenger\Parser\InterfaceParser , AppserverIo\Doppelgaenger\Parser\TraitParser . 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.
![]() |
|||
170 | $tokenCount = count($tokens); |
||
171 | for ($i = 0; $i < $tokenCount; $i++) { |
||
172 | // If we got the target token indicating the structure start |
||
173 | if ($tokens[$i][0] === $targetToken && $tokens[$i - 1][0] !== T_PAAMAYIM_NEKUDOTAYIM) { |
||
174 | return $tokens[$i][2]; |
||
175 | } |
||
176 | } |
||
177 | |||
178 | // Return that we found nothing |
||
179 | return false; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Get the ending line of the structure, FALSE if unknown |
||
184 | * |
||
185 | * @param array $tokens The token array |
||
186 | * |
||
187 | * @return integer|boolean |
||
188 | */ |
||
189 | protected function getEndLine($tokens) |
||
190 | { |
||
191 | // Check the tokens for a line number |
||
192 | $lastIndex = (count($tokens) - 1); |
||
193 | for ($i = $lastIndex; $i >= 0; $i--) { |
||
194 | // If we got a token we know about the line number of the last token |
||
195 | if (is_array($tokens[$i])) { |
||
196 | // we found something already |
||
197 | $endLine = $tokens[$i][2]; |
||
198 | // might be a linebreak as well |
||
199 | if ($tokens[$i][0] === T_WHITESPACE) { |
||
200 | $endLine += substr_count($tokens[$i][1], "\n"); |
||
201 | } |
||
202 | return $endLine; |
||
203 | } |
||
204 | } |
||
205 | |||
206 | // Return that we found nothing |
||
207 | return false; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Will search for a certain token in a certain entity. |
||
212 | * |
||
213 | * This method will search the signature of either a class or a function for a certain token e.g. final. |
||
214 | * Will return true if the token is found, and false if not or an error occurred. |
||
215 | * |
||
216 | * @param array $tokens The token array to search in |
||
217 | * @param integer $searchedToken The token we search for, use PHP tokens here |
||
218 | * @param integer $parsedEntity The type of entity we search in front of, use PHP tokens here |
||
219 | * |
||
220 | * @return boolean |
||
221 | */ |
||
222 | protected function hasSignatureToken( |
||
223 | $tokens, |
||
224 | $searchedToken, |
||
225 | $parsedEntity |
||
226 | ) { |
||
227 | // We have to check what kind of structure we will check. Class and function are the only valid ones. |
||
228 | if ($parsedEntity !== T_FUNCTION && $parsedEntity !== T_CLASS && $parsedEntity !== T_INTERFACE) { |
||
229 | return false; |
||
230 | } |
||
231 | |||
232 | // Check the tokens |
||
233 | for ($i = 0; $i < count($tokens); $i++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
234 | // If we got the function name we have to check if we have the final keyword in front of it. |
||
235 | // I would say should be within 6 tokens in front of the function keyword. |
||
236 | if ($tokens[$i][0] === $parsedEntity) { |
||
237 | // Check if our $i is lower than 6, if so we have to avoid getting into a negative range |
||
238 | if ($i < 6) { |
||
239 | $i = 6; |
||
240 | } |
||
241 | |||
242 | for ($j = $i - 1; $j >= $i - 6; $j--) { |
||
243 | if ($tokens[$j][0] === $searchedToken) { |
||
244 | return true; |
||
245 | } |
||
246 | } |
||
247 | |||
248 | // We passed the 6 token loop but did not find something. So report it. |
||
249 | return false; |
||
250 | } |
||
251 | } |
||
252 | |||
253 | // We are still here? That should not be. |
||
254 | return false; |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Will return the DocBlock of a certain construct based on the token identifying it. |
||
259 | * Will return an empty string if none is found |
||
260 | * |
||
261 | * @param array $tokens The token array to search in |
||
262 | * @param integer $structureToken The type of entity we search in front of, use PHP tokens here e.g. T_CLASS |
||
263 | * |
||
264 | * @return string |
||
265 | */ |
||
266 | protected function getDocBlock($tokens, $structureToken) |
||
267 | { |
||
268 | // we need tokens which woudl break the construct and the DocBlock apart |
||
269 | $blockBreakers = array_flip(array(T_CLASS, T_TRAIT, T_INTERFACE, T_FUNCTION)); |
||
270 | |||
271 | // the general assumption is: |
||
272 | // We go to the first occurance of the structure token and traverse back until |
||
273 | // we find a DocBlock without passing any breaks in the flow. This should be the correct block |
||
274 | $tokenCount = count($tokens); |
||
275 | for ($i = 0; $i < $tokenCount; $i++) { |
||
276 | // if we passed the structure token |
||
277 | if ($tokens[$i][0] === $structureToken) { |
||
278 | // traverse back until we find the first DocBlock |
||
279 | for ($j = ($i - 1); $j >= 0; $j--) { |
||
280 | if ($tokens[$j][0] === T_DOC_COMMENT) { |
||
281 | return $tokens[$j][1]; |
||
282 | |||
0 ignored issues
–
show
|
|||
283 | } elseif (isset($blockBreakers[$tokens[$j][0]])) { |
||
284 | // if we pass any other construct tokens or breaks we will fail |
||
285 | break; |
||
286 | |||
0 ignored issues
–
show
|
|||
287 | } elseif ($tokens[$j][0] === T_WHITESPACE && substr_count($tokens[$j][1], "\n") > 1) { |
||
288 | // if there is a bigger linebreak in between construct and block we will fail too |
||
289 | break; |
||
290 | } |
||
291 | } |
||
292 | |||
293 | // still here? We did not find anything then |
||
294 | break; |
||
295 | } |
||
296 | } |
||
297 | |||
298 | // still here? That does not sound right |
||
299 | return ''; |
||
300 | } |
||
301 | } |
||
302 |