aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/composer.json2
-rw-r--r--lib/simplepie/simplepie/CHANGELOG.md8
-rw-r--r--lib/simplepie/simplepie/phpstan.neon.dist3
-rw-r--r--lib/simplepie/simplepie/src/File.php68
-rw-r--r--lib/simplepie/simplepie/src/HTTP/Client.php4
-rw-r--r--lib/simplepie/simplepie/src/HTTP/ClientException.php (renamed from lib/simplepie/simplepie/src/Exception/HttpException.php)8
-rw-r--r--lib/simplepie/simplepie/src/HTTP/FileClient.php9
-rw-r--r--lib/simplepie/simplepie/src/HTTP/Psr18Client.php11
-rw-r--r--lib/simplepie/simplepie/src/HTTP/Psr7Response.php121
-rw-r--r--lib/simplepie/simplepie/src/HTTP/RawTextResponse.php121
-rw-r--r--lib/simplepie/simplepie/src/Item.php35
-rw-r--r--lib/simplepie/simplepie/src/Locator.php8
-rw-r--r--lib/simplepie/simplepie/src/Misc.php17
-rw-r--r--lib/simplepie/simplepie/src/Parser.php21
-rw-r--r--lib/simplepie/simplepie/src/Sanitize.php4
-rw-r--r--lib/simplepie/simplepie/src/SimplePie.php10
-rw-r--r--lib/simplepie/simplepie/utils/PHPStan/README.md7
-rw-r--r--lib/simplepie/simplepie/utils/PHPStan/RegistryCallMethodReturnTypeExtension.php101
-rw-r--r--lib/simplepie/simplepie/utils/PHPStan/extension.neon6
19 files changed, 199 insertions, 365 deletions
diff --git a/lib/composer.json b/lib/composer.json
index 197ed3a2d..0901f62a6 100644
--- a/lib/composer.json
+++ b/lib/composer.json
@@ -14,7 +14,7 @@
"marienfressinaud/lib_opml": "0.5.1",
"phpgt/cssxpath": "v1.3.0",
"phpmailer/phpmailer": "6.10.0",
- "simplepie/simplepie": "dev-freshrss#2f0417355a702c678c237eac5ffc273863301a80"
+ "simplepie/simplepie": "dev-freshrss#d80757267ea1fcbe13d1d1e3a73c2e81f23440de"
},
"config": {
"sort-packages": true,
diff --git a/lib/simplepie/simplepie/CHANGELOG.md b/lib/simplepie/simplepie/CHANGELOG.md
index 69b3dc9df..ff12d7cfb 100644
--- a/lib/simplepie/simplepie/CHANGELOG.md
+++ b/lib/simplepie/simplepie/CHANGELOG.md
@@ -24,6 +24,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Deprecated
+- The following `SimplePie\Misc` methods are deprecated without replacement:
+ - `SimplePie\Misc::element_implode()`
+ - `SimplePie\Misc::parse_str()`
+ - `SimplePie\Misc::percent_encoding_normalization()`
+ - `SimplePie\Misc::strip_comments()`
+ - `SimplePie\Misc::uncomment_rfc822()`
+
+ If you need any of them, consider copying the function to your codebase. (by @jtojnar in [#899](https://github.com/simplepie/simplepie/pull/899))
- The method `SimplePie\SimplePie::set_file()` is deprecated, use `SimplePie\SimplePie::set_http_client()` or `SimplePie\SimplePie::set_raw_data()` instead
- The method `SimplePie\Sanitize::pass_file_data()` is deprecated, use `SimplePie\Sanitize::set_http_client()` instead
- Passing multiple URLs to `SimplePie\SimplePie::set_feed_url()` is deprecated. You can create separate `SimplePie` instance per feed and then use `SimplePie::merge_items()` to get a single list of items. ([#795](https://github.com/simplepie/simplepie/pull/795))
diff --git a/lib/simplepie/simplepie/phpstan.neon.dist b/lib/simplepie/simplepie/phpstan.neon.dist
index 5450a9acb..d922910f9 100644
--- a/lib/simplepie/simplepie/phpstan.neon.dist
+++ b/lib/simplepie/simplepie/phpstan.neon.dist
@@ -65,3 +65,6 @@ parameters:
message: '(^Access to an undefined property XMLReader::\$\w+\.$)'
# Only occurs on PHP ≥ 8.2
reportUnmatched: false
+
+includes:
+ - utils/PHPStan/extension.neon
diff --git a/lib/simplepie/simplepie/src/File.php b/lib/simplepie/simplepie/src/File.php
index a6a444f56..dcc4a690d 100644
--- a/lib/simplepie/simplepie/src/File.php
+++ b/lib/simplepie/simplepie/src/File.php
@@ -324,98 +324,30 @@ class File implements Response
return (int) $this->status_code;
}
- /**
- * Retrieves all message header values.
- *
- * The keys represent the header name as it will be sent over the wire, and
- * each value is an array of strings associated with the header.
- *
- * // Represent the headers as a string
- * foreach ($message->get_headers() as $name => $values) {
- * echo $name . ': ' . implode(', ', $values);
- * }
- *
- * // Emit headers iteratively:
- * foreach ($message->get_headers() as $name => $values) {
- * foreach ($values as $value) {
- * header(sprintf('%s: %s', $name, $value), false);
- * }
- * }
- *
- * @return string[][] Returns an associative array of the message's headers.
- * Each key MUST be a header name, and each value MUST be an array of
- * strings for that header.
- */
public function get_headers(): array
{
$this->maybe_update_headers();
return $this->parsed_headers;
}
- /**
- * Checks if a header exists by the given case-insensitive name.
- *
- * @param string $name Case-insensitive header field name.
- * @return bool Returns true if any header names match the given header
- * name using a case-insensitive string comparison. Returns false if
- * no matching header name is found in the message.
- */
public function has_header(string $name): bool
{
$this->maybe_update_headers();
return $this->get_header($name) !== [];
}
- /**
- * Retrieves a message header value by the given case-insensitive name.
- *
- * This method returns an array of all the header values of the given
- * case-insensitive header name.
- *
- * If the header does not appear in the message, this method MUST return an
- * empty array.
- *
- * @param string $name Case-insensitive header field name.
- * @return string[] An array of string values as provided for the given
- * header. If the header does not appear in the message, this method MUST
- * return an empty array.
- */
public function get_header(string $name): array
{
$this->maybe_update_headers();
return $this->parsed_headers[strtolower($name)] ?? [];
}
- /**
- * Retrieves a comma-separated string of the values for a single header.
- *
- * This method returns all of the header values of the given
- * case-insensitive header name as a string concatenated together using
- * a comma.
- *
- * NOTE: Not all header values may be appropriately represented using
- * comma concatenation. For such headers, use getHeader() instead
- * and supply your own delimiter when concatenating.
- *
- * If the header does not appear in the message, this method MUST return
- * an empty string.
- *
- * @param string $name Case-insensitive header field name.
- * @return string A string of values as provided for the given header
- * concatenated together using a comma. If the header does not appear in
- * the message, this method MUST return an empty string.
- */
public function get_header_line(string $name): string
{
$this->maybe_update_headers();
return implode(', ', $this->get_header($name));
}
- /**
- * get the body as string
- *
- * @return string
- */
public function get_body_content(): string
{
return (string) $this->body;
diff --git a/lib/simplepie/simplepie/src/HTTP/Client.php b/lib/simplepie/simplepie/src/HTTP/Client.php
index 0c67650cf..507c1b0f1 100644
--- a/lib/simplepie/simplepie/src/HTTP/Client.php
+++ b/lib/simplepie/simplepie/src/HTTP/Client.php
@@ -7,8 +7,6 @@ declare(strict_types=1);
namespace SimplePie\HTTP;
-use SimplePie\Exception\HttpException;
-
/**
* HTTP Client interface
*
@@ -24,7 +22,7 @@ interface Client
* @param Client::METHOD_* $method
* @param array<string, string> $headers
*
- * @throws HttpException if anything goes wrong requesting the data
+ * @throws ClientException if anything goes wrong requesting the data
*/
public function request(string $method, string $url, array $headers = []): Response;
}
diff --git a/lib/simplepie/simplepie/src/Exception/HttpException.php b/lib/simplepie/simplepie/src/HTTP/ClientException.php
index 775373aff..d7c005680 100644
--- a/lib/simplepie/simplepie/src/Exception/HttpException.php
+++ b/lib/simplepie/simplepie/src/HTTP/ClientException.php
@@ -5,13 +5,15 @@
declare(strict_types=1);
-namespace SimplePie\Exception;
+namespace SimplePie\HTTP;
use SimplePie\Exception as SimplePieException;
/**
- * HTTP exception class
+ * Client exception class
+ *
+ * @internal
*/
-final class HttpException extends SimplePieException
+final class ClientException extends SimplePieException
{
}
diff --git a/lib/simplepie/simplepie/src/HTTP/FileClient.php b/lib/simplepie/simplepie/src/HTTP/FileClient.php
index 2b21601c8..2cbae4d3b 100644
--- a/lib/simplepie/simplepie/src/HTTP/FileClient.php
+++ b/lib/simplepie/simplepie/src/HTTP/FileClient.php
@@ -8,7 +8,6 @@ declare(strict_types=1);
namespace SimplePie\HTTP;
use InvalidArgumentException;
-use SimplePie\Exception\HttpException;
use SimplePie\File;
use SimplePie\Misc;
use SimplePie\Registry;
@@ -42,7 +41,7 @@ final class FileClient implements Client
* @param Client::METHOD_* $method
* @param array<string, string> $headers
*
- * @throws HttpException if anything goes wrong requesting the data
+ * @throws ClientException if anything goes wrong requesting the data
*/
public function request(string $method, string $url, array $headers = []): Response
{
@@ -66,11 +65,11 @@ final class FileClient implements Client
$this->options['curl_options'] ?? []
]);
} catch (Throwable $th) {
- throw new HttpException($th->getMessage(), $th->getCode(), $th);
+ throw new ClientException($th->getMessage(), $th->getCode(), $th);
}
- if (!$file->success) {
- throw new HttpException($file->error, $file->get_status_code()); // FreshRSS https://github.com/simplepie/simplepie/pull/905
+ if (!$file->success && $file->get_status_code() === 0) {
+ throw new ClientException($file->error);
}
return $file;
diff --git a/lib/simplepie/simplepie/src/HTTP/Psr18Client.php b/lib/simplepie/simplepie/src/HTTP/Psr18Client.php
index a1100f2de..b920333e4 100644
--- a/lib/simplepie/simplepie/src/HTTP/Psr18Client.php
+++ b/lib/simplepie/simplepie/src/HTTP/Psr18Client.php
@@ -12,7 +12,6 @@ use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
-use SimplePie\Exception\HttpException;
use Throwable;
/**
@@ -71,7 +70,7 @@ final class Psr18Client implements Client
* @param string $url
* @param array<string,string|string[]> $headers
*
- * @throws HttpException if anything goes wrong requesting the data
+ * @throws ClientException if anything goes wrong requesting the data
*/
public function request(string $method, string $url, array $headers = []): Response
{
@@ -114,7 +113,7 @@ final class Psr18Client implements Client
try {
$response = $this->httpClient->sendRequest($request);
} catch (ClientExceptionInterface $th) {
- throw new HttpException($th->getMessage(), $th->getCode(), $th);
+ throw new ClientException($th->getMessage(), $th->getCode(), $th);
}
$statusCode = $response->getStatusCode();
@@ -145,17 +144,17 @@ final class Psr18Client implements Client
private function requestLocalFile(string $path): Response
{
if (!is_readable($path)) {
- throw new HttpException(sprintf('file "%s" is not readable', $path));
+ throw new ClientException(sprintf('file "%s" is not readable', $path));
}
try {
$raw = file_get_contents($path);
} catch (Throwable $th) {
- throw new HttpException($th->getMessage(), $th->getCode(), $th);
+ throw new ClientException($th->getMessage(), $th->getCode(), $th);
}
if ($raw === false) {
- throw new HttpException('file_get_contents() could not read the file', 1);
+ throw new ClientException('file_get_contents() could not read the file', 1);
}
return new RawTextResponse($raw, $path);
diff --git a/lib/simplepie/simplepie/src/HTTP/Psr7Response.php b/lib/simplepie/simplepie/src/HTTP/Psr7Response.php
index 65fe4a083..7a52c8ec6 100644
--- a/lib/simplepie/simplepie/src/HTTP/Psr7Response.php
+++ b/lib/simplepie/simplepie/src/HTTP/Psr7Response.php
@@ -41,162 +41,41 @@ final class Psr7Response implements Response
$this->requested_url = $requested_url;
}
- /**
- * Return the string representation of the permanent URI of the requested resource
- * (the first location after a prefix of (only) permanent redirects).
- *
- * Depending on which components of the URI are present, the resulting
- * string is either a full URI or relative reference according to RFC 3986,
- * Section 4.1. The method concatenates the various components of the URI,
- * using the appropriate delimiters:
- *
- * - If a scheme is present, it MUST be suffixed by ":".
- * - If an authority is present, it MUST be prefixed by "//".
- * - The path can be concatenated without delimiters. But there are two
- * cases where the path has to be adjusted to make the URI reference
- * valid as PHP does not allow to throw an exception in __toString():
- * - If the path is rootless and an authority is present, the path MUST
- * be prefixed by "/".
- * - If the path is starting with more than one "/" and no authority is
- * present, the starting slashes MUST be reduced to one.
- * - If a query is present, it MUST be prefixed by "?".
- * - If a fragment is present, it MUST be prefixed by "#".
- *
- * @see http://tools.ietf.org/html/rfc3986#section-4.1
- */
public function get_permanent_uri(): string
{
return $this->permanent_url;
}
- /**
- * Return the string representation of the final requested URL after following all redirects.
- *
- * Depending on which components of the URI are present, the resulting
- * string is either a full URI or relative reference according to RFC 3986,
- * Section 4.1. The method concatenates the various components of the URI,
- * using the appropriate delimiters:
- *
- * - If a scheme is present, it MUST be suffixed by ":".
- * - If an authority is present, it MUST be prefixed by "//".
- * - The path can be concatenated without delimiters. But there are two
- * cases where the path has to be adjusted to make the URI reference
- * valid as PHP does not allow to throw an exception in __toString():
- * - If the path is rootless and an authority is present, the path MUST
- * be prefixed by "/".
- * - If the path is starting with more than one "/" and no authority is
- * present, the starting slashes MUST be reduced to one.
- * - If a query is present, it MUST be prefixed by "?".
- * - If a fragment is present, it MUST be prefixed by "#".
- *
- * @see http://tools.ietf.org/html/rfc3986#section-4.1
- */
public function get_final_requested_uri(): string
{
return $this->requested_url;
}
- /**
- * Gets the response status code.
- *
- * The status code is a 3-digit integer result code of the server's attempt
- * to understand and satisfy the request.
- *
- * @return int Status code.
- */
public function get_status_code(): int
{
return $this->response->getStatusCode();
}
- /**
- * Retrieves all message header values.
- *
- * The keys represent the header name as it will be sent over the wire, and
- * each value is an array of strings associated with the header.
- *
- * // Represent the headers as a string
- * foreach ($message->get_headers() as $name => $values) {
- * echo $name . ': ' . implode(', ', $values);
- * }
- *
- * // Emit headers iteratively:
- * foreach ($message->get_headers() as $name => $values) {
- * foreach ($values as $value) {
- * header(sprintf('%s: %s', $name, $value), false);
- * }
- * }
- *
- * @return string[][] Returns an associative array of the message's headers.
- * Each key MUST be a header name, and each value MUST be an array of
- * strings for that header.
- */
public function get_headers(): array
{
return $this->response->getHeaders();
}
- /**
- * Checks if a header exists by the given case-insensitive name.
- *
- * @param string $name Case-insensitive header field name.
- * @return bool Returns true if any header names match the given header
- * name using a case-insensitive string comparison. Returns false if
- * no matching header name is found in the message.
- */
public function has_header(string $name): bool
{
return $this->response->hasHeader($name);
}
- /**
- * Retrieves a message header value by the given case-insensitive name.
- *
- * This method returns an array of all the header values of the given
- * case-insensitive header name.
- *
- * If the header does not appear in the message, this method MUST return an
- * empty array.
- *
- * @param string $name Case-insensitive header field name.
- * @return string[] An array of string values as provided for the given
- * header. If the header does not appear in the message, this method MUST
- * return an empty array.
- */
public function get_header(string $name): array
{
return $this->response->getHeader($name);
}
- /**
- * Retrieves a comma-separated string of the values for a single header.
- *
- * This method returns all of the header values of the given
- * case-insensitive header name as a string concatenated together using
- * a comma.
- *
- * NOTE: Not all header values may be appropriately represented using
- * comma concatenation. For such headers, use getHeader() instead
- * and supply your own delimiter when concatenating.
- *
- * If the header does not appear in the message, this method MUST return
- * an empty string.
- *
- * @param string $name Case-insensitive header field name.
- * @return string A string of values as provided for the given header
- * concatenated together using a comma. If the header does not appear in
- * the message, this method MUST return an empty string.
- */
public function get_header_line(string $name): string
{
return $this->response->getHeaderLine($name);
}
- /**
- * get the body as string
- *
- * @return string
- */
public function get_body_content(): string
{
return $this->response->getBody()->__toString();
diff --git a/lib/simplepie/simplepie/src/HTTP/RawTextResponse.php b/lib/simplepie/simplepie/src/HTTP/RawTextResponse.php
index 41cb88abc..1cb8fd46d 100644
--- a/lib/simplepie/simplepie/src/HTTP/RawTextResponse.php
+++ b/lib/simplepie/simplepie/src/HTTP/RawTextResponse.php
@@ -39,162 +39,41 @@ final class RawTextResponse implements Response
$this->requested_url = $filepath;
}
- /**
- * Return the string representation of the permanent URI of the requested resource
- * (the first location after a prefix of (only) permanent redirects).
- *
- * Depending on which components of the URI are present, the resulting
- * string is either a full URI or relative reference according to RFC 3986,
- * Section 4.1. The method concatenates the various components of the URI,
- * using the appropriate delimiters:
- *
- * - If a scheme is present, it MUST be suffixed by ":".
- * - If an authority is present, it MUST be prefixed by "//".
- * - The path can be concatenated without delimiters. But there are two
- * cases where the path has to be adjusted to make the URI reference
- * valid as PHP does not allow to throw an exception in __toString():
- * - If the path is rootless and an authority is present, the path MUST
- * be prefixed by "/".
- * - If the path is starting with more than one "/" and no authority is
- * present, the starting slashes MUST be reduced to one.
- * - If a query is present, it MUST be prefixed by "?".
- * - If a fragment is present, it MUST be prefixed by "#".
- *
- * @see http://tools.ietf.org/html/rfc3986#section-4.1
- */
public function get_permanent_uri(): string
{
return $this->permanent_url;
}
- /**
- * Return the string representation of the final requested URL after following all redirects.
- *
- * Depending on which components of the URI are present, the resulting
- * string is either a full URI or relative reference according to RFC 3986,
- * Section 4.1. The method concatenates the various components of the URI,
- * using the appropriate delimiters:
- *
- * - If a scheme is present, it MUST be suffixed by ":".
- * - If an authority is present, it MUST be prefixed by "//".
- * - The path can be concatenated without delimiters. But there are two
- * cases where the path has to be adjusted to make the URI reference
- * valid as PHP does not allow to throw an exception in __toString():
- * - If the path is rootless and an authority is present, the path MUST
- * be prefixed by "/".
- * - If the path is starting with more than one "/" and no authority is
- * present, the starting slashes MUST be reduced to one.
- * - If a query is present, it MUST be prefixed by "?".
- * - If a fragment is present, it MUST be prefixed by "#".
- *
- * @see http://tools.ietf.org/html/rfc3986#section-4.1
- */
public function get_final_requested_uri(): string
{
return $this->requested_url;
}
- /**
- * Gets the response status code.
- *
- * The status code is a 3-digit integer result code of the server's attempt
- * to understand and satisfy the request.
- *
- * @return int Status code.
- */
public function get_status_code(): int
{
return 200;
}
- /**
- * Retrieves all message header values.
- *
- * The keys represent the header name as it will be sent over the wire, and
- * each value is an array of strings associated with the header.
- *
- * // Represent the headers as a string
- * foreach ($message->get_headers() as $name => $values) {
- * echo $name . ': ' . implode(', ', $values);
- * }
- *
- * // Emit headers iteratively:
- * foreach ($message->get_headers() as $name => $values) {
- * foreach ($values as $value) {
- * header(sprintf('%s: %s', $name, $value), false);
- * }
- * }
- *
- * @return string[][] Returns an associative array of the message's headers.
- * Each key MUST be a header name, and each value MUST be an array of
- * strings for that header.
- */
public function get_headers(): array
{
return [];
}
- /**
- * Checks if a header exists by the given case-insensitive name.
- *
- * @param string $name Case-insensitive header field name.
- * @return bool Returns true if any header names match the given header
- * name using a case-insensitive string comparison. Returns false if
- * no matching header name is found in the message.
- */
public function has_header(string $name): bool
{
return false;
}
- /**
- * Retrieves a message header value by the given case-insensitive name.
- *
- * This method returns an array of all the header values of the given
- * case-insensitive header name.
- *
- * If the header does not appear in the message, this method MUST return an
- * empty array.
- *
- * @param string $name Case-insensitive header field name.
- * @return string[] An array of string values as provided for the given
- * header. If the header does not appear in the message, this method MUST
- * return an empty array.
- */
public function get_header(string $name): array
{
return [];
}
- /**
- * Retrieves a comma-separated string of the values for a single header.
- *
- * This method returns all of the header values of the given
- * case-insensitive header name as a string concatenated together using
- * a comma.
- *
- * NOTE: Not all header values may be appropriately represented using
- * comma concatenation. For such headers, use getHeader() instead
- * and supply your own delimiter when concatenating.
- *
- * If the header does not appear in the message, this method MUST return
- * an empty string.
- *
- * @param string $name Case-insensitive header field name.
- * @return string A string of values as provided for the given header
- * concatenated together using a comma. If the header does not appear in
- * the message, this method MUST return an empty string.
- */
public function get_header_line(string $name): string
{
return '';
}
- /**
- * get the body as string
- *
- * @return string
- */
public function get_body_content(): string
{
return $this->raw_text;
diff --git a/lib/simplepie/simplepie/src/Item.php b/lib/simplepie/simplepie/src/Item.php
index 8780a83ce..2b0201d77 100644
--- a/lib/simplepie/simplepie/src/Item.php
+++ b/lib/simplepie/simplepie/src/Item.php
@@ -127,7 +127,7 @@ class Item implements RegistryAware
* @param array<string, mixed> $element
* @see get_base
*/
- protected function get_own_base(array $element = []): string
+ private function get_own_base(array $element = []): string
{
if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
return $element['xml_base'];
@@ -1221,11 +1221,11 @@ class Item implements RegistryAware
// PLAYER
if ($player_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
if (isset($player_parent[0]['attribs']['']['url'])) {
- $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($player_parent[0]));
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($player_parent[0]));
}
} elseif ($player_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
if (isset($player_parent[0]['attribs']['']['url'])) {
- $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($player_parent[0]));
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($player_parent[0]));
}
}
@@ -1345,13 +1345,13 @@ class Item implements RegistryAware
if ($thumbnails = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
foreach ($thumbnails as $thumbnail) {
if (isset($thumbnail['attribs']['']['url'])) {
- $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($thumbnail));
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
}
}
} elseif ($thumbnails = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
foreach ($thumbnails as $thumbnail) {
if (isset($thumbnail['attribs']['']['url'])) {
- $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($thumbnail));
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
}
}
}
@@ -1475,7 +1475,7 @@ class Item implements RegistryAware
if (isset($content['attribs']['']['width'])) {
$width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
}
- $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($content));
+ $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($content));
// Checking the other optional media: elements. Priority: media:content, media:group, item, channel
@@ -1734,9 +1734,11 @@ class Item implements RegistryAware
// PLAYER
if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
- $player = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player']));
+ $playerElem = $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
+ $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
} elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
- $player = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player']));
+ $playerElem = $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
+ $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
} else {
$player = $player_parent;
}
@@ -1826,14 +1828,14 @@ class Item implements RegistryAware
// THUMBNAILS
if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
- $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($thumbnail));
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
}
if (is_array($thumbnails)) {
$thumbnails = array_values(array_unique($thumbnails));
}
} elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
- $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($thumbnail));
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
}
if (is_array($thumbnails)) {
$thumbnails = array_values(array_unique($thumbnails));
@@ -1931,7 +1933,7 @@ class Item implements RegistryAware
$width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
}
if (isset($content['attribs']['']['url'])) {
- $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($content));
+ $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($content));
}
// Checking the other optional media: elements. Priority: media:content, media:group, item, channel
@@ -2086,7 +2088,8 @@ class Item implements RegistryAware
// PLAYER
if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
- $player = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]));
+ $playerElem = $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0];
+ $player = $this->sanitize($playerElem['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($playerElem));
}
} else {
$player = $player_parent;
@@ -2142,7 +2145,7 @@ class Item implements RegistryAware
if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
if (isset($thumbnail['attribs']['']['url'])) {
- $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($thumbnail));
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($thumbnail));
}
}
if (is_array($thumbnails)) {
@@ -2182,7 +2185,7 @@ class Item implements RegistryAware
$url = null;
$width = null;
- $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
+ $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
if (isset($link['attribs']['']['type'])) {
$type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
}
@@ -2218,7 +2221,7 @@ class Item implements RegistryAware
$url = null;
$width = null;
- $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
+ $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($link));
if (isset($link['attribs']['']['type'])) {
$type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
}
@@ -2249,7 +2252,7 @@ class Item implements RegistryAware
$url = null;
$width = null;
- $url = $this->sanitize($enclosure['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($enclosure));
+ $url = $this->sanitize($enclosure['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_own_base($enclosure));
$url = $this->get_sanitize()->https_url($url);
if (isset($enclosure['attribs']['']['type'])) {
$type = $this->sanitize($enclosure['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
diff --git a/lib/simplepie/simplepie/src/Locator.php b/lib/simplepie/simplepie/src/Locator.php
index 79ce5d761..2f06c3f99 100644
--- a/lib/simplepie/simplepie/src/Locator.php
+++ b/lib/simplepie/simplepie/src/Locator.php
@@ -11,8 +11,8 @@ use DomDocument;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
-use SimplePie\Exception\HttpException;
use SimplePie\HTTP\Client;
+use SimplePie\HTTP\ClientException;
use SimplePie\HTTP\FileClient;
use SimplePie\HTTP\Psr18Client;
use SimplePie\HTTP\Response;
@@ -263,7 +263,7 @@ class Locator implements RegistryAware
if ((!Misc::is_remote_uri($feed->get_final_requested_uri()) || ($feed->get_status_code() === 200 || $feed->get_status_code() > 206 && $feed->get_status_code() < 300)) && $this->is_feed($feed, true)) {
$feeds[$href] = $feed;
}
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
// Just mark it as done and continue.
}
}
@@ -388,7 +388,7 @@ class Locator implements RegistryAware
if ((!Misc::is_remote_uri($feed->get_final_requested_uri()) || ($feed->get_status_code() === 200 || $feed->get_status_code() > 206 && $feed->get_status_code() < 300)) && $this->is_feed($feed)) {
return [$feed];
}
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
// Just unset and continue.
}
@@ -420,7 +420,7 @@ class Locator implements RegistryAware
if ((!Misc::is_remote_uri($feed->get_final_requested_uri()) || ($feed->get_status_code() === 200 || $feed->get_status_code() > 206 && $feed->get_status_code() < 300)) && $this->is_feed($feed)) {
return [$feed];
}
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
// Just unset and continue.
}
diff --git a/lib/simplepie/simplepie/src/Misc.php b/lib/simplepie/simplepie/src/Misc.php
index b5569510a..2376a8dcc 100644
--- a/lib/simplepie/simplepie/src/Misc.php
+++ b/lib/simplepie/simplepie/src/Misc.php
@@ -105,11 +105,14 @@ class Misc
}
/**
+ * @deprecated since SimplePie 1.9.0. If you need it, you can copy the function to your codebase. But you should consider using `DOMDocument` for any DOM wrangling.
* @param array{tag: string, self_closing: bool, attribs: array<string, array{data: string}>, content: string} $element
* @return string
*/
public static function element_implode(array $element)
{
+ // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.9.'), \E_USER_DEPRECATED);
+
$full = "<{$element['tag']}";
foreach ($element['attribs'] as $key => $value) {
$key = strtolower($key);
@@ -250,6 +253,7 @@ class Misc
}
/**
+ * @deprecated since SimplePie 1.9.0. This functionality is part of `IRI` – if you need it standalone, consider copying the function to your codebase.
* @param array<int, string> $match
* @return string
*/
@@ -1712,11 +1716,14 @@ class Misc
/**
* Strip HTML comments
*
+ * @deprecated since SimplePie 1.9.0. If you need it, you can copy the function to your codebase. But you should consider using `DOMDocument` for any DOM wrangling.
* @param string $data Data to strip comments from
* @return string Comment stripped string
*/
public static function strip_comments(string $data)
{
+ // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.9.'), \E_USER_DEPRECATED);
+
$output = '';
while (($start = strpos($data, '<!--')) !== false) {
$output .= substr($data, 0, $start);
@@ -1756,11 +1763,14 @@ class Misc
/**
* Remove RFC822 comments
*
+ * @deprecated since SimplePie 1.9.0. If you need it, consider copying the function to your codebase.
* @param string $string Data to strip comments from
* @return string Comment stripped string
*/
public static function uncomment_rfc822(string $string)
{
+ // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.9.'), \E_USER_DEPRECATED);
+
$position = 0;
$length = strlen($string);
$depth = 0;
@@ -1848,7 +1858,7 @@ class Misc
/**
* @param array<string, array<string, string>> $attribs
- * @return int
+ * @return int-mask-of<SimplePie::CONSTRUCT_*>
*/
public static function atom_10_construct_type(array $attribs)
{
@@ -1872,7 +1882,7 @@ class Misc
/**
* @param array<string, array<string, string>> $attribs
- * @return int
+ * @return int-mask-of<SimplePie::CONSTRUCT_*>
*/
public static function atom_10_content_construct_type(array $attribs)
{
@@ -1964,12 +1974,15 @@ class Misc
* Returns an associative array of name/value pairs, where the value is an
* array of values that have used the same name
*
+ * @deprecated since SimplePie 1.9.0. If you need it, consider copying the function to your codebase.
* @static
* @param string $str The input string.
* @return array<string, array<string|null>>
*/
public static function parse_str(string $str)
{
+ // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.9.'), \E_USER_DEPRECATED);
+
$return = [];
$str = explode('&', $str);
diff --git a/lib/simplepie/simplepie/src/Parser.php b/lib/simplepie/simplepie/src/Parser.php
index 5c748477e..eb171d9dd 100644
--- a/lib/simplepie/simplepie/src/Parser.php
+++ b/lib/simplepie/simplepie/src/Parser.php
@@ -111,18 +111,14 @@ class Parser implements RegistryAware
$declaration = $this->registry->create(DeclarationParser::class, [substr($data, 5, $pos - 5)]);
if ($declaration->parse()) {
$data = substr($data, $pos + 2);
- $data = preg_replace('/^\\s*<!DOCTYPE\\s[^>\\[\\]]*>\s*/', '', $data); // Strip DOCTYPE except if containing an [internal subset]
$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . "\n" .
- (preg_match('/^\\s*<!DOCTYPE\\s/', $data) ? '' : $this->declare_html_entities()) . // Declare HTML entities only if no remaining DOCTYPE
- $data;
+ self::set_doctype($data);
} else {
$this->error_string = 'SimplePie bug! Please report this!';
return false;
}
} else {
- $data = preg_replace('/^\\s*<!DOCTYPE\\s[^>\\[\\]]*>\s*/', '', $data); // Strip DOCTYPE except if containing an [internal subset]
- $data = (preg_match('/^\\s*<!DOCTYPE\\s/', $data) ? '' : $this->declare_html_entities()) . // Declare HTML entities only if no remaining DOCTYPE
- $data;
+ $data = self::set_doctype($data);
}
$return = true;
@@ -651,11 +647,20 @@ class Parser implements RegistryAware
return true;
}
- private function declare_html_entities(): string
+ private static function set_doctype(string $data): string
+ {
+ // Strip DOCTYPE except if containing an [internal subset]
+ $data = preg_replace('/^\\s*<!DOCTYPE\\s[^>\\[\\]]*>\s*/', '', $data);
+ // Declare HTML entities only if no remaining DOCTYPE
+ $doctype = preg_match('/^\\s*<!DOCTYPE\\s/', $data) ? '' : self::declare_html_entities();
+ return $doctype . $data;
+ }
+
+ private static function declare_html_entities(): string
{
// This is required because the RSS specification says that entity-encoded
// html is allowed, but the xml specification says they must be declared.
- return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
+ return '<!DOCTYPE rss [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
}
}
diff --git a/lib/simplepie/simplepie/src/Sanitize.php b/lib/simplepie/simplepie/src/Sanitize.php
index 1050b2266..9af3a6b12 100644
--- a/lib/simplepie/simplepie/src/Sanitize.php
+++ b/lib/simplepie/simplepie/src/Sanitize.php
@@ -18,8 +18,8 @@ use SimplePie\Cache\BaseDataCache;
use SimplePie\Cache\CallableNameFilter;
use SimplePie\Cache\DataCache;
use SimplePie\Cache\NameFilter;
-use SimplePie\Exception\HttpException;
use SimplePie\HTTP\Client;
+use SimplePie\HTTP\ClientException;
use SimplePie\HTTP\FileClient;
use SimplePie\HTTP\Psr18Client;
@@ -504,7 +504,7 @@ class Sanitize implements RegistryAware
$img->getAttribute('src'),
['X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']]
);
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
continue;
}
diff --git a/lib/simplepie/simplepie/src/SimplePie.php b/lib/simplepie/simplepie/src/SimplePie.php
index 89f7624f8..a61e7158a 100644
--- a/lib/simplepie/simplepie/src/SimplePie.php
+++ b/lib/simplepie/simplepie/src/SimplePie.php
@@ -20,8 +20,8 @@ use SimplePie\Cache\NameFilter;
use SimplePie\Cache\Psr16;
use SimplePie\Content\Type\Sniffer;
use SimplePie\Exception as SimplePieException;
-use SimplePie\Exception\HttpException;
use SimplePie\HTTP\Client;
+use SimplePie\HTTP\ClientException;
use SimplePie\HTTP\FileClient;
use SimplePie\HTTP\Psr18Client;
use SimplePie\HTTP\Response;
@@ -1997,7 +1997,7 @@ class SimplePie
try {
$file = $this->get_http_client()->request(Client::METHOD_GET, $this->feed_url, $headers);
$this->status_code = $file->get_status_code();
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
$this->check_modified = false;
$this->status_code = $th->getCode(); // FreshRSS https://github.com/simplepie/simplepie/pull/905
@@ -2090,7 +2090,7 @@ class SimplePie
];
try {
$file = $this->get_http_client()->request(Client::METHOD_GET, $this->feed_url, $headers);
- } catch (HttpException $th) {
+ } catch (ClientException $th) {
// If the file connection has an error, set SimplePie::error to that and quit
$this->error = $th->getMessage();
$this->status_code = $th->getCode(); // FreshRSS https://github.com/simplepie/simplepie/pull/905
@@ -2605,10 +2605,10 @@ class SimplePie
if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
return $element['xml_base'];
}
- if (($link = $this->get_link(0, 'self')) !== null) {
+ if (($link = $this->get_link(0, 'alternate')) !== null) {
return $link;
}
- if (($link = $this->get_link(0, 'alternate')) !== null) {
+ if (($link = $this->get_link(0, 'self')) !== null) {
return $link;
}
diff --git a/lib/simplepie/simplepie/utils/PHPStan/README.md b/lib/simplepie/simplepie/utils/PHPStan/README.md
new file mode 100644
index 000000000..bd0cdb030
--- /dev/null
+++ b/lib/simplepie/simplepie/utils/PHPStan/README.md
@@ -0,0 +1,7 @@
+# SimplePie PHPStan extension
+
+**This extension is considered unstable, use at your own risk.**
+
+It provides:
+
+- Correct return type for `Registry::call()`
diff --git a/lib/simplepie/simplepie/utils/PHPStan/RegistryCallMethodReturnTypeExtension.php b/lib/simplepie/simplepie/utils/PHPStan/RegistryCallMethodReturnTypeExtension.php
new file mode 100644
index 000000000..564ba0dfa
--- /dev/null
+++ b/lib/simplepie/simplepie/utils/PHPStan/RegistryCallMethodReturnTypeExtension.php
@@ -0,0 +1,101 @@
+<?php
+
+// SPDX-FileCopyrightText: 2024 Jan Tojnar
+// SPDX-License-Identifier: BSD-3-Clause
+
+declare(strict_types=1);
+
+namespace SimplePieUtils\PHPStan;
+
+use PHPStan\Analyser\Scope;
+use PHPStan\Reflection\MethodReflection;
+use PHPStan\Reflection\ParametersAcceptorSelector;
+use PHPStan\Type\DynamicMethodReturnTypeExtension;
+use PHPStan\Type\Type;
+use PHPStan\Reflection\ReflectionProvider;
+use PhpParser\Node\Expr\MethodCall;
+use PHPStan\Type\Constant\ConstantStringType;
+use PHPStan\Type\Constant\ConstantArrayType;
+use PHPStan\Type\ArrayType;
+use PHPStan\Type\MixedType;
+
+/**
+ * Fixes return type for `Registry::call()` to match the called method.
+ */
+class RegistryCallMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
+{
+ /** @var ReflectionProvider */
+ private $reflectionProvider;
+
+ public function __construct(ReflectionProvider $reflectionProvider)
+ {
+ $this->reflectionProvider = $reflectionProvider;
+ }
+
+ public function getClass(): string
+ {
+ return 'SimplePie\Registry';
+ }
+
+ public function isMethodSupported(MethodReflection $methodReflection): bool
+ {
+ return $methodReflection->getName() === 'call';
+ }
+
+ public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
+ {
+ // The method will be called as `$registry->call($className, $methodName, $arguments)`.
+ $args = $methodCall->getArgs();
+
+ if (count($args) < 2) {
+ // Not enough arguments to determine the return type.
+ return new MixedType();
+ }
+
+ $classNameArg = $args[0]->value;
+ $methodNameArg = $args[1]->value;
+ $argumentsArg = $args[2]->value ?? null;
+
+ $classType = $scope->getType($classNameArg);
+ $methodType = $scope->getType($methodNameArg);
+
+ if (!$classType instanceof ConstantStringType || !$methodType instanceof ConstantStringType) {
+ return new MixedType();
+ }
+
+ $className = $classType->getValue();
+ if (!$this->reflectionProvider->hasClass($className)) {
+ return new MixedType();
+ }
+
+ $classReflection = $this->reflectionProvider->getClass($className);
+
+ $methodName = $methodType->getValue();
+ if (!$classReflection->hasMethod($methodName)) {
+ return new MixedType();
+ }
+
+ $methodReflection = $classReflection->getMethod($methodName, $scope);
+
+ $argumentTypes = [];
+ if ($argumentsArg !== null) {
+ $argumentsType = $scope->getType($argumentsArg);
+
+ if ($argumentsType instanceof ConstantArrayType) {
+ $argumentTypes = $argumentsType->getValueTypes();
+ } elseif ($argumentsType instanceof ArrayType) {
+ $argumentTypes = [$argumentsType->getItemType()];
+ } else {
+ return new MixedType();
+ }
+ }
+
+ $parametersAcceptor = ParametersAcceptorSelector::selectFromTypes(
+ $argumentTypes,
+ $methodReflection->getVariants(),
+ false
+ );
+
+ return $parametersAcceptor->getReturnType();
+ }
+}
diff --git a/lib/simplepie/simplepie/utils/PHPStan/extension.neon b/lib/simplepie/simplepie/utils/PHPStan/extension.neon
new file mode 100644
index 000000000..3b6811a20
--- /dev/null
+++ b/lib/simplepie/simplepie/utils/PHPStan/extension.neon
@@ -0,0 +1,6 @@
+
+services:
+ -
+ class: SimplePieUtils\PHPStan\RegistryCallMethodReturnTypeExtension
+ tags:
+ - phpstan.broker.dynamicMethodReturnTypeExtension