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 | namespace Spindle\Collection; |
||
3 | |||
4 | class Collection implements \IteratorAggregate |
||
5 | { |
||
6 | use Traits\SortTrait; |
||
7 | use Traits\SetsTrait; |
||
8 | use Traits\TerminateTrait; |
||
9 | use Traits\LimitTrait; |
||
10 | use Traits\TransformTrait; |
||
11 | |||
12 | const TYPE_FOR = 'for'; |
||
13 | const TYPE_FOREACH = 'foreach'; |
||
14 | |||
15 | private $type = self::TYPE_FOREACH; |
||
16 | private $debug = false; |
||
17 | |||
18 | private $ops = []; |
||
19 | private $seed; |
||
20 | private $is_array; |
||
21 | private $vars = []; |
||
22 | private $fn_cnt = 0; |
||
23 | |||
24 | /** |
||
25 | * @return \Spindle\Collection |
||
26 | */ |
||
27 | 10 | public static function from($iterable, $debug = null) |
|
28 | { |
||
29 | 10 | return new static($iterable, $debug); |
|
30 | } |
||
31 | |||
32 | /** |
||
33 | * Generator-based range() |
||
34 | * @param int|string $start |
||
35 | * @param int|string $end |
||
36 | * @param int $step |
||
37 | * @param bool $debug |
||
38 | * @return \Spindle\Collection |
||
39 | */ |
||
40 | 23 | public static function range($start, $end, $step = 1, $debug = null) |
|
41 | { |
||
42 | 23 | if (!is_int($step) || $step < 1) { |
|
43 | 1 | throw new \InvalidArgumentException('$step must be natural number: ' . $step); |
|
44 | } |
||
45 | 22 | if (is_numeric($start) && is_numeric($end)) { |
|
46 | $seed = [ |
||
47 | 22 | '$_current = ' . $start, |
|
48 | 22 | '$_current <= ' . $end, |
|
49 | 22 | $step === 1 ? '++$_current' : '$_current += ' . $step, |
|
50 | 22 | ]; |
|
51 | 22 | } else { |
|
52 | $seed = [ |
||
53 | 1 | '$_current = ' . var_export($start, 1), |
|
54 | 1 | '$_current <= ' . var_export($end, 1), |
|
55 | 1 | implode(',', array_fill(0, $step, '++$_current')), |
|
56 | 1 | ]; |
|
57 | } |
||
58 | 22 | return new static($seed, $debug, self::TYPE_FOR); |
|
0 ignored issues
–
show
|
|||
59 | } |
||
60 | |||
61 | /** |
||
62 | * Generator-based repeat() |
||
63 | * @param mixed $elem |
||
64 | * @param int $count |
||
65 | * @param bool $debug |
||
66 | */ |
||
67 | 2 | public static function repeat($elem, $count, $debug = null) |
|
68 | { |
||
69 | 2 | if (!is_int($count) || $count < 0) { |
|
70 | 1 | throw new \InvalidArgumentException('$count must be int >= 0. given: ' . gettype($count)); |
|
71 | } |
||
72 | $seed = [ |
||
73 | 1 | '$_current = $_elem, $_count = ' . var_export($count, 1), |
|
74 | 1 | '$_count > 0', |
|
75 | '--$_count' |
||
76 | 1 | ]; |
|
77 | 1 | $collection = new static($seed, $debug, self::TYPE_FOR); |
|
0 ignored issues
–
show
$seed is of type array<integer,string,{"0..."string","2":"string"}> , but the function expects a object<Spindle\Collection\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
78 | 1 | $collection->vars['_elem'] = $elem; |
|
79 | 1 | return $collection; |
|
80 | } |
||
81 | |||
82 | /** |
||
83 | * @param iterable $seed |
||
84 | */ |
||
85 | 32 | public function __construct($seed, $debug = null, $type = null) |
|
86 | { |
||
87 | 32 | if (!is_array($seed) && !is_object($seed)) { |
|
88 | 1 | throw new \InvalidArgumentException('$seed should be iterable, given ' . gettype($seed)); |
|
89 | } |
||
90 | 31 | $this->seed = $seed; |
|
91 | 31 | if ($debug) { |
|
92 | 1 | $this->debug = true; |
|
93 | 1 | } |
|
94 | 31 | if ($type === self::TYPE_FOR) { |
|
95 | 23 | $this->type = $type; |
|
96 | 23 | $this->is_array = false; |
|
97 | 23 | return; |
|
98 | } |
||
99 | 16 | $this->is_array = is_array($seed); |
|
100 | 16 | } |
|
101 | |||
102 | 17 | private function step() |
|
0 ignored issues
–
show
|
|||
103 | { |
||
104 | 17 | if ($this->debug) { |
|
105 | 1 | $this->toArray(); |
|
106 | 1 | return $this; |
|
107 | } |
||
108 | 16 | return $this; |
|
109 | } |
||
110 | |||
111 | /** |
||
112 | * @return \Generator|\ArrayIterator |
||
113 | */ |
||
114 | 1 | public function getIterator() |
|
115 | { |
||
116 | 1 | if ($this->is_array) { |
|
117 | 1 | return new \ArrayIterator($this->seed); |
|
118 | } |
||
119 | 1 | $ops = $this->ops; |
|
120 | 1 | $ops[] = 'yield $_key => $_;'; |
|
121 | 1 | $gen = self::evaluate( |
|
0 ignored issues
–
show
Are you sure the assignment to
$gen is correct as self::evaluate($this->se...() use($_seed){', '};') (which targets Spindle\Collection\Collection::evaluate() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
122 | 1 | $this->seed, |
|
123 | 1 | $this->vars, |
|
124 | 1 | $this->compile($ops), |
|
125 | 1 | '$_result = static function() use($_seed){', |
|
126 | '};' |
||
127 | 1 | ); |
|
128 | 1 | return $gen(); |
|
129 | } |
||
130 | |||
131 | /** |
||
132 | * @return array |
||
133 | */ |
||
134 | 19 | public function toArray() |
|
135 | { |
||
136 | 19 | if ($this->is_array) { |
|
137 | 10 | return $this->seed; |
|
138 | } |
||
139 | 15 | $ops = $this->ops; |
|
140 | 15 | $ops[] = ' $_result[$_key] = $_;'; |
|
141 | 15 | $array = self::evaluate( |
|
0 ignored issues
–
show
Are you sure the assignment to
$array is correct as self::evaluate($this->se..., '$_result = [];', '') (which targets Spindle\Collection\Collection::evaluate() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
142 | 15 | $this->seed, |
|
143 | 15 | $this->vars, |
|
144 | 15 | $this->compile($ops), |
|
145 | 15 | '$_result = [];', |
|
146 | '' |
||
147 | 15 | ); |
|
148 | 15 | $this->type = self::TYPE_FOREACH; |
|
149 | 15 | $this->is_array = true; |
|
150 | 15 | $this->ops = []; |
|
151 | 15 | $this->seed = $array; |
|
152 | 15 | $this->vars = []; |
|
153 | 15 | $this->fn_cnt = 0; |
|
154 | 15 | return $array; |
|
155 | } |
||
156 | |||
157 | /** |
||
158 | * @return $this |
||
159 | */ |
||
160 | 1 | public function dump() |
|
161 | { |
||
162 | 1 | var_dump($this); |
|
0 ignored issues
–
show
|
|||
163 | 1 | return $this; |
|
164 | } |
||
165 | |||
166 | /** |
||
167 | * @return $this |
||
168 | */ |
||
169 | 1 | public function assignTo(&$var = null) |
|
170 | { |
||
171 | 1 | $var = $this; |
|
172 | 1 | return $this; |
|
173 | } |
||
174 | |||
175 | /** |
||
176 | * @return $this |
||
177 | */ |
||
178 | 4 | public function assignArrayTo(&$var = null) |
|
179 | { |
||
180 | 4 | $var = $this->toArray(); |
|
181 | 4 | return $this; |
|
182 | } |
||
183 | |||
184 | /** |
||
185 | * @return string |
||
186 | */ |
||
187 | 1 | public function __toString() |
|
188 | { |
||
189 | 1 | return implode("\n", [ |
|
190 | 1 | static::class, |
|
191 | 1 | ' array-mode:' . (int)$this->is_array, |
|
192 | 1 | " codes:\n " . implode("\n ", $this->ops) |
|
193 | 1 | ]); |
|
194 | } |
||
195 | |||
196 | /** |
||
197 | * @return array |
||
198 | */ |
||
199 | 1 | public function __debugInfo() |
|
200 | { |
||
201 | 1 | if (is_array($this->seed)) { |
|
202 | 1 | $cnt = count($this->seed); |
|
203 | 1 | if ($cnt === 0) { |
|
204 | 1 | $seed = "empty array()"; |
|
205 | 1 | } else { |
|
206 | 1 | $first = gettype(current($this->seed)); |
|
207 | 1 | $seed = "array($first, ...($cnt items))"; |
|
208 | } |
||
209 | 1 | } else { |
|
210 | 1 | $seed = get_class($this->seed); |
|
211 | } |
||
212 | return [ |
||
213 | 1 | 'seed' => $seed, |
|
214 | 1 | 'code' => $this->compile($this->ops), |
|
215 | 1 | ]; |
|
216 | } |
||
217 | |||
218 | private static function evaluate($_seed, $_vars, $_code, $_before, $_after) |
||
0 ignored issues
–
show
|
|||
219 | { |
||
220 | 24 | set_error_handler(function($severity, $message, $file, $line){ |
|
221 | 1 | throw new \ErrorException($message, 0, $severity, $file, $line); |
|
222 | 24 | }, E_ALL ^ E_DEPRECATED ^ E_USER_DEPRECATED); |
|
223 | try { |
||
224 | 24 | $_result = null; |
|
225 | 24 | extract($_vars); |
|
226 | 24 | eval("$_before \n $_code \n $_after"); |
|
0 ignored issues
–
show
It is generally not recommended to use
eval unless absolutely required.
On one hand, ![]() |
|||
227 | 24 | } catch (\ParseError $e) { |
|
0 ignored issues
–
show
The class
ParseError does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
228 | throw new \RuntimeException($e->getMessage(), $e->getCode(), $e); |
||
229 | 24 | } finally { |
|
230 | 24 | restore_error_handler(); |
|
231 | } |
||
232 | 24 | return $_result; |
|
233 | } |
||
234 | |||
235 | 25 | private function compile($ops) |
|
236 | { |
||
237 | 25 | if ($this->type === self::TYPE_FOR) { |
|
238 | 20 | return $this->compileFor($ops, $this->seed); |
|
239 | } |
||
240 | |||
241 | 10 | return $this->compileForeach($ops); |
|
242 | } |
||
243 | |||
244 | 20 | private static function compileFor($ops, $seed) |
|
245 | { |
||
246 | 20 | array_unshift( |
|
247 | 20 | $ops, |
|
248 | 20 | '$_i = 0;', |
|
249 | 20 | 'for (' . implode('; ', $seed). ') {', |
|
250 | 20 | ' $_key = $_i;', |
|
251 | 20 | ' $_ = $_current;', |
|
252 | ' ++$_i;' |
||
253 | 20 | ); |
|
254 | 20 | $ops[] = '}'; |
|
255 | |||
256 | 20 | return implode("\n", $ops); |
|
257 | } |
||
258 | |||
259 | 10 | private static function compileForeach($ops) |
|
260 | { |
||
261 | 10 | array_unshift( |
|
262 | 10 | $ops, |
|
263 | 10 | '$_i = 0;', |
|
264 | 10 | 'foreach ($_seed as $_key => $_) {', |
|
265 | ' ++$_i;' |
||
266 | 10 | ); |
|
267 | 10 | $ops[] = '}'; |
|
268 | |||
269 | 10 | return implode("\n", $ops); |
|
270 | } |
||
271 | } |
||
272 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: