Skip to content

Commit 1722802

Browse files
committed
Upgrade to psalm 6, test on PHP 8.4
1 parent f010a16 commit 1722802

File tree

17 files changed

+128
-95
lines changed

17 files changed

+128
-95
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
operating-system: ['ubuntu-latest']
17-
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
17+
php-version: [ '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
1818

1919
name: CI on ${{ matrix.operating-system }} with PHP ${{ matrix.php-version }}
2020

2121
steps:
2222
- name: Checkout code
23-
uses: actions/checkout@v3
23+
uses: actions/checkout@v4
2424

2525
- name: Setup PHP
2626
uses: shivammathur/setup-php@v2
@@ -35,7 +35,7 @@ jobs:
3535
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
3636
3737
- name: Cache dependencies
38-
uses: actions/cache@v3
38+
uses: actions/cache@v4
3939
with:
4040
path: ${{ steps.composer-cache.outputs.dir }}
4141
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}

.github/workflows/static-analysis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ jobs:
1414
strategy:
1515
matrix:
1616
operating-system: [ 'ubuntu-latest' ]
17-
php-version: [ '7.4', '8.2' ]
17+
php-version: [ '8.2' ]
1818

1919
steps:
2020
- name: Checkout code
21-
uses: actions/checkout@v3
21+
uses: actions/checkout@v4
2222

2323
- name: Install PHP
2424
uses: shivammathur/setup-php@v2
@@ -33,7 +33,7 @@ jobs:
3333
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
3434
3535
- name: Cache dependencies
36-
uses: actions/cache@v3
36+
uses: actions/cache@v4
3737
with:
3838
path: ${{ steps.composer-cache.outputs.dir }}
3939
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -46,7 +46,7 @@ jobs:
4646
4747
- name: Install psalm and pear/Log
4848
run: |
49-
composer require --dev "vimeo/psalm:^5.15" "pear/log:^1"
49+
composer require --dev "vimeo/psalm:^6" "pear/log:^1"
5050
5151
- name: Run a static analysis with vimeo/psalm
5252
run: |

HTTP/Request2.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
*/
4242
class HTTP_Request2 implements SplSubject
4343
{
44+
const VERSION = '2.7.0';
45+
4446
/**
4547
* #@+
4648
* Constants for HTTP request methods
@@ -233,10 +235,11 @@ public function __construct(
233235
if (!empty($method)) {
234236
$this->setMethod($method);
235237
}
236-
$this->setHeader(
237-
'user-agent', 'HTTP_Request2/2.6.0 ' .
238-
'(https://github.com/pear/HTTP_Request2) PHP/' . phpversion()
239-
);
238+
$this->setHeader('user-agent', sprintf(
239+
'HTTP_Request2/%s (https://github.com/pear/HTTP_Request2) PHP/%s',
240+
self::VERSION,
241+
phpversion() ?: '6.0'
242+
));
240243
}
241244

242245
/**
@@ -640,7 +643,7 @@ public function getBody()
640643
if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) {
641644
$body = http_build_query($this->postParams, '', '&');
642645
if (!$this->getConfig('use_brackets')) {
643-
$body = preg_replace('/%5B\d+%5D=/', '=', $body);
646+
$body = (string)preg_replace('/%5B\d+%5D=/', '=', $body);
644647
}
645648
// support RFC 3986 by not encoding '~' symbol (request #15368)
646649
return str_replace('%7E', '~', $body);

HTTP/Request2/Adapter.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ protected function calculateRequestLength(&$headers)
106106
if (is_string($this->requestBody)) {
107107
$this->contentLength = strlen($this->requestBody);
108108
} elseif (is_resource($this->requestBody)) {
109-
$stat = fstat($this->requestBody);
109+
if (false === $stat = fstat($this->requestBody)) {
110+
throw new HTTP_Request2_LogicException(
111+
"fstat() call failed", HTTP_Request2_Exception::READ_ERROR
112+
);
113+
}
110114
$this->contentLength = $stat['size'];
111115
rewind($this->requestBody);
112116
} else {

HTTP/Request2/Adapter/Curl.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,9 @@ public function getInfo()
238238
*/
239239
protected function createCurlHandle()
240240
{
241-
$ch = curl_init();
241+
if (false === $ch = curl_init()) {
242+
throw new HTTP_Request2_Exception("Failed to initialize a cURL session");
243+
}
242244

243245
curl_setopt_array(
244246
$ch, [
@@ -441,7 +443,7 @@ protected function workaroundPhpBug47204($ch, &$headers)
441443
$fp = $this->requestBody;
442444
$this->requestBody = '';
443445
while (!feof($fp)) {
444-
$this->requestBody .= fread($fp, 16384);
446+
$this->requestBody .= (string)fread($fp, 16384);
445447
}
446448
}
447449
// curl hangs up if content-length is present
@@ -473,9 +475,9 @@ protected function callbackReadBody($ch, $fd, $length)
473475
return '';
474476
}
475477
if (is_string($this->requestBody)) {
476-
$string = substr($this->requestBody, $this->position, $length);
478+
$string = (string)substr($this->requestBody, $this->position, $length);
477479
} elseif (is_resource($this->requestBody)) {
478-
$string = fread($this->requestBody, $length);
480+
$string = (string)fread($this->requestBody, $length);
479481
} else {
480482
$string = $this->requestBody->read($length);
481483
}

HTTP/Request2/Adapter/Mock.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public function addResponse($response, $url = null)
129129
*/
130130
public static function createResponseFromString($str)
131131
{
132-
$parts = preg_split('!(\r?\n){2}!m', $str, 2);
132+
$parts = preg_split('!(\r?\n){2}!m', $str, 2) ?: [''];
133133
$headerLines = explode("\n", $parts[0]);
134134
$response = new HTTP_Request2_Response(array_shift($headerLines));
135135
foreach ($headerLines as $headerLine) {
@@ -152,14 +152,14 @@ public static function createResponseFromString($str)
152152
*/
153153
public static function createResponseFromFile($fp)
154154
{
155-
$response = new HTTP_Request2_Response(fgets($fp));
155+
$response = new HTTP_Request2_Response((string)fgets($fp));
156156
do {
157-
$headerLine = fgets($fp);
157+
$headerLine = (string)fgets($fp);
158158
$response->parseHeaderLine($headerLine);
159159
} while ('' != trim($headerLine));
160160

161161
while (!feof($fp)) {
162-
$response->appendBody(fread($fp, 8192));
162+
$response->appendBody((string)fread($fp, 8192));
163163
}
164164
return $response;
165165
}

HTTP/Request2/Adapter/Socket.php

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ protected function connect()
270270
$options['ssl']['peer_name'] = $reqHost;
271271

272272
} else {
273-
$options['ssl'][substr($name, 4)] = $value;
273+
$options['ssl'][(string)substr($name, 4)] = $value;
274274
}
275275
}
276276
}
@@ -504,18 +504,18 @@ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response)
504504

505505
$url = $this->request->getUrl();
506506
$scheme = (string)$url->getScheme();
507-
$host = $scheme . '://' . $url->getHost();
507+
$host = $scheme . '://' . (string)$url->getHost();
508508
if ($port = $url->getPort()) {
509509
if ((0 === strcasecmp($scheme, 'http') && 80 != $port)
510510
|| (0 === strcasecmp($scheme, 'https') && 443 != $port)
511511
) {
512-
$host .= ':' . $port;
512+
$host .= ':' . (string)$port;
513513
}
514514
}
515515

516516
if (!empty($challenge['domain'])) {
517517
$prefixes = [];
518-
foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) {
518+
foreach (preg_split('/\\s+/', $challenge['domain']) ?: [] as $prefix) {
519519
// don't bother with different servers
520520
if ('/' == substr($prefix, 0, 1)) {
521521
$prefixes[] = $host . $prefix;
@@ -699,7 +699,7 @@ protected function createDigestResponse($user, $password, $url, &$challenge)
699699
if (false !== ($q = strpos($url, '?'))
700700
&& $this->request->getConfig('digest_compat_ie')
701701
) {
702-
$url = substr($url, 0, $q);
702+
$url = (string)substr($url, 0, $q);
703703
}
704704

705705
$a1 = md5($user . ':' . $challenge['realm'] . ':' . $password);
@@ -713,7 +713,7 @@ protected function createDigestResponse($user, $password, $url, &$challenge)
713713
if (empty($challenge['nc'])) {
714714
$challenge['nc'] = 1;
715715
}
716-
$nc = sprintf('%08x', $challenge['nc']++);
716+
$nc = (string)sprintf('%08x', $challenge['nc']++);
717717
$digest = md5(
718718
$a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' .
719719
$challenge['cnonce'] . ':auth:' . $a2
@@ -756,10 +756,9 @@ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl)
756756

757757
case HTTP_Request2::AUTH_DIGEST:
758758
unset($this->serverChallenge);
759-
$fullUrl = ('/' == $requestUrl[0])?
760-
$this->request->getUrl()->getScheme() . '://' .
761-
$requestHost . $requestUrl:
762-
$requestUrl;
759+
$fullUrl = '/' == $requestUrl[0]
760+
? (string)$this->request->getUrl()->getScheme() . '://' . $requestHost . $requestUrl
761+
: $requestUrl;
763762
foreach (array_keys(self::$challenges) as $key) {
764763
if ($key == substr($fullUrl, 0, strlen($key))) {
765764
$headers['authorization'] = $this->createDigestResponse(
@@ -841,9 +840,10 @@ protected function prepareHeaders()
841840
$connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod();
842841
$host = (string)$url->getHost();
843842

844-
$defaultPort = 0 === strcasecmp((string)$url->getScheme(), 'https')? 443: 80;
845-
if (($port = $url->getPort()) && $port != $defaultPort || $connect) {
846-
$host .= ':' . (empty($port)? $defaultPort: $port);
843+
$customPort = (string)$url->getPort();
844+
$defaultPort = 0 === strcasecmp((string)$url->getScheme(), 'https') ? '443' : '80';
845+
if ('' !== $customPort && $defaultPort !== $customPort || $connect) {
846+
$host .= ':' . ($customPort ?: $defaultPort);
847847
}
848848
// Do not overwrite explicitly set 'Host' header, see bug #16146
849849
if (!isset($headers['host'])) {
@@ -860,11 +860,11 @@ protected function prepareHeaders()
860860
) {
861861
$requestUrl = '';
862862
} else {
863-
$requestUrl = $url->getScheme() . '://' . $host;
863+
$requestUrl = (string)$url->getScheme() . '://' . $host;
864864
}
865-
$path = $url->getPath();
866-
$query = $url->getQuery();
867-
$requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query);
865+
$path = (string)$url->getPath();
866+
$query = (string)$url->getQuery();
867+
$requestUrl .= ('' === $path ? '/' : $path) . ('' === $query ? '' : '?' . $query);
868868
}
869869

870870
if ('1.1' == $this->request->getConfig('protocol_version')
@@ -990,9 +990,9 @@ protected function writeBody()
990990
$chunked = isset($headers['transfer-encoding']);
991991
while ($position < $this->contentLength) {
992992
if (is_string($this->requestBody)) {
993-
$str = substr($this->requestBody, $position, $bufferSize);
993+
$str = (string)substr($this->requestBody, $position, $bufferSize);
994994
} elseif (is_resource($this->requestBody)) {
995-
$str = fread($this->requestBody, $bufferSize);
995+
$str = (string)fread($this->requestBody, $bufferSize);
996996
} else {
997997
$str = $this->requestBody->read($bufferSize);
998998
}

HTTP/Request2/CookieJar.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null)
195195

196196
if ($setter && !$this->domainMatch((string)$setter->getHost(), $cookie['domain'])) {
197197
throw new HTTP_Request2_MessageException(
198-
"Domain " . $setter->getHost() . " cannot set cookies for "
198+
"Domain " . (string)$setter->getHost() . " cannot set cookies for "
199199
. $cookie['domain']
200200
);
201201
}
@@ -433,13 +433,13 @@ public function __serialize()
433433
/**
434434
* Constructs the object from serialized string
435435
*
436-
* @param string $serialized string representation
436+
* @param string $data string representation
437437
*
438438
* @return void
439439
*/
440-
public function unserialize($serialized)
440+
public function unserialize($data)
441441
{
442-
$this->__unserialize(unserialize($serialized));
442+
$this->__unserialize(unserialize($data));
443443
}
444444

445445
/**
@@ -524,10 +524,12 @@ public static function getRegisteredDomain($domain)
524524
if (empty(self::$psl)) {
525525
$path = '@data_dir@' . DIRECTORY_SEPARATOR . 'HTTP_Request2';
526526
if (0 === strpos($path, '@' . 'data_dir@')) {
527-
$path = realpath(
528-
__DIR__ . DIRECTORY_SEPARATOR . '..'
529-
. DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data'
530-
);
527+
if (false === $path = realpath(__DIR__ . '/../../data')) {
528+
throw new HTTP_Request2_LogicException(
529+
"Unable to locate directory containing Public Suffix List",
530+
HTTP_Request2_Exception::READ_ERROR
531+
);
532+
}
531533
}
532534
self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php';
533535
}

HTTP/Request2/MultipartBody.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,17 @@ public function read($length)
166166
$param = sprintf(
167167
$this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
168168
) . $this->_params[$this->_pos[0]][1] . "\r\n";
169-
$ret .= substr($param, $this->_pos[1], $length);
169+
$ret .= (string)substr($param, $this->_pos[1], $length);
170170
$length -= min(strlen($param) - $this->_pos[1], $length);
171171

172172
} elseif ($this->_pos[0] < $paramCount + $uploadCount) {
173173
$pos = $this->_pos[0] - $paramCount;
174-
$header = sprintf(
174+
$header = (string)sprintf(
175175
$this->_headerUpload, $boundary, $this->_uploads[$pos]['name'],
176176
$this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type']
177177
);
178178
if ($this->_pos[1] < strlen($header)) {
179-
$ret .= substr($header, $this->_pos[1], $length);
179+
$ret .= (string)substr($header, $this->_pos[1], $length);
180180
$length -= min(strlen($header) - $this->_pos[1], $length);
181181
}
182182
$filePos = max(0, $this->_pos[1] - strlen($header));
@@ -194,13 +194,13 @@ public function read($length)
194194
if ($length > 0) {
195195
$start = $this->_pos[1] + ($oldLength - $length) -
196196
strlen($header) - $this->_uploads[$pos]['size'];
197-
$ret .= substr("\r\n", $start, $length);
197+
$ret .= (string)substr("\r\n", $start, $length);
198198
$length -= min(2 - $start, $length);
199199
}
200200

201201
} else {
202202
$closing = '--' . $boundary . "--\r\n";
203-
$ret .= substr($closing, $this->_pos[1], $length);
203+
$ret .= (string)substr($closing, $this->_pos[1], $length);
204204
$length -= min(strlen($closing) - $this->_pos[1], $length);
205205
}
206206
if ($length > 0) {

HTTP/Request2/Observer/Log.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ public function __construct($target = 'php://output', array $events = [])
111111
}
112112
if (is_resource($target) || $target instanceof Log) {
113113
$this->target = $target;
114-
} elseif (false === ($this->target = @fopen($target, 'ab'))) {
115-
throw new HTTP_Request2_Exception("Unable to open '{$target}'");
114+
} else {
115+
if (false === $fp = @fopen($target, 'ab')) {
116+
throw new HTTP_Request2_Exception("Unable to open '{$target}'");
117+
}
118+
$this->target = $fp;
116119
}
117120
}
118121

0 commit comments

Comments
 (0)