From 7b1b3fe8cf6a7a1db05cde7a55bb84da12305ceb Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 05:24:33 +0000 Subject: [PATCH 1/8] Fix exception, when a provided URI is invalid --- src/Content/Post/Factory/PostMedia.php | 13 +++++++------ src/Util/Network.php | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Content/Post/Factory/PostMedia.php b/src/Content/Post/Factory/PostMedia.php index fe71b21973..38c5f28ebf 100644 --- a/src/Content/Post/Factory/PostMedia.php +++ b/src/Content/Post/Factory/PostMedia.php @@ -25,6 +25,7 @@ use Friendica\BaseFactory; use Friendica\Capabilities\ICanCreateFromTableRow; use Friendica\Content\Post\Entity; use Friendica\Network; +use Friendica\Util\Network as UtilNetwork; use GuzzleHttp\Psr7\Uri; use Psr\Log\LoggerInterface; use stdClass; @@ -48,24 +49,24 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow { return new Entity\PostMedia( $row['uri-id'], - $row['url'] ? new Uri($row['url']) : null, + UtilNetwork::isValidUri($row['url']) ? new Uri($row['url']) : '', $row['type'], $this->mimeTypeFactory->createFromContentType($row['mimetype']), $row['media-uri-id'], $row['width'], $row['height'], $row['size'], - $row['preview'] ? new Uri($row['preview']) : null, + UtilNetwork::isValidUri($row['preview']) ? new Uri($row['preview']) : null, $row['preview-width'], $row['preview-height'], $row['description'], $row['name'], - $row['author-url'] ? new Uri($row['author-url']) : null, + UtilNetwork::isValidUri($row['author-url']) ? new Uri($row['author-url']) : null, $row['author-name'], - $row['author-image'] ? new Uri($row['author-image']) : null, - $row['publisher-url'] ? new Uri($row['publisher-url']) : null, + UtilNetwork::isValidUri($row['author-image']) ? new Uri($row['author-image']) : null, + UtilNetwork::isValidUri($row['publisher-url']) ? new Uri($row['publisher-url']) : null, $row['publisher-name'], - $row['publisher-image'] ? new Uri($row['publisher-image']) : null, + UtilNetwork::isValidUri($row['publisher-image']) ? new Uri($row['publisher-image']) : null, $row['blurhash'], $row['id'] ); diff --git a/src/Util/Network.php b/src/Util/Network.php index 495510189f..e18173c72c 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -658,4 +658,25 @@ class Network $scheme = parse_url($url, PHP_URL_SCHEME); return !empty($scheme) && in_array($scheme, ['http', 'https']) && parse_url($url, PHP_URL_HOST); } + + /** + * Check if a provided URI is valid + * + * @param string|null $uri + * @return boolean + */ + public static function isValidUri(string $uri = null): bool + { + if (empty($uri)) { + return false; + } + + try { + new Uri($uri); + } catch (\Exception $e) { + Logger::debug('Invalid URI', ['code' => $e->getCode(), 'message' => $e->getMessage(), 'uri' => $uri]); + return false; + } + return true; + } } From be2e715eb1118cbd890dc7c3370ccced500136ab Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 05:51:39 +0000 Subject: [PATCH 2/8] Added test --- tests/src/Util/NetworkTest.php | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/src/Util/NetworkTest.php diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php new file mode 100644 index 0000000000..08d641ab43 --- /dev/null +++ b/tests/src/Util/NetworkTest.php @@ -0,0 +1,42 @@ +. + * + */ + +namespace Friendica\Test\src\Util; + +use Friendica\Util\Network; +use PHPUnit\Framework\TestCase; + +/** + * Network utility test class + */ +class NetworkTest extends TestCase +{ + public function testValidUri() + { + self::assertTrue(Network::isValidUri('https://friendi.ca')); + self::assertTrue(Network::isValidUri('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); + self::assertTrue('did:plc:geqiabvo4b4jnfv2paplzcge'); + self::assertFalse(Network::isValidUri('https://')); + self::assertFalse(Network::isValidUri('')); + self::assertFalse(Network::isValidUri(null)); + self::assertFalse(Network::isValidUri('friendi.ca')); + } +} From 2e0c550ee746cd1d1e1c9778e56c4c50db60d162 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 05:57:38 +0000 Subject: [PATCH 3/8] Fixed test --- tests/src/Util/NetworkTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php index 08d641ab43..b6e471f30a 100644 --- a/tests/src/Util/NetworkTest.php +++ b/tests/src/Util/NetworkTest.php @@ -33,7 +33,6 @@ class NetworkTest extends TestCase { self::assertTrue(Network::isValidUri('https://friendi.ca')); self::assertTrue(Network::isValidUri('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); - self::assertTrue('did:plc:geqiabvo4b4jnfv2paplzcge'); self::assertFalse(Network::isValidUri('https://')); self::assertFalse(Network::isValidUri('')); self::assertFalse(Network::isValidUri(null)); From 8e91db7fb18f674d0b10eb135f0e4112f2912b04 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 06:02:38 +0000 Subject: [PATCH 4/8] Fix test again --- tests/src/Util/NetworkTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php index b6e471f30a..f98ee19a2c 100644 --- a/tests/src/Util/NetworkTest.php +++ b/tests/src/Util/NetworkTest.php @@ -36,6 +36,5 @@ class NetworkTest extends TestCase self::assertFalse(Network::isValidUri('https://')); self::assertFalse(Network::isValidUri('')); self::assertFalse(Network::isValidUri(null)); - self::assertFalse(Network::isValidUri('friendi.ca')); } } From 691e0dd44aebe9a1ca123a181e74cb79921a1bd0 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 07:36:13 +0000 Subject: [PATCH 5/8] Added another test case --- tests/src/Util/NetworkTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php index f98ee19a2c..0c25272afc 100644 --- a/tests/src/Util/NetworkTest.php +++ b/tests/src/Util/NetworkTest.php @@ -33,6 +33,7 @@ class NetworkTest extends TestCase { self::assertTrue(Network::isValidUri('https://friendi.ca')); self::assertTrue(Network::isValidUri('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); + self::assertTrue(Network::isValidUri('did:plc:54alhpjxysxurr3c63zfk63f')); self::assertFalse(Network::isValidUri('https://')); self::assertFalse(Network::isValidUri('')); self::assertFalse(Network::isValidUri(null)); From 0aa49510b2faeefdee6184687bc9868f32f1dd21 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 07:44:01 +0000 Subject: [PATCH 6/8] Changed uri --- tests/src/Util/NetworkTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php index 0c25272afc..6f28cef1eb 100644 --- a/tests/src/Util/NetworkTest.php +++ b/tests/src/Util/NetworkTest.php @@ -33,7 +33,7 @@ class NetworkTest extends TestCase { self::assertTrue(Network::isValidUri('https://friendi.ca')); self::assertTrue(Network::isValidUri('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); - self::assertTrue(Network::isValidUri('did:plc:54alhpjxysxurr3c63zfk63f')); + self::assertTrue(Network::isValidUri('did:plc:geqiabvo4b4jnfv2paplzcge')); self::assertFalse(Network::isValidUri('https://')); self::assertFalse(Network::isValidUri('')); self::assertFalse(Network::isValidUri(null)); From 9b73189e1d08e3f0fb9a28e32026bbed9abd1021 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 19:55:27 +0000 Subject: [PATCH 7/8] Renamed function name --- src/Content/Post/Factory/PostMedia.php | 12 ++++++------ src/Util/Network.php | 13 ++++++------- tests/src/Util/NetworkTest.php | 12 ++++++------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/Content/Post/Factory/PostMedia.php b/src/Content/Post/Factory/PostMedia.php index 38c5f28ebf..864786569f 100644 --- a/src/Content/Post/Factory/PostMedia.php +++ b/src/Content/Post/Factory/PostMedia.php @@ -49,24 +49,24 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow { return new Entity\PostMedia( $row['uri-id'], - UtilNetwork::isValidUri($row['url']) ? new Uri($row['url']) : '', + UtilNetwork::createUriFromString($row['url']) ?: '', $row['type'], $this->mimeTypeFactory->createFromContentType($row['mimetype']), $row['media-uri-id'], $row['width'], $row['height'], $row['size'], - UtilNetwork::isValidUri($row['preview']) ? new Uri($row['preview']) : null, + UtilNetwork::createUriFromString($row['preview']), $row['preview-width'], $row['preview-height'], $row['description'], $row['name'], - UtilNetwork::isValidUri($row['author-url']) ? new Uri($row['author-url']) : null, + UtilNetwork::createUriFromString($row['author-url']), $row['author-name'], - UtilNetwork::isValidUri($row['author-image']) ? new Uri($row['author-image']) : null, - UtilNetwork::isValidUri($row['publisher-url']) ? new Uri($row['publisher-url']) : null, + UtilNetwork::createUriFromString($row['author-image']), + UtilNetwork::createUriFromString($row['publisher-url']), $row['publisher-name'], - UtilNetwork::isValidUri($row['publisher-image']) ? new Uri($row['publisher-image']) : null, + UtilNetwork::createUriFromString($row['publisher-image']), $row['blurhash'], $row['id'] ); diff --git a/src/Util/Network.php b/src/Util/Network.php index e18173c72c..b2f472ba77 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -660,23 +660,22 @@ class Network } /** - * Check if a provided URI is valid + * Creates an Uri object out of a given Uri string * * @param string|null $uri - * @return boolean + * @return UriInterface|null */ - public static function isValidUri(string $uri = null): bool + public static function createUriFromString(string $uri = null): ?UriInterface { if (empty($uri)) { - return false; + return null; } try { - new Uri($uri); + return new Uri($uri); } catch (\Exception $e) { Logger::debug('Invalid URI', ['code' => $e->getCode(), 'message' => $e->getMessage(), 'uri' => $uri]); - return false; + return null; } - return true; } } diff --git a/tests/src/Util/NetworkTest.php b/tests/src/Util/NetworkTest.php index 6f28cef1eb..945abf84db 100644 --- a/tests/src/Util/NetworkTest.php +++ b/tests/src/Util/NetworkTest.php @@ -31,11 +31,11 @@ class NetworkTest extends TestCase { public function testValidUri() { - self::assertTrue(Network::isValidUri('https://friendi.ca')); - self::assertTrue(Network::isValidUri('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); - self::assertTrue(Network::isValidUri('did:plc:geqiabvo4b4jnfv2paplzcge')); - self::assertFalse(Network::isValidUri('https://')); - self::assertFalse(Network::isValidUri('')); - self::assertFalse(Network::isValidUri(null)); + self::assertNotNull(Network::createUriFromString('https://friendi.ca')); + self::assertNotNull(Network::createUriFromString('magnet:?xs=https%3A%2F%2Ftube.jeena.net%2Flazy-static%2Ftorrents%2F04bec7a8-34de-4847-b080-6ee00c4b3d49-1080-hls.torrent&xt=urn:btih:5def5a24dfa7307e999a0d4f0fcc29c3e2b13be2&dn=My+fediverse+setup+-+I+host+everything+myself&tr=https%3A%2F%2Ftube.jeena.net%2Ftracker%2Fannounce&tr=wss%3A%2F%2Ftube.jeena.net%3A443%2Ftracker%2Fsocket&ws=https%3A%2F%2Ftube.jeena.net%2Fstatic%2Fstreaming-playlists%2Fhls%2F23989f41-e230-4dbf-9111-936bc730bf50%2Fe5905de3-e488-4bb8-a1e8-eb7a53ac24ad-1080-fragmented.mp4')); + self::assertNotNull(Network::createUriFromString('did:plc:geqiabvo4b4jnfv2paplzcge')); + self::assertNull(Network::createUriFromString('https://')); + self::assertNull(Network::createUriFromString('')); + self::assertNull(Network::createUriFromString(null)); } } From 914d4506e24ae04760a711f19f27e2a6f274bab1 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 5 Dec 2023 22:33:45 +0000 Subject: [PATCH 8/8] Exception handling added --- src/Content/Post/Factory/PostMedia.php | 2 +- src/Content/Post/Repository/PostMedia.php | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Content/Post/Factory/PostMedia.php b/src/Content/Post/Factory/PostMedia.php index 864786569f..dfebfd4874 100644 --- a/src/Content/Post/Factory/PostMedia.php +++ b/src/Content/Post/Factory/PostMedia.php @@ -49,7 +49,7 @@ class PostMedia extends BaseFactory implements ICanCreateFromTableRow { return new Entity\PostMedia( $row['uri-id'], - UtilNetwork::createUriFromString($row['url']) ?: '', + UtilNetwork::createUriFromString($row['url']), $row['type'], $this->mimeTypeFactory->createFromContentType($row['mimetype']), $row['media-uri-id'], diff --git a/src/Content/Post/Repository/PostMedia.php b/src/Content/Post/Repository/PostMedia.php index 405d9eb86b..70441e0c9d 100644 --- a/src/Content/Post/Repository/PostMedia.php +++ b/src/Content/Post/Repository/PostMedia.php @@ -45,7 +45,11 @@ class PostMedia extends BaseRepository $Entities = new Collection\PostMedias(); foreach ($rows as $fields) { - $Entities[] = $this->factory->createFromTableRow($fields); + try { + $Entities[] = $this->factory->createFromTableRow($fields); + } catch (\Exception $e) { + $this->logger->warning('Invalid media row', ['code' => $e->getCode(), 'message' => $e->getMessage(), 'fields' => $fields]); + } } return $Entities;