Skip to content

Commit 3435c3b

Browse files
staabmondrejmirtes
authored andcommitted
Fix crashes in ParametersAcceptorSelector
1 parent 603b06f commit 3435c3b

File tree

4 files changed

+219
-139
lines changed

4 files changed

+219
-139
lines changed

build/PHPStan/Build/NamedArgumentsRule.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ private function processArgs(ExtendedParametersAcceptor $acceptor, Scope $scope,
116116

117117
$errorBuilders = [];
118118
$parameters = $acceptor->getParameters();
119+
if (count($parameters) !== count($normalizedArgs)) {
120+
return [];
121+
}
122+
119123
$defaultValueWasPassed = [];
120124
foreach ($normalizedArgs as $i => $normalizedArg) {
121125
if ($normalizedArg->unpack) {

src/Reflection/ParametersAcceptorSelector.php

Lines changed: 154 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -104,27 +104,30 @@ public static function selectFromArgs(
104104
$callbackParameters[] = new DummyParameter('item', $scope->getIterableValueType($argType), false, PassedByReference::createNo(), false, null);
105105
}
106106
}
107-
$parameters[0] = new NativeParameterReflection(
108-
$parameters[0]->getName(),
109-
$parameters[0]->isOptional(),
110-
new UnionType([
111-
new CallableType($callbackParameters, new MixedType(), false),
112-
new NullType(),
113-
]),
114-
$parameters[0]->passedByReference(),
115-
$parameters[0]->isVariadic(),
116-
$parameters[0]->getDefaultValue(),
117-
);
118-
$parametersAcceptors = [
119-
new FunctionVariant(
120-
$acceptor->getTemplateTypeMap(),
121-
$acceptor->getResolvedTemplateTypeMap(),
122-
$parameters,
123-
$acceptor->isVariadic(),
124-
$acceptor->getReturnType(),
125-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
126-
),
127-
];
107+
108+
if (isset($parameters[0])) {
109+
$parameters[0] = new NativeParameterReflection(
110+
$parameters[0]->getName(),
111+
$parameters[0]->isOptional(),
112+
new UnionType([
113+
new CallableType($callbackParameters, new MixedType(), false),
114+
new NullType(),
115+
]),
116+
$parameters[0]->passedByReference(),
117+
$parameters[0]->isVariadic(),
118+
$parameters[0]->getDefaultValue(),
119+
);
120+
$parametersAcceptors = [
121+
new FunctionVariant(
122+
$acceptor->getTemplateTypeMap(),
123+
$acceptor->getResolvedTemplateTypeMap(),
124+
$parameters,
125+
$acceptor->isVariadic(),
126+
$acceptor->getReturnType(),
127+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
128+
),
129+
];
130+
}
128131
}
129132

130133
if (count($args) >= 3 && (bool) $args[0]->getAttribute(CurlSetOptArgVisitor::ATTRIBUTE_NAME)) {
@@ -146,10 +149,9 @@ public static function selectFromArgs(
146149
$valueTypes[] = $valueType;
147150
}
148151

149-
if (count($valueTypes) !== 0) {
150-
$acceptor = $parametersAcceptors[0];
151-
$parameters = $acceptor->getParameters();
152-
152+
$acceptor = $parametersAcceptors[0];
153+
$parameters = $acceptor->getParameters();
154+
if (count($valueTypes) !== 0 && isset($parameters[2])) {
153155
$parameters[2] = new NativeParameterReflection(
154156
$parameters[2]->getName(),
155157
$parameters[2]->isOptional(),
@@ -163,7 +165,7 @@ public static function selectFromArgs(
163165
new FunctionVariant(
164166
$acceptor->getTemplateTypeMap(),
165167
$acceptor->getResolvedTemplateTypeMap(),
166-
array_values($parameters),
168+
$parameters,
167169
$acceptor->isVariadic(),
168170
$acceptor->getReturnType(),
169171
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
@@ -196,10 +198,9 @@ public static function selectFromArgs(
196198
);
197199
}
198200

199-
if ($hasTypes) {
200-
$acceptor = $parametersAcceptors[0];
201-
$parameters = $acceptor->getParameters();
202-
201+
$acceptor = $parametersAcceptors[0];
202+
$parameters = $acceptor->getParameters();
203+
if ($hasTypes && isset($parameters[1])) {
203204
$parameters[1] = new NativeParameterReflection(
204205
$parameters[1]->getName(),
205206
$parameters[1]->isOptional(),
@@ -213,7 +214,7 @@ public static function selectFromArgs(
213214
new FunctionVariant(
214215
$acceptor->getTemplateTypeMap(),
215216
$acceptor->getResolvedTemplateTypeMap(),
216-
array_values($parameters),
217+
$parameters,
217218
$acceptor->isVariadic(),
218219
$acceptor->getReturnType(),
219220
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
@@ -241,44 +242,49 @@ public static function selectFromArgs(
241242

242243
$acceptor = $parametersAcceptors[0];
243244
$parameters = $acceptor->getParameters();
244-
$parameters[1] = new NativeParameterReflection(
245-
$parameters[1]->getName(),
246-
$parameters[1]->isOptional(),
247-
new UnionType([
248-
new CallableType(
249-
$arrayFilterParameters ?? [
250-
new DummyParameter('item', $scope->getIterableValueType($scope->getType($args[0]->value)), false, PassedByReference::createNo(), false, null),
251-
],
252-
new BooleanType(),
253-
false,
245+
if (isset($parameters[1])) {
246+
$parameters[1] = new NativeParameterReflection(
247+
$parameters[1]->getName(),
248+
$parameters[1]->isOptional(),
249+
new UnionType([
250+
new CallableType(
251+
$arrayFilterParameters ?? [
252+
new DummyParameter('item', $scope->getIterableValueType($scope->getType($args[0]->value)), false, PassedByReference::createNo(), false, null),
253+
],
254+
new BooleanType(),
255+
false,
256+
),
257+
new NullType(),
258+
]),
259+
$parameters[1]->passedByReference(),
260+
$parameters[1]->isVariadic(),
261+
$parameters[1]->getDefaultValue(),
262+
);
263+
$parametersAcceptors = [
264+
new FunctionVariant(
265+
$acceptor->getTemplateTypeMap(),
266+
$acceptor->getResolvedTemplateTypeMap(),
267+
$parameters,
268+
$acceptor->isVariadic(),
269+
$acceptor->getReturnType(),
270+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
254271
),
255-
new NullType(),
256-
]),
257-
$parameters[1]->passedByReference(),
258-
$parameters[1]->isVariadic(),
259-
$parameters[1]->getDefaultValue(),
260-
);
261-
$parametersAcceptors = [
262-
new FunctionVariant(
263-
$acceptor->getTemplateTypeMap(),
264-
$acceptor->getResolvedTemplateTypeMap(),
265-
array_values($parameters),
266-
$acceptor->isVariadic(),
267-
$acceptor->getReturnType(),
268-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
269-
),
270-
];
272+
];
273+
}
271274
}
272275

273276
if (count($args) <= 2 && (bool) $args[0]->getAttribute(ImplodeArgVisitor::ATTRIBUTE_NAME)) {
274277
$acceptor = $namedArgumentsVariants[0] ?? $parametersAcceptors[0];
275278
$parameters = $acceptor->getParameters();
276-
if (isset($args[1]) || ($args[0]->name !== null && $args[0]->name->name === 'array')) {
279+
if (
280+
(isset($args[1]) || ($args[0]->name !== null && $args[0]->name->name === 'array'))
281+
&& isset($parameters[0]) && isset($parameters[1])
282+
) {
277283
$parameters = [
278284
new NativeParameterReflection($parameters[0]->getName(), false, new StringType(), PassedByReference::createNo(), false, null),
279285
new NativeParameterReflection($parameters[1]->getName(), false, new ArrayType(new MixedType(), new MixedType()), PassedByReference::createNo(), false, null),
280286
];
281-
} else {
287+
} elseif (isset($parameters[0])) {
282288
$parameters = [
283289
new NativeParameterReflection($parameters[0]->getName(), false, new ArrayType(new MixedType(), new MixedType()), PassedByReference::createNo(), false, null),
284290
];
@@ -307,55 +313,59 @@ public static function selectFromArgs(
307313

308314
$acceptor = $parametersAcceptors[0];
309315
$parameters = $acceptor->getParameters();
310-
$parameters[1] = new NativeParameterReflection(
311-
$parameters[1]->getName(),
312-
$parameters[1]->isOptional(),
313-
new CallableType($arrayWalkParameters, new MixedType(), false),
314-
$parameters[1]->passedByReference(),
315-
$parameters[1]->isVariadic(),
316-
$parameters[1]->getDefaultValue(),
317-
);
318-
$parametersAcceptors = [
319-
new FunctionVariant(
320-
$acceptor->getTemplateTypeMap(),
321-
$acceptor->getResolvedTemplateTypeMap(),
322-
array_values($parameters),
323-
$acceptor->isVariadic(),
324-
$acceptor->getReturnType(),
325-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
326-
),
327-
];
316+
if (isset($parameters[1])) {
317+
$parameters[1] = new NativeParameterReflection(
318+
$parameters[1]->getName(),
319+
$parameters[1]->isOptional(),
320+
new CallableType($arrayWalkParameters, new MixedType(), false),
321+
$parameters[1]->passedByReference(),
322+
$parameters[1]->isVariadic(),
323+
$parameters[1]->getDefaultValue(),
324+
);
325+
$parametersAcceptors = [
326+
new FunctionVariant(
327+
$acceptor->getTemplateTypeMap(),
328+
$acceptor->getResolvedTemplateTypeMap(),
329+
$parameters,
330+
$acceptor->isVariadic(),
331+
$acceptor->getReturnType(),
332+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
333+
),
334+
];
335+
}
328336
}
329337

330338
if ((bool) $args[0]->getAttribute(ArrayFindArgVisitor::ATTRIBUTE_NAME)) {
331339
$acceptor = $parametersAcceptors[0];
332340
$parameters = $acceptor->getParameters();
333-
$argType = $scope->getType($args[0]->value);
334-
$parameters[1] = new NativeParameterReflection(
335-
$parameters[1]->getName(),
336-
$parameters[1]->isOptional(),
337-
new CallableType(
338-
[
339-
new DummyParameter('value', $scope->getIterableValueType($argType), false, PassedByReference::createNo(), false, null),
340-
new DummyParameter('key', $scope->getIterableKeyType($argType), false, PassedByReference::createNo(), false, null),
341-
],
342-
new BooleanType(),
343-
false,
344-
),
345-
$parameters[1]->passedByReference(),
346-
$parameters[1]->isVariadic(),
347-
$parameters[1]->getDefaultValue(),
348-
);
349-
$parametersAcceptors = [
350-
new FunctionVariant(
351-
$acceptor->getTemplateTypeMap(),
352-
$acceptor->getResolvedTemplateTypeMap(),
353-
array_values($parameters),
354-
$acceptor->isVariadic(),
355-
$acceptor->getReturnType(),
356-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
357-
),
358-
];
341+
if (isset($parameters[1])) {
342+
$argType = $scope->getType($args[0]->value);
343+
$parameters[1] = new NativeParameterReflection(
344+
$parameters[1]->getName(),
345+
$parameters[1]->isOptional(),
346+
new CallableType(
347+
[
348+
new DummyParameter('value', $scope->getIterableValueType($argType), false, PassedByReference::createNo(), false, null),
349+
new DummyParameter('key', $scope->getIterableKeyType($argType), false, PassedByReference::createNo(), false, null),
350+
],
351+
new BooleanType(),
352+
false,
353+
),
354+
$parameters[1]->passedByReference(),
355+
$parameters[1]->isVariadic(),
356+
$parameters[1]->getDefaultValue(),
357+
);
358+
$parametersAcceptors = [
359+
new FunctionVariant(
360+
$acceptor->getTemplateTypeMap(),
361+
$acceptor->getResolvedTemplateTypeMap(),
362+
$parameters,
363+
$acceptor->isVariadic(),
364+
$acceptor->getReturnType(),
365+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
366+
),
367+
];
368+
}
359369
}
360370

361371
$closureBindToVar = $args[0]->getAttribute(ClosureBindToVarVisitor::ATTRIBUTE_NAME);
@@ -378,24 +388,26 @@ public static function selectFromArgs(
378388
if ($scope->hasExpressionType(new ParameterVariableOriginalValueExpr($closureBindToVar->name))->yes()) {
379389
$acceptor = $parametersAcceptors[0];
380390
$parameters = $acceptor->getParameters();
381-
$parameters[0] = new NativeParameterReflection(
382-
$parameters[0]->getName(),
383-
$parameters[0]->isOptional(),
384-
$closureThisParameters[$closureBindToVar->name],
385-
$parameters[0]->passedByReference(),
386-
$parameters[0]->isVariadic(),
387-
$parameters[0]->getDefaultValue(),
388-
);
389-
$parametersAcceptors = [
390-
new FunctionVariant(
391-
$acceptor->getTemplateTypeMap(),
392-
$acceptor->getResolvedTemplateTypeMap(),
393-
$parameters,
394-
$acceptor->isVariadic(),
395-
$acceptor->getReturnType(),
396-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
397-
),
398-
];
391+
if (isset($parameters[0])) {
392+
$parameters[0] = new NativeParameterReflection(
393+
$parameters[0]->getName(),
394+
$parameters[0]->isOptional(),
395+
$closureThisParameters[$closureBindToVar->name],
396+
$parameters[0]->passedByReference(),
397+
$parameters[0]->isVariadic(),
398+
$parameters[0]->getDefaultValue(),
399+
);
400+
$parametersAcceptors = [
401+
new FunctionVariant(
402+
$acceptor->getTemplateTypeMap(),
403+
$acceptor->getResolvedTemplateTypeMap(),
404+
$parameters,
405+
$acceptor->isVariadic(),
406+
$acceptor->getReturnType(),
407+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
408+
),
409+
];
410+
}
399411
}
400412
}
401413
}
@@ -421,24 +433,27 @@ public static function selectFromArgs(
421433
if ($scope->hasExpressionType(new ParameterVariableOriginalValueExpr($closureVarName))->yes()) {
422434
$acceptor = $parametersAcceptors[0];
423435
$parameters = $acceptor->getParameters();
424-
$parameters[1] = new NativeParameterReflection(
425-
$parameters[1]->getName(),
426-
$parameters[1]->isOptional(),
427-
$closureThisParameters[$closureVarName],
428-
$parameters[1]->passedByReference(),
429-
$parameters[1]->isVariadic(),
430-
$parameters[1]->getDefaultValue(),
431-
);
432-
$parametersAcceptors = [
433-
new FunctionVariant(
434-
$acceptor->getTemplateTypeMap(),
435-
$acceptor->getResolvedTemplateTypeMap(),
436-
array_values($parameters),
437-
$acceptor->isVariadic(),
438-
$acceptor->getReturnType(),
439-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
440-
),
441-
];
436+
437+
if (isset($parameters[1])) {
438+
$parameters[1] = new NativeParameterReflection(
439+
$parameters[1]->getName(),
440+
$parameters[1]->isOptional(),
441+
$closureThisParameters[$closureVarName],
442+
$parameters[1]->passedByReference(),
443+
$parameters[1]->isVariadic(),
444+
$parameters[1]->getDefaultValue(),
445+
);
446+
$parametersAcceptors = [
447+
new FunctionVariant(
448+
$acceptor->getTemplateTypeMap(),
449+
$acceptor->getResolvedTemplateTypeMap(),
450+
$parameters,
451+
$acceptor->isVariadic(),
452+
$acceptor->getReturnType(),
453+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
454+
),
455+
];
456+
}
442457
}
443458
}
444459
}

0 commit comments

Comments
 (0)