Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions resources/functionMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@
'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'],
'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'class_name'=>'string', 'codepage='=>'int'],
'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'],
'doubleval' => ['float', 'var'=>'int|float|__stringNotStringable|bool|array|resource|null'],
'doubleval' => ['float', 'var'=>'int|float|__stringNotStringable|bool|array|resource|GMP|SimpleXMLElement|null'],
'Ds\Deque::__construct' => ['void', 'values='=>'mixed'],
'Ds\Deque::count' => ['0|positive-int'],
'Ds\Deque::jsonSerialize' => ['array'],
Expand Down Expand Up @@ -2448,7 +2448,7 @@
'finfo_file' => ['string|false', 'finfo'=>'resource', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'],
'finfo_open' => ['resource|false', 'options='=>'int', 'arg='=>'string'],
'finfo_set_flags' => ['bool', 'finfo'=>'resource', 'options'=>'int'],
'floatval' => ['float', 'var'=>'int|float|__stringNotStringable|bool|array|resource|null'],
'floatval' => ['float', 'var'=>'int|float|__stringNotStringable|bool|array|resource|GMP|SimpleXMLElement|null'],
'flock' => ['bool', 'fp'=>'resource', 'operation'=>'int-mask<LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB>', '&w_wouldblock='=>'0|1'],
'floor' => ['__benevolent<float|false>', 'number'=>'float'],
'flush' => ['void'],
Expand Down Expand Up @@ -5075,7 +5075,7 @@
'intltz_to_date_time_zone' => ['DateTimeZone|false', 'obj'=>''],
'intltz_use_daylight_time' => ['bool', 'obj'=>''],
'intlz_create_default' => ['IntlTimeZone'],
'intval' => ['int', 'var'=>'int|float|__stringNotStringable|bool|array|resource|null', 'base='=>'int'],
'intval' => ['int', 'var'=>'int|float|__stringNotStringable|bool|array|resource|GMP|SimpleXMLElement|null', 'base='=>'int'],
'InvalidArgumentException::__clone' => ['void'],
'InvalidArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?InvalidArgumentException)'],
'InvalidArgumentException::__toString' => ['string'],
Expand Down Expand Up @@ -10438,7 +10438,7 @@
'strtoupper' => ['uppercase-string', 'str'=>'string'],
'strtr' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'],
'strtr\'1' => ['string', 'str'=>'string', 'replace_pairs'=>'array'],
'strval' => ['string', 'var'=>'__stringAndStringable|int|float|bool|resource|null'],
'strval' => ['string', 'var'=>'__stringAndStringable|int|float|bool|resource|GMP|null'],
'substr' => ['__benevolent<string|false>', 'string'=>'string', 'start'=>'int', 'length='=>'int'],
'substr_compare' => ['int<-1, 1>|false', 'main_str'=>'string', 'str'=>'string', 'offset'=>'int', 'length='=>'int', 'case_sensitivity='=>'bool'],
'substr_count' => ['0|positive-int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'int'],
Expand Down
16 changes: 13 additions & 3 deletions src/Type/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,10 @@

public function toInteger(): Type
{
if ($this->isInstanceOf('SimpleXMLElement')->yes()) {
if (
$this->isInstanceOf('SimpleXMLElement')->yes()

Check warning on line 776 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toInteger(): Type { if ( - $this->isInstanceOf('SimpleXMLElement')->yes() + !$this->isInstanceOf('SimpleXMLElement')->no() || $this->isInstanceOf('GMP')->yes() ) { return new IntegerType();

Check warning on line 776 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toInteger(): Type { if ( - $this->isInstanceOf('SimpleXMLElement')->yes() + !$this->isInstanceOf('SimpleXMLElement')->no() || $this->isInstanceOf('GMP')->yes() ) { return new IntegerType();
|| $this->isInstanceOf('GMP')->yes()

Check warning on line 777 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('SimpleXMLElement')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new IntegerType(); }

Check warning on line 777 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('SimpleXMLElement')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new IntegerType(); }
) {
return new IntegerType();
}

Expand All @@ -785,15 +788,21 @@

public function toFloat(): Type
{
if ($this->isInstanceOf('SimpleXMLElement')->yes()) {
if (
$this->isInstanceOf('SimpleXMLElement')->yes()

Check warning on line 792 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toFloat(): Type { if ( - $this->isInstanceOf('SimpleXMLElement')->yes() + !$this->isInstanceOf('SimpleXMLElement')->no() || $this->isInstanceOf('GMP')->yes() ) { return new FloatType();

Check warning on line 792 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toFloat(): Type { if ( - $this->isInstanceOf('SimpleXMLElement')->yes() + !$this->isInstanceOf('SimpleXMLElement')->no() || $this->isInstanceOf('GMP')->yes() ) { return new FloatType();
Comment thread
staabm marked this conversation as resolved.
|| $this->isInstanceOf('GMP')->yes()

Check warning on line 793 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('SimpleXMLElement')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new FloatType(); }

Check warning on line 793 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('SimpleXMLElement')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new FloatType(); }
) {
return new FloatType();
}
return new ErrorType();
}

public function toString(): Type
{
if ($this->isInstanceOf('BcMath\Number')->yes()) {
if (
$this->isInstanceOf('BcMath\Number')->yes()

Check warning on line 803 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toString(): Type { if ( - $this->isInstanceOf('BcMath\Number')->yes() + !$this->isInstanceOf('BcMath\Number')->no() || $this->isInstanceOf('GMP')->yes() ) { return new IntersectionType([

Check warning on line 803 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ public function toString(): Type { if ( - $this->isInstanceOf('BcMath\Number')->yes() + !$this->isInstanceOf('BcMath\Number')->no() || $this->isInstanceOf('GMP')->yes() ) { return new IntersectionType([
|| $this->isInstanceOf('GMP')->yes()

Check warning on line 804 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('BcMath\Number')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new IntersectionType([ new StringType(),

Check warning on line 804 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ { if ( $this->isInstanceOf('BcMath\Number')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new IntersectionType([ new StringType(),
) {
return new IntersectionType([
new StringType(),
new AccessoryNumericStringType(),
Expand Down Expand Up @@ -910,6 +919,7 @@
if (
$this->isInstanceOf('SimpleXMLElement')->yes()
|| $this->isInstanceOf('BcMath\Number')->yes()
|| $this->isInstanceOf('GMP')->yes()

Check warning on line 922 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ if ( $this->isInstanceOf('SimpleXMLElement')->yes() || $this->isInstanceOf('BcMath\Number')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new BooleanType(); }

Check warning on line 922 in src/Type/ObjectType.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Escaped Mutant for Mutator "PHPStan\Infection\TrinaryLogicMutator": @@ @@ if ( $this->isInstanceOf('SimpleXMLElement')->yes() || $this->isInstanceOf('BcMath\Number')->yes() - || $this->isInstanceOf('GMP')->yes() + || !$this->isInstanceOf('GMP')->no() ) { return new BooleanType(); }
) {
return new BooleanType();
}
Expand Down
30 changes: 30 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-14136.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Bug14136Nsrt;

use function PHPStan\Testing\assertType;

$xml = <<<'EOT'
<?xml version="1.0"?><item>3</item>
EOT;

$xml = simplexml_load_string($xml);
assertType('int', intval($xml));
assertType('int', intval(gmp_init(42)));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mutations make me think we should also test unions like

intval(rand(0,1) ? gmp_init(42) : 'abc');
intval(rand(0,1) ? gmp_init(42) : []);
intval(rand(0,1) ? gmp_init(42) : '123');

assertType('int', (int) ($xml));
assertType('int', (int) (gmp_init(42)));

assertType('float', floatval($xml));
assertType('float', floatval(gmp_init(42)));
assertType('float', (float) ($xml));
assertType('float', (float) (gmp_init(42)));

assertType('string', strval($xml));
assertType('non-empty-string&numeric-string', strval(gmp_init(42)));
assertType('string', (string) ($xml));
assertType('non-empty-string&numeric-string', (string) (gmp_init(42)));

assertType('bool', boolval($xml));
assertType('bool', boolval(gmp_init(0)));
assertType('bool', (bool) ($xml));
assertType('bool', (bool) (gmp_init(0)));
5 changes: 5 additions & 0 deletions tests/PHPStan/Rules/Cast/InvalidCastRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public function testRuleWithNullsafeVariant(): void
]);
}

public function testBug14136(): void
{
$this->analyse([__DIR__ . '/data/bug-14136.php'], []);
}

public function testCastObjectToString(): void
{
$this->analyse([__DIR__ . '/data/cast-object-to-string.php'], [
Expand Down
28 changes: 28 additions & 0 deletions tests/PHPStan/Rules/Cast/data/bug-14136.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);

namespace Bug14136Cast;

$xml = <<<'EOT'
<?xml version="1.0"?><item>3</item>
EOT;

$xml = simplexml_load_string($xml);
var_dump(intval($xml));
var_dump(intval(gmp_init(42)));
var_dump((int) ($xml));
var_dump((int)(gmp_init(42)));

var_dump(floatval ($xml));
var_dump(floatval(gmp_init(42)));
var_dump((float) ($xml));
var_dump((float)(gmp_init(42)));

var_dump(strval($xml));
var_dump(strval(gmp_init(42)));
var_dump((string) ($xml));
var_dump((string)(gmp_init(42)));

var_dump(boolval($xml));
var_dump(boolval(gmp_init(42)));
var_dump((bool) ($xml));
var_dump((bool) (gmp_init(42)));
23 changes: 14 additions & 9 deletions tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2481,39 +2481,39 @@ public function testBug6560(string $fileName): void

$this->analyse([__DIR__ . '/data/' . $fileName], [
[
sprintf('Parameter #1 %s of function strval expects bool|float|int|resource|string|null, array given.', $varName),
sprintf('Parameter #1 %s of function strval expects bool|float|GMP|int|resource|string|null, array given.', $varName),
23,
],
[
sprintf('Parameter #1 %s of function strval expects bool|float|int|resource|string|null, stdClass given.', $varName),
sprintf('Parameter #1 %s of function strval expects bool|float|GMP|int|resource|string|null, stdClass given.', $varName),
77,
],
[
sprintf('Parameter #1 %s of function intval expects array|bool|float|int|resource|string|null, stdClass given.', $varName),
sprintf('Parameter #1 %s of function intval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, stdClass given.', $varName),
80,
],
[
sprintf('Parameter #1 %s of function floatval expects array|bool|float|int|resource|string|null, stdClass given.', $varName),
sprintf('Parameter #1 %s of function floatval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, stdClass given.', $varName),
83,
],
[
sprintf('Parameter #1 %s of function intval expects array|bool|float|int|resource|string|null, %s@anonymous/tests/PHPStan/Rules/Functions/data/' . $fileName . ':13 given.', $varName, $stringableName),
sprintf('Parameter #1 %s of function intval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, %s@anonymous/tests/PHPStan/Rules/Functions/data/' . $fileName . ':13 given.', $varName, $stringableName),
89,
],
[
sprintf('Parameter #1 %s of function floatval expects array|bool|float|int|resource|string|null, %s@anonymous/tests/PHPStan/Rules/Functions/data/' . $fileName . ':13 given.', $varName, $stringableName),
sprintf('Parameter #1 %s of function floatval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, %s@anonymous/tests/PHPStan/Rules/Functions/data/' . $fileName . ':13 given.', $varName, $stringableName),
92,
],
[
sprintf('Parameter #1 %s of function strval expects bool|float|int|resource|string|null, mixed given.', $varName),
sprintf('Parameter #1 %s of function strval expects bool|float|GMP|int|resource|string|null, mixed given.', $varName),
95,
],
[
sprintf('Parameter #1 %s of function intval expects array|bool|float|int|resource|string|null, mixed given.', $varName),
sprintf('Parameter #1 %s of function intval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, mixed given.', $varName),
98,
],
[
sprintf('Parameter #1 %s of function floatval expects array|bool|float|int|resource|string|null, mixed given.', $varName),
sprintf('Parameter #1 %s of function floatval expects array|bool|float|GMP|int|resource|SimpleXMLElement|string|null, mixed given.', $varName),
101,
],
]);
Expand Down Expand Up @@ -2678,6 +2678,11 @@ public function testBug9652(): void
$this->analyse([__DIR__ . '/data/bug-9652.php'], []);
}

public function testBug14136(): void
{
$this->analyse([__DIR__ . '/data/bug-14136.php'], []);
}

#[RequiresPhp('>= 8.1')]
public function testBug8936(): void
{
Expand Down
28 changes: 28 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-14136.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);

namespace Bug14136;

$xml = <<<'EOT'
<?xml version="1.0"?><item>3</item>
EOT;

$xml = simplexml_load_string($xml);
var_dump(intval($xml));
var_dump(intval(gmp_init(42)));
var_dump((int) ($xml));
var_dump((int)(gmp_init(42)));

var_dump(floatval ($xml));
var_dump(floatval(gmp_init(42)));
var_dump((float) ($xml));
var_dump((float)(gmp_init(42)));

var_dump(strval($xml));
var_dump(strval(gmp_init(42)));
var_dump((string) ($xml));
var_dump((string)(gmp_init(42)));

var_dump(boolval($xml));
var_dump(boolval(gmp_init(42)));
var_dump((bool) ($xml));
var_dump((bool) (gmp_init(42)));
Loading