From ebad36fb2629b39303fc1b6c3d5627028cc5dc78 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 5 Sep 2024 15:46:59 +0545 Subject: [PATCH 1/3] Add PHP 8.4 compliance for v4 --- .github/workflows/ci.yml | 10 ++++++++-- .php-cs-fixer.dist.php | 4 ++++ composer.json | 6 +++--- lib/ContextStackTrait.php | 2 +- lib/Writer.php | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 690ec0e..df2cce0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,10 +14,16 @@ jobs: matrix: php-versions: ['8.0', '8.1', '8.2', '8.3'] coverage: ['pcov'] + code-style: ['no'] code-analysis: ['no'] include: - php-versions: '7.4' coverage: 'none' + code-style: 'yes' + code-analysis: 'yes' + - php-versions: '8.4' + coverage: 'pcov' + code-style: 'no' code-analysis: 'yes' steps: - name: Checkout @@ -48,8 +54,8 @@ jobs: run: composer install --no-progress --prefer-dist --optimize-autoloader - name: Code Analysis (PHP CS-Fixer) - if: matrix.code-analysis == 'yes' - run: php vendor/bin/php-cs-fixer fix --dry-run --diff + if: matrix.code-style == 'yes' + run: PHP_CS_FIXER_IGNORE_ENV=true php vendor/bin/php-cs-fixer fix --dry-run --diff - name: Code Analysis (PHPStan) if: matrix.code-analysis == 'yes' diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 8fbc3c6..9f41283 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -11,6 +11,10 @@ $config->setRules([ '@PSR1' => true, '@Symfony' => true, + 'nullable_type_declaration' => [ + 'syntax' => 'question_mark', + ], + 'nullable_type_declaration_for_default_null_value' => true, ]); $config->setFinder($finder); diff --git a/composer.json b/composer.json index b744452..faf06b3 100644 --- a/composer.json +++ b/composer.json @@ -44,8 +44,8 @@ } }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.56", - "phpstan/phpstan": "^1.11", + "friendsofphp/php-cs-fixer": "^3.64", + "phpstan/phpstan": "^1.12", "phpunit/phpunit" : "^9.6" }, "scripts": { @@ -56,7 +56,7 @@ "phpstan analyse --generate-baseline phpstan-baseline.neon" ], "cs-fixer": [ - "php-cs-fixer fix" + "PHP_CS_FIXER_IGNORE_ENV=true php-cs-fixer fix" ], "phpunit": [ "phpunit --configuration tests/phpunit.xml" diff --git a/lib/ContextStackTrait.php b/lib/ContextStackTrait.php index b514f37..7c082f5 100644 --- a/lib/ContextStackTrait.php +++ b/lib/ContextStackTrait.php @@ -110,7 +110,7 @@ public function popContext(): void $this->elementMap, $this->contextUri, $this->namespaceMap, - $this->classMap + $this->classMap, ) = array_pop($this->contextStack); } } diff --git a/lib/Writer.php b/lib/Writer.php index d431838..3dea023 100644 --- a/lib/Writer.php +++ b/lib/Writer.php @@ -235,7 +235,7 @@ public function writeAttribute($name, $value): bool list( $namespace, - $localName + $localName, ) = Service::parseClarkNotation($name); if (array_key_exists($namespace, $this->namespaceMap)) { From 91fdf78c5b69362206944e399b07742d1ed46175 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 5 Sep 2024 20:29:18 +0545 Subject: [PATCH 2/3] check if parser input is not a string --- lib/Service.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Service.php b/lib/Service.php index 4eebd1f..e9fa895 100644 --- a/lib/Service.php +++ b/lib/Service.php @@ -109,7 +109,7 @@ public function getWriter(): Writer */ public function parse($input, ?string $contextUri = null, ?string &$rootElementName = null) { - if (is_resource($input)) { + if (!is_string($input)) { // Unfortunately the XMLReader doesn't support streams. When it // does, we can optimize this. $input = (string) stream_get_contents($input); @@ -153,7 +153,7 @@ public function parse($input, ?string $contextUri = null, ?string &$rootElementN */ public function expect($rootElementName, $input, ?string $contextUri = null) { - if (is_resource($input)) { + if (!is_string($input)) { // Unfortunately the XMLReader doesn't support streams. When it // does, we can optimize this. $input = (string) stream_get_contents($input); From 7e41f14cc4115b225b3c23ec70de8dd3300c838e Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 5 Sep 2024 20:50:53 +0545 Subject: [PATCH 3/3] Handle input being a closed resource --- lib/Service.php | 18 ++++++++++++++++-- tests/Sabre/Xml/ServiceTest.php | 13 +++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/Service.php b/lib/Service.php index e9fa895..ace923f 100644 --- a/lib/Service.php +++ b/lib/Service.php @@ -112,7 +112,14 @@ public function parse($input, ?string $contextUri = null, ?string &$rootElementN if (!is_string($input)) { // Unfortunately the XMLReader doesn't support streams. When it // does, we can optimize this. - $input = (string) stream_get_contents($input); + if (is_resource($input)) { + $input = (string) stream_get_contents($input); + } else { + // Input is not a string and not a resource. + // Therefore, it has to be a closed resource. + // Effectively empty input has been passed in. + $input = ''; + } } // If input is empty, then it's safe to throw an exception @@ -156,7 +163,14 @@ public function expect($rootElementName, $input, ?string $contextUri = null) if (!is_string($input)) { // Unfortunately the XMLReader doesn't support streams. When it // does, we can optimize this. - $input = (string) stream_get_contents($input); + if (is_resource($input)) { + $input = (string) stream_get_contents($input); + } else { + // Input is not a string and not a resource. + // Therefore, it has to be a closed resource. + // Effectively empty input has been passed in. + $input = ''; + } } // If input is empty, then it's safe to throw an exception diff --git a/tests/Sabre/Xml/ServiceTest.php b/tests/Sabre/Xml/ServiceTest.php index 823675f..245366f 100644 --- a/tests/Sabre/Xml/ServiceTest.php +++ b/tests/Sabre/Xml/ServiceTest.php @@ -388,6 +388,19 @@ public function providesEmptyInput(): array $data[] = [$emptyResource]; $data[] = ['']; + // Also test trying to parse a resource stream that has already been closed. + $xml = << + value + +XML; + $stream = fopen('php://memory', 'r+'); + self:assertIsResource($stream); + fwrite($stream, $xml); + rewind($stream); + fclose($stream); + $data[] = [$stream]; + return $data; }