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 | ar_pinp::allow( 'ar_html_zen' ); |
||
4 | |||
5 | class ar_html_zen extends ar_htmlNodes { |
||
6 | |||
7 | const T_EOF = 0; |
||
8 | const T_IDENT = 1; |
||
9 | const T_NUMBER = 2; |
||
10 | const T_PLACEHOLDER = 3; |
||
11 | const T_EXPRESSION_OPEN = 4; |
||
12 | const T_EXPRESSION_CLOSE = 5; |
||
13 | |||
14 | const T_OP_ATTRIBUTES_OPEN = 6; |
||
15 | const T_OP_ATTRIBUTES_CLOSE = 7; |
||
16 | const T_OP_FILTER = 8; |
||
17 | const T_OP_MULTIPLIER = 9; |
||
18 | const T_OP_ASSIGN = 11; |
||
19 | const T_OP_ID = 12; |
||
20 | const T_OP_CLASS = 13; |
||
21 | const T_OP_CHILDREN = 14; |
||
22 | const T_OP_SIBLINGS = 15; |
||
23 | const T_OP_SETTING = 16; |
||
24 | |||
25 | public function __construct( $string ) { |
||
26 | $parser = new ar_html_zenParser($string); |
||
27 | $nodes = $parser->run(); |
||
28 | parent::__construct( (array)$this->compileNodes($nodes) ); |
||
29 | } |
||
30 | |||
31 | private function compileNodes($nodes, $childNodes = null) { |
||
32 | if( !isset($childNodes) ) { |
||
33 | $childNodes = ar_html::nodes(); |
||
34 | } |
||
35 | if( isset($nodes["children"]) ) { |
||
36 | $childNodes = $this->compileNodes($nodes["children"], $childNodes); |
||
37 | } |
||
38 | unset($nodes["children"]); |
||
39 | $result = array(); |
||
40 | $mult = 1; |
||
41 | if( isset($nodes["multiplier"]) ) { |
||
42 | $mult = (int)$nodes["multiplier"]; |
||
43 | unset($nodes["multiplier"]); |
||
44 | } |
||
45 | for($i=0;$i<$mult;$i++) { |
||
46 | foreach( $nodes as $key => $value ) { |
||
47 | if( $value["tagName"] ) { |
||
48 | $tmult = 1; |
||
49 | if( isset($value["multiplier"]) ) { |
||
50 | $tmult = (int)$value["multiplier"]; |
||
51 | } |
||
52 | for($j=0;$j<$tmult;$j++) { |
||
53 | $result[] = ar_html::tag( $value["tagName"], $value["attributes"], $childNodes->cloneNode(true)); |
||
54 | } |
||
55 | } else { |
||
56 | $result = array_merge($result, (array)$this->compileNodes($value, $childNodes)); |
||
57 | } |
||
58 | } |
||
59 | } |
||
60 | return ar_html::nodes($result); |
||
61 | } |
||
62 | } |
||
63 | |||
64 | class ar_html_zenScanner { |
||
65 | protected $YYLINE; |
||
66 | protected $YYBUFFER; |
||
67 | protected $YYCURSOR; |
||
68 | protected $YYSTATE; |
||
69 | |||
70 | protected $class_ident = array(); |
||
71 | protected $class_ident_next = array(); |
||
72 | protected $class_number = array(); |
||
73 | protected $class_whitespace = array(); |
||
74 | |||
75 | protected $tokens = array(); |
||
76 | |||
77 | public $token; |
||
78 | public $token_value; |
||
79 | public $token_ahead; |
||
80 | public $token_ahead_value; |
||
81 | |||
82 | |||
83 | function __construct($buffer) { |
||
84 | $this->YYBUFFER = $buffer."\000"; |
||
85 | $this->YYLINE = 0; |
||
86 | $this->YYCURSOR = 0; |
||
87 | $this->YYSTATE = STATE_TEXT; |
||
88 | |||
89 | |||
90 | // Identifiers [a-zA-Z] |
||
91 | $class_ident_start = array(); |
||
92 | $start = ord('a'); |
||
93 | $end = ord('z'); |
||
94 | for ($i = $start; $i <= $end; $i++) { |
||
95 | $class_ident_start[chr($i)] = chr($i); |
||
96 | $class_ident_start[strtoupper(chr($i))] = strtoupper(chr($i)); |
||
97 | } |
||
98 | $this->class_ident = array_merge(array('-' => '-', '_' => '_'), $class_ident_start); |
||
99 | $this->class_ident_start = $class_ident_start; |
||
0 ignored issues
–
show
|
|||
100 | // Numbers [0-9] |
||
101 | $class_number = array(); |
||
102 | $start = ord('0'); |
||
103 | $end = ord('9'); |
||
104 | View Code Duplication | for ($i = $start; $i <= $end; $i++) { |
|
105 | $class_ident_next[chr($i)] = chr($i); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$class_ident_next was never initialized. Although not strictly required by PHP, it is generally a good practice to add $class_ident_next = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
106 | $class_number[chr($i)] = chr($i); |
||
107 | } |
||
108 | $this->class_number = $class_number; |
||
109 | $this->class_ident = array_merge($this->class_ident, $class_ident_next); |
||
0 ignored issues
–
show
The variable
$class_ident_next does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
110 | // Whitespace |
||
111 | $class_whitespace = array(" " => " ", "\t" => "\t", "\r" => "\r", "\n" => "\n"); |
||
112 | $this->class_whitespace = $class_whitespace; |
||
113 | } |
||
114 | |||
115 | View Code Duplication | function next() { |
|
116 | if (count($this->tokens) == 0) { |
||
117 | $new_token = $this->scan($new_value); |
||
118 | } else { |
||
119 | $entry = array_shift($this->tokens); |
||
120 | list($new_token, $new_value) = each($entry); |
||
121 | } |
||
122 | if (isset($this->token_ahead)) { |
||
123 | $this->token = $this->token_ahead; |
||
124 | $this->token_value = $this->token_ahead_value; |
||
125 | } |
||
126 | $this->token_ahead = $new_token; |
||
127 | $this->token_ahead_value = $new_value; |
||
128 | return $this->token; |
||
129 | } |
||
130 | |||
131 | |||
132 | function scan(&$value) { |
||
133 | $YYCURSOR = &$this->YYCURSOR; |
||
134 | $YYBUFFER = &$this->YYBUFFER; |
||
135 | $yych = $YYBUFFER[$YYCURSOR]; |
||
136 | $token = ""; |
||
137 | |||
138 | do { |
||
139 | switch (true) { |
||
140 | case '"' === $yych: |
||
141 | View Code Duplication | case "'" === $yych: |
|
142 | $quote = $yych; |
||
143 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
144 | while ($yych !== "\000" && $yych !== $quote) { |
||
145 | if ($yych == "\\") { |
||
146 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
147 | if ($yych !== $quote && $yych != "\\") { |
||
148 | $value .= "\\"; |
||
149 | } |
||
150 | } |
||
151 | $value .= $yych; |
||
152 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
153 | } |
||
154 | ++$YYCURSOR; |
||
155 | return ar_html_zen::T_IDENT; |
||
156 | break; |
||
157 | case '|' === $yych: ($token || $token = ar_html_zen::T_OP_FILTER); |
||
158 | case '(' === $yych: ($token || $token = ar_html_zen::T_EXPRESSION_OPEN); |
||
159 | case ')' === $yych: ($token || $token = ar_html_zen::T_EXPRESSION_CLOSE); |
||
160 | case '*' === $yych: ($token || $token = ar_html_zen::T_OP_MULTIPLIER); |
||
161 | case '+' === $yych: ($token || $token = ar_html_zen::T_OP_SIBLINGS); |
||
162 | case '[' === $yych: ($token || $token = ar_html_zen::T_OP_ATTRIBUTES_OPEN); |
||
163 | case ']' === $yych: ($token || $token = ar_html_zen::T_OP_ATTRIBUTES_CLOSE); |
||
164 | case '=' === $yych: ($token || $token = ar_html_zen::T_OP_ASSIGN); |
||
165 | case '$' === $yych: ($token || $token = ar_html_zen::T_PLACEHOLDER); |
||
166 | case '>' === $yych: ($token || $token = ar_html_zen::T_OP_CHILDREN); |
||
167 | case '.' === $yych: ($token || $token = ar_html_zen::T_OP_CLASS); |
||
168 | case '#' === $yych: ($token || $token = ar_html_zen::T_OP_ID); |
||
169 | case ':' === $yych: ($token || $token = ar_html_zen::T_OP_SETTING); |
||
170 | $value = $yych; |
||
171 | ++$YYCURSOR; |
||
172 | return $token; |
||
173 | break; |
||
174 | case $this->class_whitespace[$yych] === $yych: |
||
175 | $yych = $YYBUFFER[++$YYCURSOR]; continue; |
||
176 | break; |
||
177 | View Code Duplication | case $this->class_number[$yych] === $yych: |
|
178 | $value = ""; |
||
179 | while ($this->class_number[$yych] == $yych && ($yych != "\000")) { |
||
180 | $value .= $yych; |
||
181 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
182 | } |
||
183 | return ar_html_zen::T_NUMBER; |
||
184 | break; |
||
185 | case $this->class_ident_start[$yych] === $yych: |
||
0 ignored issues
–
show
The property
class_ident_start does not seem to exist. Did you mean class_ident ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
186 | $value = $yych; |
||
187 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
188 | while ($this->class_ident[$yych] == $yych && ($yych != "\000")) { |
||
189 | $value .= $yych; |
||
190 | $yych = $YYBUFFER[++$YYCURSOR]; |
||
191 | } |
||
192 | return ar_html_zen::T_IDENT; |
||
193 | break; |
||
194 | case "\000" === $yych: |
||
195 | $value = $yych; |
||
196 | return ar_html_zen::T_EOF; |
||
197 | break; |
||
198 | default: |
||
199 | $value = $yych; |
||
200 | ++$YYCURSOR; |
||
201 | return $value; |
||
202 | break; |
||
203 | } |
||
204 | } while(1); |
||
205 | } |
||
206 | } |
||
207 | |||
208 | class ar_html_zenParser { |
||
209 | protected $scanner; |
||
210 | |||
211 | public function __construct($string) { |
||
212 | $this->scanner = new ar_html_zenScanner($string); |
||
213 | $this->scanner->next(); |
||
214 | } |
||
215 | |||
216 | public function run() { |
||
217 | $nodelist = $this->parse(); |
||
218 | return $nodelist; |
||
219 | } |
||
220 | |||
221 | private function parse() { |
||
222 | $result = array(); |
||
223 | $result[] = $this->parseExpression(); |
||
224 | $bye = false; |
||
225 | do { |
||
226 | $token = $this->scanner->token_ahead; |
||
227 | switch($token) { |
||
228 | case ar_html_zen::T_OP_CHILDREN: |
||
229 | $this->scanner->next(); |
||
230 | $result["children"] = $this->parse(); |
||
231 | break; |
||
232 | case ar_html_zen::T_OP_SIBLINGS: |
||
233 | $this->scanner->next(); |
||
234 | $result[] = $this->parseExpression(); |
||
235 | break; |
||
236 | default: |
||
237 | $bye = true; |
||
238 | break; |
||
239 | } |
||
240 | } while( !$bye ); |
||
241 | return $result; |
||
242 | } |
||
243 | |||
244 | private function parseExpression() { |
||
245 | $token = $this->scanner->token_ahead; |
||
246 | switch( $token ) { |
||
247 | View Code Duplication | case ar_html_zen::T_EXPRESSION_OPEN: |
|
248 | $this->scanner->next(); |
||
249 | $result = $this->parse(); |
||
250 | if( $this->scanner->token_ahead != ar_html_zen::T_EXPRESSION_CLOSE ) { |
||
251 | die("No closing ')' found for expression."); |
||
0 ignored issues
–
show
The method
parseExpression() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
252 | } |
||
253 | $this->scanner->next(); |
||
254 | break; |
||
255 | case ar_html_zen::T_IDENT: |
||
256 | $tagName = $this->scanner->token_ahead_value; |
||
257 | $result["tagName"] = $tagName; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
258 | $this->scanner->next(); |
||
259 | $result["attributes"] = $this->parseAttributes(); |
||
260 | break; |
||
261 | } |
||
262 | $mult = $this->parseMultiplier(); |
||
263 | if( $mult ) { |
||
264 | $result["multiplier"] = $mult; |
||
0 ignored issues
–
show
The variable
$result does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
265 | } |
||
266 | return $result; |
||
267 | } |
||
268 | |||
269 | private function parseAttributes() { |
||
270 | $bye = false; |
||
271 | $result = array(); |
||
272 | do { |
||
273 | $token = $this->scanner->token_ahead; |
||
274 | $key = false; |
||
275 | switch( $token ) { |
||
276 | case ar_html_zen::T_OP_ID: |
||
277 | $key = "id"; |
||
278 | case ar_html_zen::T_OP_CLASS: |
||
279 | if( !$key ) { $key = "class"; } |
||
0 ignored issues
–
show
The expression
$key of type string|false is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
280 | $this->scanner->next(); |
||
281 | if( $this->scanner->token_ahead == ar_html_zen::T_IDENT ) { |
||
282 | $result[$key][] = $this->scanner->token_ahead_value; |
||
283 | $this->scanner->next(); |
||
284 | } else { |
||
285 | die('no ident found for attribute: '.$key); |
||
0 ignored issues
–
show
The method
parseAttributes() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
286 | } |
||
287 | break; |
||
288 | View Code Duplication | case ar_html_zen::T_OP_ATTRIBUTES_OPEN: |
|
289 | $this->scanner->next(); |
||
290 | $result = array_merge($result, $this->parseAttributeList() ); // FIXME: deep merge |
||
291 | if( $this->scanner->token_ahead != ar_html_zen::T_OP_ATTRIBUTES_CLOSE ) { |
||
292 | die("No attribute closing tag ']' found."); |
||
0 ignored issues
–
show
The method
parseAttributes() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
293 | } |
||
294 | $this->scanner->next(); |
||
295 | break; |
||
296 | default: |
||
297 | $bye = true; |
||
298 | break; |
||
299 | } |
||
300 | } while( !$bye ); |
||
301 | return $result; |
||
302 | } |
||
303 | |||
304 | private function parseAttributeList() { |
||
305 | $bye = false; |
||
306 | $result = array(); |
||
307 | do { |
||
308 | $token = $this->scanner->token_ahead; |
||
309 | switch( $token ) { |
||
310 | case ar_html_zen::T_IDENT: |
||
311 | $attr = $this->scanner->token_ahead_value; |
||
312 | $value = ""; |
||
313 | $this->scanner->next(); |
||
314 | if( $this->scanner->token_ahead == ar_html_zen::T_OP_ASSIGN ) { |
||
315 | $this->scanner->next(); |
||
316 | if( $this->scanner->token_ahead != ar_html_zen::T_IDENT ) { |
||
317 | die('Trying to assign empty attribute '.$this->scanner->token_ahead_value ); |
||
0 ignored issues
–
show
The method
parseAttributeList() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
318 | } |
||
319 | $value = $this->scanner->token_ahead_value; |
||
320 | $this->scanner->next(); |
||
321 | } |
||
322 | $result[$attr] = $value; |
||
323 | break; |
||
324 | default: |
||
325 | $bye = true; |
||
326 | break; |
||
327 | } |
||
328 | } while( !$bye ); |
||
329 | return $result; |
||
330 | } |
||
331 | |||
332 | private function parseMultiplier() { |
||
333 | $token = $this->scanner->token_ahead; |
||
334 | if( $token == ar_html_zen::T_OP_MULTIPLIER ) { |
||
335 | $this->scanner->next(); |
||
336 | if( $this->scanner->token_ahead == ar_html_zen::T_NUMBER ) { |
||
337 | $value = $this->scanner->token_ahead_value; |
||
338 | $this->scanner->next(); |
||
339 | return $value; |
||
340 | } else { |
||
341 | die('Invalid multiplier found: '.$this->scanner->token_ahead_value); |
||
0 ignored issues
–
show
The method
parseMultiplier() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
342 | } |
||
343 | } |
||
344 | return false; |
||
345 | } |
||
346 | } |
||
347 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.