Skip to content

Commit 55edc1d

Browse files
committed
Support union types in curl_setopt validation
1 parent 3adc625 commit 55edc1d

File tree

3 files changed

+63
-26
lines changed

3 files changed

+63
-26
lines changed

src/Reflection/ParametersAcceptorSelector.php

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use function constant;
5151
use function count;
5252
use function defined;
53+
use function is_int;
5354
use function is_string;
5455
use function sprintf;
5556
use const ARRAY_FILTER_USE_BOTH;
@@ -126,33 +127,51 @@ public static function selectFromArgs(
126127

127128
if (count($args) >= 3 && (bool) $args[0]->getAttribute(CurlSetOptArgVisitor::ATTRIBUTE_NAME)) {
128129
$optType = $scope->getType($args[1]->value);
129-
if ($optType instanceof ConstantIntegerType) {
130-
$optValueType = self::getCurlOptValueType($optType->getValue());
131-
132-
if ($optValueType !== null) {
133-
$acceptor = $parametersAcceptors[0];
134-
$parameters = $acceptor->getParameters();
135-
136-
$parameters[2] = new NativeParameterReflection(
137-
$parameters[2]->getName(),
138-
$parameters[2]->isOptional(),
139-
$optValueType,
140-
$parameters[2]->passedByReference(),
141-
$parameters[2]->isVariadic(),
142-
$parameters[2]->getDefaultValue(),
143-
);
144-
145-
$parametersAcceptors = [
146-
new FunctionVariant(
147-
$acceptor->getTemplateTypeMap(),
148-
$acceptor->getResolvedTemplateTypeMap(),
149-
array_values($parameters),
150-
$acceptor->isVariadic(),
151-
$acceptor->getReturnType(),
152-
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
153-
),
154-
];
130+
131+
$optValueType = null;
132+
foreach ($optType->getConstantScalarValues() as $scalarValue) {
133+
if (!is_int($scalarValue)) {
134+
$optValueType = null;
135+
break;
136+
}
137+
138+
$valueType = self::getCurlOptValueType($scalarValue);
139+
if ($valueType === null) {
140+
$optValueType = null;
141+
break;
142+
}
143+
144+
if ($optValueType === null) {
145+
$optValueType = $valueType;
146+
continue;
155147
}
148+
149+
$optValueType = TypeCombinator::union($optValueType, $valueType);
150+
}
151+
152+
if ($optValueType !== null) {
153+
$acceptor = $parametersAcceptors[0];
154+
$parameters = $acceptor->getParameters();
155+
156+
$parameters[2] = new NativeParameterReflection(
157+
$parameters[2]->getName(),
158+
$parameters[2]->isOptional(),
159+
$optValueType,
160+
$parameters[2]->passedByReference(),
161+
$parameters[2]->isVariadic(),
162+
$parameters[2]->getDefaultValue(),
163+
);
164+
165+
$parametersAcceptors = [
166+
new FunctionVariant(
167+
$acceptor->getTemplateTypeMap(),
168+
$acceptor->getResolvedTemplateTypeMap(),
169+
array_values($parameters),
170+
$acceptor->isVariadic(),
171+
$acceptor->getReturnType(),
172+
$acceptor instanceof ExtendedParametersAcceptor ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
173+
),
174+
];
156175
}
157176
}
158177

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,10 @@ public function testCurlSetOpt(): void
13751375
'Parameter #3 $value of function curl_setopt expects array<int, string>, array<string, string> given.',
13761376
77,
13771377
],
1378+
[
1379+
'Parameter #3 $value of function curl_setopt expects bool|int, int|string given.',
1380+
96,
1381+
],
13781382
]);
13791383
}
13801384

tests/PHPStan/Rules/Functions/data/curl_setopt.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,18 @@ public function bug9263() {
8181
];
8282
curl_setopt($curl, CURLOPT_HTTPHEADER, $header_list);
8383
}
84+
85+
public function unionType() {
86+
$curl = curl_init();
87+
88+
if (rand(0,1)) {
89+
$var = CURLOPT_AUTOREFERER;
90+
$value = 'yes'; // invalid, should be bool
91+
} else {
92+
$var = CURLOPT_TIMEOUT;
93+
$value = 1;
94+
}
95+
96+
curl_setopt($curl, $var, $value);
97+
}
8498
}

0 commit comments

Comments
 (0)