Skip to content

Commit

Permalink
Stricter treatment of types in SetCookie (#2945)
Browse files Browse the repository at this point in the history
* Stricter treatment of types in `SetCookie`

* Upgraded static analyzers
  • Loading branch information
GrahamCampbell committed Oct 18, 2021
1 parent 399c0ea commit 70d32b9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 63 deletions.
67 changes: 39 additions & 28 deletions phpstan-baseline.neon
Expand Up @@ -6,12 +6,22 @@ parameters:
path: src/Client.php

-
message: "#^Property GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:\\$handles has unknown class CurlHandle as its type\\.$#"
message: "#^Result of && is always false\\.$#"
count: 3
path: src/Cookie/SetCookie.php

-
message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#"
count: 3
path: src/Cookie/SetCookie.php

-
message: "#^Cannot access offset 'version' on array\\|false\\.$#"
count: 1
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_setopt_array expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Cannot call method getBody\\(\\) on Psr\\\\Http\\\\Message\\\\ResponseInterface\\|null\\.$#"
count: 1
path: src/Handler/CurlFactory.php

Expand All @@ -21,7 +31,12 @@ parameters:
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_setopt expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$ch of function curl_error expects resource, CurlHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_getinfo expects resource, CurlHandle\\|resource given\\.$#"
count: 4
path: src/Handler/CurlFactory.php

Expand All @@ -31,52 +46,57 @@ parameters:
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_getinfo expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$ch of function curl_setopt expects resource, CurlHandle\\|resource given\\.$#"
count: 4
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_error expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$ch of function curl_setopt_array expects resource, CurlHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlFactory.php

-
message: "#^Cannot access offset 'version' on array\\|false\\.$#"
message: "#^Parameter \\#1 \\$str1 of function strcasecmp expects string, int\\|string given\\.$#"
count: 1
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$str1 of function strcasecmp expects string, int\\|string given\\.$#"
message: "#^Property GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:\\$handles has unknown class CurlHandle as its type\\.$#"
count: 1
path: src/Handler/CurlFactory.php

-
message: "#^Parameter \\#1 \\$ch of function curl_exec expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$ch of function curl_errno expects resource, CurlHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlHandler.php

-
message: "#^Parameter \\#1 \\$ch of function curl_errno expects resource, CurlHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$ch of function curl_exec expects resource, CurlHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlHandler.php

-
message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$active has unknown class CurlMultiHandle as its type\\.$#"
message: "#^Parameter \\#1 \\$mh of function curl_multi_add_handle expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 2
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_close expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlMultiHandler.php

-
message: "#^Return typehint of method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__get\\(\\) has invalid type CurlMultiHandle\\.$#"
message: "#^Parameter \\#1 \\$mh of function curl_multi_exec expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_close expects resource, CurlMultiHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$mh of function curl_multi_info_read expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 1
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_add_handle expects resource, CurlMultiHandle\\|resource given\\.$#"
message: "#^Parameter \\#1 \\$mh of function curl_multi_remove_handle expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 2
path: src/Handler/CurlMultiHandler.php

Expand All @@ -86,17 +106,12 @@ parameters:
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_exec expects resource, CurlMultiHandle\\|resource given\\.$#"
message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$active has unknown class CurlMultiHandle as its type\\.$#"
count: 1
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_remove_handle expects resource, CurlMultiHandle\\|resource given\\.$#"
count: 2
path: src/Handler/CurlMultiHandler.php

-
message: "#^Parameter \\#1 \\$mh of function curl_multi_info_read expects resource, CurlMultiHandle\\|resource given\\.$#"
message: "#^Return typehint of method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__get\\(\\) has invalid type CurlMultiHandle\\.$#"
count: 1
path: src/Handler/CurlMultiHandler.php

Expand All @@ -105,17 +120,13 @@ parameters:
count: 1
path: src/Handler/EasyHandle.php

-
message: "#^Result of && is always false\\.$#"
count: 2
path: src/Middleware.php

-
message: "#^Result of && is always false\\.$#"
count: 1
path: src/Cookie/SetCookie.php
path: src/HandlerStack.php

-
message: "#^Result of && is always false\\.$#"
count: 1
path: src/HandlerStack.php
count: 2
path: src/Middleware.php

45 changes: 37 additions & 8 deletions psalm-baseline.xml
Expand Up @@ -13,16 +13,45 @@
<code>$result</code>
</PossiblyFalseOperand>
</file>
<file src="src/Cookie/SetCookie.php">
<RedundantCast occurrences="9">
<code>(bool) $discard</code>
<code>(bool) $httpOnly</code>
<code>(bool) $secure</code>
<code>(int) $maxAge</code>
<code>(string) $domain</code>
<code>(string) $name</code>
<code>(string) $path</code>
<code>(string) $timestamp</code>
<code>(string) $value</code>
</RedundantCast>
<TooManyArguments occurrences="9">
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int, string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
</TooManyArguments>
</file>
<file src="src/Exception/RequestException.php">
<ImplicitToStringCast occurrences="1">
<code>$uri</code>
</ImplicitToStringCast>
</file>
<file src="src/Handler/CurlFactory.php">
<FalseOperand occurrences="2">
<code>$timeoutRequiresNoSignal</code>
<FalseOperand occurrences="1">
<code>$timeoutRequiresNoSignal</code>
</FalseOperand>
<InvalidOperand occurrences="1">
<code>$options['connect_timeout'] &lt; 1</code>
</InvalidOperand>
<PossiblyFalseOperand occurrences="1">
<code>$timeoutRequiresNoSignal</code>
</PossiblyFalseOperand>
<PossiblyInvalidArgument occurrences="13">
<code>$easy-&gt;handle</code>
<code>$easy-&gt;handle</code>
Expand All @@ -41,9 +70,6 @@
<PossiblyInvalidCast occurrences="1">
<code>$sslKey</code>
</PossiblyInvalidCast>
<TypeDoesNotContainType occurrences="1">
<code>$timeoutRequiresNoSignal</code>
</TypeDoesNotContainType>
<UndefinedDocblockClass occurrences="2">
<code>private $handles = [];</code>
<code>resource[]|\CurlHandle[]</code>
Expand All @@ -68,6 +94,9 @@
<code>$this-&gt;_mh</code>
<code>$this-&gt;_mh</code>
</PossiblyInvalidArgument>
<TooManyArguments occurrences="1">
<code>trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an integer to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__)</code>
</TooManyArguments>
<UndefinedDocblockClass occurrences="2">
<code>resource|\CurlMultiHandle</code>
<code>resource|\CurlMultiHandle|null</code>
Expand All @@ -77,9 +106,6 @@
</UndefinedThisPropertyAssignment>
</file>
<file src="src/Handler/EasyHandle.php">
<RedundantCast occurrences="1">
<code>(string) $startLine[2]</code>
</RedundantCast>
<UndefinedDocblockClass occurrences="1">
<code>resource|\CurlHandle</code>
</UndefinedDocblockClass>
Expand All @@ -88,6 +114,9 @@
<ImplicitToStringCast occurrences="1">
<code>$uri</code>
</ImplicitToStringCast>
<RedundantCondition occurrences="1">
<code>empty($options)</code>
</RedundantCondition>
</file>
<file src="src/HandlerStack.php">
<PropertyTypeCoercion occurrences="4">
Expand Down
48 changes: 23 additions & 25 deletions src/Cookie/SetCookie.php
Expand Up @@ -92,7 +92,7 @@ public function __construct(array $data = [])

public function __toString()
{
$str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
$str = $this->data['Name'] . '=' . ($this->data['Value'] ?? '') . '; ';
foreach ($this->data as $k => $v) {
if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
if ($k === 'Expires') {
Expand Down Expand Up @@ -132,7 +132,7 @@ public function setName($name): void
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Name'] = $name;
$this->data['Name'] = (string) $name;
}

/**
Expand All @@ -156,7 +156,7 @@ public function setValue($value): void
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Value'] = $value;
$this->data['Value'] = (string) $value;
}

/**
Expand All @@ -172,15 +172,15 @@ public function getDomain()
/**
* Set the domain of the cookie.
*
* @param string $domain
* @param string|null $domain
*/
public function setDomain($domain): void
{
if (!is_string($domain)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
if (!is_string($domain) && null !== $domain) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Domain'] = $domain;
$this->data['Domain'] = null === $domain ? null : (string) $domain;
}

/**
Expand All @@ -204,7 +204,7 @@ public function setPath($path): void
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Path'] = $path;
$this->data['Path'] = (string) $path;
}

/**
Expand All @@ -220,15 +220,15 @@ public function getMaxAge()
/**
* Set the max-age of the cookie.
*
* @param int $maxAge Max age of the cookie in seconds
* @param int|null $maxAge Max age of the cookie in seconds
*/
public function setMaxAge($maxAge): void
{
if (!is_int($maxAge)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
if (!is_int($maxAge) && null !== $maxAge) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Max-Age'] = $maxAge;
$this->data['Max-Age'] = $maxAge === null ? null : (int) $maxAge;
}

/**
Expand All @@ -244,23 +244,21 @@ public function getExpires()
/**
* Set the unix timestamp for which the cookie will expire.
*
* @param int|string $timestamp Unix timestamp or any English textual datetime description.
* @param int|string|null $timestamp Unix timestamp or any English textual datetime description.
*/
public function setExpires($timestamp): void
{
if (!is_int($timestamp) && !is_string($timestamp)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
if (!is_int($timestamp) && !is_string($timestamp) && null !== $timestamp) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int, string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Expires'] = \is_numeric($timestamp)
? (int) $timestamp
: \strtotime($timestamp);
$this->data['Expires'] = null === $timestamp ? null : (\is_numeric($timestamp) ? (int) $timestamp : \strtotime((string) $timestamp));
}

/**
* Get whether or not this is a secure cookie.
*
* @return bool|null
* @return bool
*/
public function getSecure()
{
Expand All @@ -275,10 +273,10 @@ public function getSecure()
public function setSecure($secure): void
{
if (!is_bool($secure)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a boolean to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Secure'] = $secure;
$this->data['Secure'] = (bool) $secure;
}

/**
Expand All @@ -299,10 +297,10 @@ public function getDiscard()
public function setDiscard($discard): void
{
if (!is_bool($discard)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a boolean to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['Discard'] = $discard;
$this->data['Discard'] = (bool) $discard;
}

/**
Expand All @@ -323,10 +321,10 @@ public function getHttpOnly()
public function setHttpOnly($httpOnly): void
{
if (!is_bool($httpOnly)) {
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a boolean to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
}

$this->data['HttpOnly'] = $httpOnly;
$this->data['HttpOnly'] = (bool) $httpOnly;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion vendor-bin/phpstan/composer.json
@@ -1,7 +1,7 @@
{
"require": {
"php": "^7.2.5 || ^8.0",
"phpstan/phpstan": "0.12.81",
"phpstan/phpstan": "0.12.99",
"phpstan/phpstan-deprecation-rules": "0.12.6"
},
"config": {
Expand Down
2 changes: 1 addition & 1 deletion vendor-bin/psalm/composer.json
@@ -1,7 +1,7 @@
{
"require": {
"php": "^7.2.5 || ^8.0",
"psalm/phar": "4.6.2"
"psalm/phar": "4.10.0"
},
"config": {
"preferred-install": "dist"
Expand Down

0 comments on commit 70d32b9

Please sign in to comment.