From e7574356d83ec698afcc942103c0aa1c14000860 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:08:48 -0500 Subject: [PATCH 1/9] Replace parse_url with UriInterface instantiation in Model\APContact - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/Model/APContact.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 67ce2b66bf..fd748f1cd4 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -291,14 +291,11 @@ class APContact return $fetched_contact; } - $parts = parse_url($apcontact['url']); - unset($parts['scheme']); - unset($parts['path']); - if (empty($apcontact['addr'])) { - if (!empty($apcontact['nick']) && is_array($parts)) { - $apcontact['addr'] = $apcontact['nick'] . '@' . str_replace('//', '', Network::unparseURL($parts)); - } else { + try { + $apcontact['addr'] = $apcontact['nick'] . '@' . (new Uri($apcontact['url']))->getAuthority(); + } catch (\Throwable $e) { + Logger::warning('Unable to coerce APContact URL into a UriInterface object', ['url' => $apcontact['url'], 'error' => $e->getMessage()]); $apcontact['addr'] = ''; } } From 1622ce0a998b99683df6ca0d6e2f36393a179739 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:10:38 -0500 Subject: [PATCH 2/9] Coalesce null activity name in ActivityPub\Processor - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/Protocol/ActivityPub/Processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 8e21a66446..60a5c8d741 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -804,7 +804,7 @@ class Processor private static function processContent(array $activity, array $item) { if (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/markdown')) { - $item['title'] = strip_tags($activity['name']); + $item['title'] = strip_tags($activity['name'] ?? ''); $content = Markdown::toBBCode($activity['content']); } elseif (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/bbcode')) { $item['title'] = $activity['name']; From 0af2be14eec590ca55bec12b6e37beed588d0436 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:15:47 -0500 Subject: [PATCH 3/9] Check for parts key existence before performing strpos in Network\Probe - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/Network/Probe.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/Probe.php b/src/Network/Probe.php index e74b437345..87c28619dc 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -684,7 +684,7 @@ class Probe } $parts = parse_url($uri); - if (empty($parts['scheme']) && empty($parts['host']) && !strstr($parts['path'], '@')) { + if (empty($parts['scheme']) && empty($parts['host']) && (empty($parts['path']) || strpos($parts['path'], '@') === false)) { Logger::info('URI was not detectable', ['uri' => $uri]); return []; } From fc246424a907e91fc19a4aa9ac7ef3526523607e Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:21:23 -0500 Subject: [PATCH 4/9] Provide default host value to hash() in Model\Item::guidFromUri - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/Contact/Avatar.php | 2 +- src/Model/Contact.php | 4 ++-- src/Model/Item.php | 10 ++++++++-- src/Model/Mail.php | 3 +-- src/Protocol/Feed.php | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index 0cfc8df345..711a8549f2 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -125,7 +125,7 @@ class Avatar private static function getFilename(string $url): string { - $guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST)); + $guid = Item::guidFromUri($url); return substr($guid, 0, 2) . '/' . substr($guid, 3, 2) . '/' . substr($guid, 5, 3) . '/' . substr($guid, 9, 2) .'/' . substr($guid, 11, 2) . '/' . substr($guid, 13, 4). '/' . substr($guid, 18) . '-'; diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 873de08906..4a10fd98ea 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2099,7 +2099,7 @@ class Contact if ($static) { $query_params['static'] = true; } - + return $url . ($guid ?: $cid) . (!empty($query_params) ? '?' . http_build_query($query_params) : ''); } @@ -2675,7 +2675,7 @@ class Contact } $update = false; - $guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], parse_url($ret['url'], PHP_URL_HOST)); + $guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url']); // make sure to not overwrite existing values with blank entries except some technical fields $keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl']; diff --git a/src/Model/Item.php b/src/Model/Item.php index ff4791a7cc..8b9909f8bf 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -2034,9 +2034,10 @@ class Item * Posts that are created on this system are using System::createUUID. * Received ActivityPub posts are using Processor::getGUIDByURL. * - * @param string $uri uri of an item entry + * @param string $uri uri of an item entry * @param string|null $host hostname for the GUID prefix * @return string Unique guid + * @throws \Exception */ public static function guidFromUri(string $uri, string $host = null): string { @@ -2047,11 +2048,16 @@ class Item // Remove the scheme to make sure that "https" and "http" doesn't make a difference unset($parsed['scheme']); + $hostPart = $host ?? $parsed['host'] ?? ''; + if (!$hostPart) { + Logger::warning('Empty host GUID part', ['uri' => $uri, 'host' => $host, 'parsed' => $parsed, 'callstack' => System::callstack(10)]); + } + // Glue it together to be able to make a hash from it $host_id = implode('/', $parsed); // Use a mixture of several hashes to provide some GUID like experience - return hash('crc32', $host) . '-'. hash('joaat', $host_id) . '-'. hash('fnv164', $host_id); + return hash('crc32', $hostPart) . '-' . hash('joaat', $host_id) . '-' . hash('fnv164', $host_id); } /** diff --git a/src/Model/Mail.php b/src/Model/Mail.php index 6ccce24ba7..9469483d9a 100644 --- a/src/Model/Mail.php +++ b/src/Model/Mail.php @@ -59,8 +59,7 @@ class Mail } if (empty($msg['guid'])) { - $host = parse_url($msg['from-url'], PHP_URL_HOST); - $msg['guid'] = Item::guidFromUri($msg['uri'], $host); + $msg['guid'] = Item::guidFromUri($msg['uri'], parse_url($msg['from-url'], PHP_URL_HOST)); } $msg['created'] = (!empty($msg['created']) ? DateTimeFormat::utc($msg['created']) : DateTimeFormat::utcNow()); diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php index 29b1923316..dec463820d 100644 --- a/src/Protocol/Feed.php +++ b/src/Protocol/Feed.php @@ -625,8 +625,8 @@ class Feed $notify = Item::isRemoteSelf($contact, $item); - // Distributed items should have a well formatted URI. - // Additionally we have to avoid conflicts with identical URI between imported feeds and these items. + // Distributed items should have a well-formatted URI. + // Additionally, we have to avoid conflicts with identical URI between imported feeds and these items. if ($notify) { $item['guid'] = Item::guidFromUri($orig_plink, DI::baseUrl()->getHostname()); $item['uri'] = Item::newURI($item['guid']); From f3dc69c226ea15f5ea5b1f1b470ee74c27313ef7 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:24:01 -0500 Subject: [PATCH 5/9] Ensure strpos is provided a string in App::runFrontend - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/App.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.php b/src/App.php index 25770dd782..0d4e8880dd 100644 --- a/src/App.php +++ b/src/App.php @@ -631,10 +631,10 @@ class App // ZRL if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) { - // Only continue when the given profile link seems valid + // Only continue when the given profile link seems valid. // Valid profile links contain a path with "/profile/" and no query parameters if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == '') && - strstr(parse_url($_GET['zrl'], PHP_URL_PATH), '/profile/')) { + strpos(parse_url($_GET['zrl'], PHP_URL_PATH) ?? '', '/profile/') !== false) { if ($this->session->get('visitor_home') != $_GET['zrl']) { $this->session->set('my_url', $_GET['zrl']); $this->session->set('authenticated', 0); From c70d657885351a780b222c784681104f7f1dc8c6 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:28:09 -0500 Subject: [PATCH 6/9] Ward against invalid name from receiver in ActivityPub::storeReceivers - Address part of https://github.com/friendica/friendica/issues/12011#issuecomment-1338133783 --- src/Protocol/ActivityPub/Processor.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 60a5c8d741..d098ddb691 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -1273,8 +1273,11 @@ class Processor foreach ($receivers[$element] as $receiver) { if ($receiver == ActivityPub::PUBLIC_COLLECTION) { $name = Receiver::PUBLIC_COLLECTION; + } elseif ($path = parse_url($receiver, PHP_URL_PATH)) { + $name = trim($path, '/'); } else { - $name = trim(parse_url($receiver, PHP_URL_PATH), '/'); + Logger::warning('Unable to coerce name from receiver', ['receiver' => $receiver]); + $name = ''; } $target = Tag::getTargetType($receiver); From b1860d412119ba6a3e4d3e5389651017f741e09a Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:31:27 -0500 Subject: [PATCH 7/9] Check for last-activity value before feeding it to strtotime in Module\NoScrape - Address https://github.com/friendica/friendica/issues/12011#issuecomment-1340019523 --- src/Module/NoScrape.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module/NoScrape.php b/src/Module/NoScrape.php index 8e5850ac0b..56f31f2dcf 100644 --- a/src/Module/NoScrape.php +++ b/src/Module/NoScrape.php @@ -94,7 +94,7 @@ class NoScrape extends BaseModule // We display the last activity (post or login), reduced to year and week number $last_active = strtotime($owner['last-item']); - if ($last_active < strtotime($owner['last-activity'])) { + if ($owner['last-activity'] && $last_active < strtotime($owner['last-activity'])) { $last_active = strtotime($owner['last-activity']); } $json_info['last-activity'] = date('o-W', $last_active); From 607d26e90676a8ab9a6a824aba9918753a61109d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 7 Dec 2022 22:35:37 -0500 Subject: [PATCH 8/9] Ward against empty JsonLD::fetchElement result in ActivityPub\Receiver::processTags - Address https://github.com/friendica/friendica/issues/12011#issuecomment-1336478368 --- src/Protocol/ActivityPub/Receiver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 4e2bcceafb..8939822742 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -209,7 +209,7 @@ class Receiver Logger::notice('No object data found', ['type' => $type, 'object_type' => $object_type, 'object_id' => $object_id, 'actor' => $actor, 'activity' => $activity]); return; } - + if (self::routeActivities($object_data, $type, true)) { Logger::debug('Handled activity', ['type' => $type, 'object_type' => $object_type, 'object_id' => $object_id, 'actor' => $actor]); } else { @@ -1472,7 +1472,7 @@ class Receiver continue; } - $element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type')), + $element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type') ?? ''), 'href' => JsonLD::fetchElement($tag, 'as:href', '@id'), 'name' => JsonLD::fetchElement($tag, 'as:name', '@value')]; From 7aa5407bbdc86a375d9c14f1ea7d3d82e9f8ea07 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 8 Dec 2022 08:51:49 -0500 Subject: [PATCH 9/9] Remove superfluous strlen call in Module\Tos - Address https://github.com/friendica/friendica/issues/12011#issuecomment-1342617099 --- src/Module/Tos.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module/Tos.php b/src/Module/Tos.php index 822aa8813b..11cecac44d 100644 --- a/src/Module/Tos.php +++ b/src/Module/Tos.php @@ -77,7 +77,7 @@ class Tos extends BaseModule */ protected function content(array $request = []): string { - if (strlen($this->config->get('system', 'singleuser'))) { + if ($this->config->get('system', 'singleuser')) { $this->baseUrl->redirect('profile/' . $this->config->get('system', 'singleuser')); }