From 4715329d4241008a36f0cd479c310f505cfdcea0 Mon Sep 17 00:00:00 2001 From: Eduardo Dobay Date: Fri, 30 Oct 2020 10:37:05 -0300 Subject: [PATCH] Allow installing under PHP 8 1. Allow PHPUnit 9 (needed for PHP 8) 2. Shim deprecated libxml functions Make the call to libxml_disable_entity_loader conditional. This function has been deprecated in PHP 8.0 and the new default is equivalent to calling that function with `true`. https://php.watch/versions/8.0/libxml_disable_entity_loader-deprecation Note: there were two instances of exactly the same XML-parsing anonymous function. I've traced this duplication back to 2015 when the functions were one line long and explicitness might have been better than deduplication. Over the years these functions have been growing together and I see no obvious reason why two copies should be maintained. --- composer.json | 4 ++-- src/ServerRequest.php | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index 14373bc..37ef3b2 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2 || ^8.0", "ext-SimpleXML": "*", "ext-fileinfo": "*", "ext-json": "*", @@ -42,7 +42,7 @@ "nyholm/psr7": "^1.3", "php-http/psr7-integration-tests": "dev-master", "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5", + "phpunit/phpunit": "^8.5 || ^9.3", "squizlabs/php_codesniffer": "^3.5" }, "autoload": { diff --git a/src/ServerRequest.php b/src/ServerRequest.php index 659bec9..954f2e0 100644 --- a/src/ServerRequest.php +++ b/src/ServerRequest.php @@ -61,12 +61,12 @@ final public function __construct(ServerRequestInterface $serverRequest) return $result; }); - $this->registerMediaTypeParser('application/xml', function ($input) { - $backup = libxml_disable_entity_loader(true); + $xmlParserCallable = function ($input) { + $backup = self::disableXmlEntityLoader(true); $backup_errors = libxml_use_internal_errors(true); $result = simplexml_load_string($input); - libxml_disable_entity_loader($backup); + self::disableXmlEntityLoader($backup); libxml_clear_errors(); libxml_use_internal_errors($backup_errors); @@ -75,23 +75,10 @@ final public function __construct(ServerRequestInterface $serverRequest) } return $result; - }); - - $this->registerMediaTypeParser('text/xml', function ($input) { - $backup = libxml_disable_entity_loader(true); - $backup_errors = libxml_use_internal_errors(true); - $result = simplexml_load_string($input); - - libxml_disable_entity_loader($backup); - libxml_clear_errors(); - libxml_use_internal_errors($backup_errors); - - if ($result === false) { - return null; - } + }; - return $result; - }); + $this->registerMediaTypeParser('application/xml', $xmlParserCallable); + $this->registerMediaTypeParser('text/xml', $xmlParserCallable); $this->registerMediaTypeParser('application/x-www-form-urlencoded', function ($input) { parse_str($input, $data); @@ -781,4 +768,17 @@ public function isXhr(): bool { return $this->serverRequest->getHeaderLine('X-Requested-With') === 'XMLHttpRequest'; } + + private static function disableXmlEntityLoader(bool $disable): bool + { + if (\LIBXML_VERSION >= 20900) { + // libxml >= 2.9.0 disables entity loading by default, so it is + // safe to skip the real call (deprecated in PHP 8). + return true; + } + + // @codeCoverageIgnoreStart + return libxml_disable_entity_loader($disable); + // @codeCoverageIgnoreEnd + } }