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 | * @author Todd Burry <[email protected]> |
||
4 | * @copyright 2009-2017 Vanilla Forums Inc. |
||
5 | * @license MIT |
||
6 | */ |
||
7 | |||
8 | namespace Ebi; |
||
9 | |||
10 | |||
11 | use Symfony\Component\ExpressionLanguage\SyntaxError; |
||
12 | |||
13 | class CompilerBuffer { |
||
14 | const STYLE_JOIN = 'join'; |
||
15 | const STYLE_ARRAY = 'array'; |
||
16 | |||
17 | /** |
||
18 | * @var ComponentBuffer[] |
||
19 | */ |
||
20 | private $buffers; |
||
21 | |||
22 | /** |
||
23 | * @var ComponentBuffer |
||
24 | */ |
||
25 | private $current; |
||
26 | |||
27 | private $currentName; |
||
28 | |||
29 | private $basename; |
||
30 | |||
31 | private $style = self::STYLE_JOIN; |
||
32 | |||
33 | private $source; |
||
34 | |||
35 | private $path; |
||
36 | |||
37 | /** |
||
38 | * @var array |
||
39 | */ |
||
40 | private $defaults; |
||
41 | |||
42 | /** |
||
43 | * @var \SplObjectStorage |
||
44 | */ |
||
45 | private $nodeProps; |
||
46 | |||
47 | 78 | public function __construct($style = self::STYLE_JOIN, array $defaults = []) { |
|
48 | $defaults += [ |
||
49 | 'baseIndent' => 0 |
||
50 | 78 | ]; |
|
51 | |||
52 | 78 | $this->buffers = []; |
|
0 ignored issues
–
show
|
|||
53 | 78 | $this->nodeProps = isset($defaults['nodeProps']) ? $defaults['nodeProps'] : new \SplObjectStorage(); |
|
54 | 78 | $this->style = $style; |
|
0 ignored issues
–
show
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line. To visualize $a = "a";
$ab = "ab";
$abc = "abc";
will produce issues in the first and second line, while this second example $a = "a";
$ab = "ab";
$abc = "abc";
will produce no issues. ![]() |
|||
55 | 78 | $this->defaults = $defaults; |
|
56 | 78 | $this->select(''); |
|
57 | 78 | } |
|
58 | |||
59 | /** |
||
60 | * Select a specific component buffer. |
||
61 | * @param string $component The name of the component to select. |
||
62 | * @param bool $add Whether to add a new component if there is already a compile buffer with the same name. |
||
63 | */ |
||
64 | 78 | public function select($component, $add = false) { |
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
65 | 78 | $previous = $this->currentName; |
|
0 ignored issues
–
show
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line. To visualize $a = "a";
$ab = "ab";
$abc = "abc";
will produce issues in the first and second line, while this second example $a = "a";
$ab = "ab";
$abc = "abc";
will produce no issues. ![]() |
|||
66 | 78 | $this->currentName = $component; |
|
67 | |||
68 | 78 | if (!array_key_exists($component, $this->buffers)) { |
|
69 | 78 | $this->buffers[$component] = $buffer = new ComponentBuffer($this->defaults); |
|
70 | 78 | } elseif ($add) { |
|
71 | 1 | if (is_array($this->buffers[$component])) { |
|
72 | $this->buffers[$component][] = $buffer = new ComponentBuffer($this->defaults); |
||
73 | } else { |
||
74 | 1 | $this->buffers[$component] = [ |
|
75 | 1 | $this->buffers[$component], |
|
76 | 1 | $buffer = new ComponentBuffer($this->defaults) |
|
0 ignored issues
–
show
Equals sign not aligned with surrounding assignments; expected 16 spaces but found 1 space
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line. To visualize $a = "a";
$ab = "ab";
$abc = "abc";
will produce issues in the first and second line, while this second example $a = "a";
$ab = "ab";
$abc = "abc";
will produce no issues. ![]() |
|||
77 | 1 | ]; |
|
78 | } |
||
79 | 1 | } else { |
|
80 | 10 | $buffer = $this->buffers[$component]; |
|
81 | 10 | if (is_array($buffer)) { |
|
82 | $buffer = end($buffer); |
||
83 | if ($previous === $component) { |
||
84 | $buffer = prev($buffer); |
||
85 | } |
||
86 | } |
||
87 | } |
||
88 | |||
89 | 78 | $this->current = $buffer; |
|
90 | |||
91 | 78 | return $previous; |
|
92 | } |
||
93 | |||
94 | 71 | public function echoLiteral($value) { |
|
95 | 71 | $this->current->echoLiteral($value); |
|
96 | 71 | } |
|
97 | |||
98 | 56 | public function echoCode($php) { |
|
99 | 56 | $this->current->echoCode($php); |
|
100 | 56 | } |
|
101 | |||
102 | 78 | public function appendCode($php) { |
|
103 | 78 | $this->current->appendCode($php); |
|
104 | 78 | } |
|
105 | |||
106 | 78 | public function indent($add) { |
|
107 | 78 | $this->current->indent($add); |
|
108 | 78 | } |
|
109 | |||
110 | 26 | public function depth($add = 1) { |
|
111 | 26 | $this->current->depth($add); |
|
112 | 26 | } |
|
113 | |||
114 | 27 | public function depthName($name, $add = 0) { |
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
115 | 27 | return $this->current->depthName($name, $add); |
|
116 | } |
||
117 | |||
118 | 78 | public function pushScope(array $vars) { |
|
119 | 78 | $this->current->pushScope($vars); |
|
120 | 78 | } |
|
121 | |||
122 | 70 | public function popScope() { |
|
123 | 70 | $this->current->popScope(); |
|
124 | 70 | } |
|
125 | |||
126 | 70 | public function getScopeVariables() { |
|
127 | 70 | return $this->current->getScopeVariables(); |
|
128 | } |
||
129 | |||
130 | 70 | public function flush() { |
|
131 | 70 | switch ($this->getStyle()) { |
|
132 | 70 | case self::STYLE_ARRAY: |
|
133 | 13 | return $this->flushArray(); |
|
134 | 70 | default: |
|
135 | 70 | return $this->flushJoin(); |
|
136 | 70 | } |
|
137 | } |
||
138 | |||
139 | private function flushJoin() { |
||
140 | 70 | return implode("\n\n", array_map(function ($buffer) { |
|
141 | /* @var ComponentBuffer $buffer */ |
||
142 | 70 | return $buffer->flush(); |
|
143 | 70 | }, $this->buffers)); |
|
144 | } |
||
145 | |||
146 | 13 | private function flushArray() { |
|
147 | 13 | $result = []; |
|
148 | |||
149 | 13 | foreach ($this->buffers as $name => $buffers) { |
|
150 | 13 | $flushed = []; |
|
151 | 13 | if (is_array($buffers)) { |
|
152 | 1 | foreach ($buffers as $buffer) { |
|
153 | 1 | $flushed[] = $buffer->flush(); |
|
154 | 1 | } |
|
155 | 1 | } else { |
|
156 | 13 | $flushed = [$buffers->flush()]; |
|
157 | } |
||
158 | |||
159 | 13 | $flushed = array_filter($flushed); |
|
160 | 13 | if (empty($flushed)) { |
|
161 | 10 | continue; |
|
162 | } |
||
163 | |||
164 | 4 | if (count($flushed) === 1) { |
|
165 | 4 | $children = reset($flushed); |
|
166 | 4 | } else { |
|
167 | 1 | $children = "[\n".implode(",\n", $flushed)."\n".$this->px(+1).']'; |
|
168 | } |
||
169 | |||
170 | 4 | if ($name === '') { |
|
0 ignored issues
–
show
|
|||
171 | 4 | $result[] = $children; |
|
172 | 4 | } else { |
|
173 | 2 | $result[] = var_export($name, true).' => '.ltrim($children); |
|
174 | } |
||
175 | 13 | } |
|
176 | |||
177 | 13 | if (empty($result)) { |
|
178 | 10 | return '[]'; |
|
179 | } else { |
||
180 | 4 | return "[\n".implode(",\n\n".$this->px(+1), $result)."\n".$this->px().']'; |
|
181 | } |
||
182 | } |
||
183 | |||
184 | 4 | protected function px($add = 0) { |
|
185 | 4 | return str_repeat(' ', ($this->defaults['baseIndent'] + $add) * 4); |
|
186 | } |
||
187 | |||
188 | /** |
||
189 | * Get the style. |
||
190 | * |
||
191 | * @return string Returns the style. |
||
192 | */ |
||
193 | 70 | public function getStyle() { |
|
194 | 70 | return $this->style; |
|
195 | } |
||
196 | |||
197 | /** |
||
198 | * Set the style. |
||
199 | * |
||
200 | * @param string $style One of the **STYLE_*** constants. |
||
201 | * @return $this |
||
202 | */ |
||
203 | public function setStyle($style) { |
||
204 | $this->style = $style; |
||
205 | return $this; |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Get the basename. |
||
210 | * |
||
211 | * @return string Returns the basename. |
||
212 | */ |
||
213 | public function getBasename() { |
||
214 | return $this->basename; |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * Set the basename. |
||
219 | * |
||
220 | * @param string $basename |
||
221 | * @return $this |
||
222 | */ |
||
223 | 78 | public function setBasename($basename) { |
|
224 | 78 | $this->basename = $basename; |
|
225 | 78 | return $this; |
|
226 | } |
||
227 | |||
228 | 78 | public function getNodeProp(\DOMNode $node, $name, $default = null) { |
|
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
229 | 78 | if (!$this->nodeProps->contains($node) || !array_key_exists($name, $this->nodeProps[$node])) { |
|
230 | 78 | return $default; |
|
231 | } |
||
232 | 12 | return $this->nodeProps[$node][$name]; |
|
233 | } |
||
234 | |||
235 | 40 | public function setNodeProp(\DOMNode $node = null, $name, $value) { |
|
236 | 40 | if ($node === null) { |
|
237 | 21 | return $this; |
|
238 | } |
||
239 | |||
240 | 23 | if (!$this->nodeProps->contains($node)) { |
|
241 | 23 | $this->nodeProps->attach($node, [$name => $value]); |
|
242 | 23 | } |
|
243 | |||
244 | 23 | $this->nodeProps[$node] = [$name => $value] + $this->nodeProps[$node]; |
|
245 | 23 | return $this; |
|
246 | } |
||
247 | |||
248 | 14 | public function getIndent() { |
|
249 | 14 | return $this->current->getIndent(); |
|
250 | } |
||
251 | |||
252 | 14 | public function getDepth() { |
|
253 | 14 | return $this->current->getDepth(); |
|
254 | } |
||
255 | |||
256 | public function getScope() { |
||
257 | return $this->current->getScope(); |
||
258 | } |
||
259 | |||
260 | 14 | public function getAllScopes() { |
|
261 | 14 | return $this->current->getAllScopes(); |
|
262 | } |
||
263 | |||
264 | /** |
||
265 | * Create a new **CompileException** with proper context. |
||
266 | * |
||
267 | * @param \DOMNode $node The node that has the error. |
||
268 | * @param \Exception $ex The exception that represents the low-level error. |
||
269 | * @param array $context Custom context information for the exception. |
||
270 | * @return CompileException Returns a new exception that can be thrown. |
||
271 | */ |
||
272 | 8 | public function createCompilerException(\DOMNode $node, \Exception $ex, array $context = []) { |
|
273 | $result = $context + [ |
||
274 | 8 | 'path' => $this->getPath(), |
|
275 | 8 | 'source' => '', |
|
276 | 8 | 'sourcePosition' => null, |
|
277 | 8 | 'line' => $node->getLineNo(), |
|
278 | 8 | 'lines' => [] |
|
279 | 8 | ]; |
|
280 | 8 | $message = $ex->getMessage(); |
|
281 | |||
282 | 8 | if ($ex instanceof SyntaxError) { |
|
283 | 3 | list($error, $position) = $this->splitSyntaxError($ex); |
|
0 ignored issues
–
show
The assignment to
$error is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
|||
284 | 3 | $result['source'] = $result['source'] ?: ($node instanceof \DOMAttr ? $node->value : $node->nodeValue); |
|
0 ignored issues
–
show
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line. To visualize $a = "a";
$ab = "ab";
$abc = "abc";
will produce issues in the first and second line, while this second example $a = "a";
$ab = "ab";
$abc = "abc";
will produce no issues. ![]() |
|||
285 | 3 | if (!isset($context['sourcePosition'])) { |
|
286 | 3 | $result['sourcePosition'] = $position; |
|
287 | 3 | } |
|
288 | 8 | } elseif (empty($result['source'])) { |
|
289 | 5 | if ($node instanceof \DOMAttr) { |
|
290 | 3 | $result['source'] = $node->name.'="'.$node->value.'"'; |
|
291 | 3 | } |
|
292 | 5 | } |
|
293 | |||
294 | 8 | if (!empty($this->source)) { |
|
295 | 8 | $allLines = explode("\n", $this->source); |
|
296 | |||
297 | 8 | $lines = []; |
|
298 | 8 | $line = $result['line']; |
|
299 | 8 | for ($i = max(0, $line - 4); $i < $line + 3; $i++) { |
|
300 | 8 | if (isset($allLines[$i])) { |
|
301 | 8 | $lines[$i + 1] = $allLines[$i]; |
|
302 | 8 | } |
|
303 | 8 | } |
|
304 | |||
305 | 8 | $result['lines'] = $lines; |
|
306 | 8 | } |
|
307 | |||
308 | 8 | return new CompileException($message, $result, $ex); |
|
309 | } |
||
310 | |||
311 | 3 | private function splitSyntaxError(SyntaxError $ex) { |
|
312 | 3 | if (preg_match('`^(.*) around position (.*)\.$`', $ex->getMessage(), $m)) { |
|
313 | 3 | return [$m[1], $m[2]]; |
|
314 | } else { |
||
315 | return [$ex->getMessage(), 0]; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Get the source. |
||
321 | * |
||
322 | * @return mixed Returns the source. |
||
323 | */ |
||
324 | 14 | public function getSource() { |
|
325 | 14 | return $this->source; |
|
326 | } |
||
327 | |||
328 | /** |
||
329 | * Set the source. |
||
330 | * |
||
331 | * @param mixed $source |
||
332 | * @return $this |
||
333 | */ |
||
334 | 78 | public function setSource($source) { |
|
335 | 78 | $this->source = $source; |
|
336 | 78 | return $this; |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * Get the path. |
||
341 | * |
||
342 | * @return mixed Returns the path. |
||
343 | */ |
||
344 | 8 | public function getPath() { |
|
345 | 8 | return $this->path; |
|
346 | } |
||
347 | |||
348 | /** |
||
349 | * Set the path. |
||
350 | * |
||
351 | * @param mixed $path |
||
352 | * @return $this |
||
353 | */ |
||
354 | 78 | public function setPath($path) { |
|
355 | 78 | $this->path = $path; |
|
356 | 78 | return $this; |
|
357 | } |
||
358 | |||
359 | /** |
||
360 | * Get the entire node property array. |
||
361 | * |
||
362 | * @return \SplObjectStorage Returns the node properties. |
||
363 | */ |
||
364 | 14 | public function getNodePropArray() { |
|
365 | 14 | return $this->nodeProps; |
|
366 | } |
||
367 | } |
||
368 |
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.
To visualize
will produce issues in the first and second line, while this second example
will produce no issues.