diff --git a/mod/lockview.php b/mod/lockview.php index af57730c8a..9f9dcfea42 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -64,10 +64,10 @@ function lockview_content(App $a) /** @var ACLFormatter $aclFormatter */ $aclFormatter = BaseObject::getClass(ACLFormatter::class); - $allowed_users = $aclFormatter->expand($item['allow_cid'] ?? ''); - $allowed_groups = $aclFormatter->expand($item['allow_gid'] ?? ''); - $deny_users = $aclFormatter->expand($item['deny_cid'] ?? ''); - $deny_groups = $aclFormatter->expand($item['deny_gid'] ?? ''); + $allowed_users = $aclFormatter->expand($item['allow_cid']); + $allowed_groups = $aclFormatter->expand($item['allow_gid']); + $deny_users = $aclFormatter->expand($item['deny_cid']); + $deny_groups = $aclFormatter->expand($item['deny_gid']); $o = L10n::t('Visible to:') . '
'; $l = []; diff --git a/src/Model/Item.php b/src/Model/Item.php index e298cc1605..9501c8e5d2 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -2904,10 +2904,10 @@ class Item extends BaseObject /** @var ACLFormatter $aclFormater */ $aclFormater = self::getClass(ACLFormatter::class); - $allow_people = $aclFormater->expand($obj['allow_cid'] ?? ''); - $allow_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['allow_gid'] ?? ''), $check_dead); - $deny_people = $aclFormater->expand($obj['deny_cid'] ?? ''); - $deny_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['deny_gid'] ?? ''), $check_dead); + $allow_people = $aclFormater->expand($obj['allow_cid']); + $allow_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['allow_gid']), $check_dead); + $deny_people = $aclFormater->expand($obj['deny_cid']); + $deny_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['deny_gid']), $check_dead); $recipients = array_unique(array_merge($allow_people, $allow_groups)); $deny = array_unique(array_merge($deny_people, $deny_groups)); $recipients = array_diff($recipients, $deny); diff --git a/src/Module/Item/Compose.php b/src/Module/Item/Compose.php index 0d3b4eaac2..c44e4c61ab 100644 --- a/src/Module/Item/Compose.php +++ b/src/Module/Item/Compose.php @@ -74,8 +74,8 @@ class Compose extends BaseModule $compose_title = L10n::t('Compose new post'); $type = 'post'; $doesFederate = true; - $contact_allow = implode(',', $aclFormatter->expand($user['allow_cid'] ?? '')); - $group_allow = implode(',', $aclFormatter->expand($user['allow_gid'] ?? '')) ?: Group::FOLLOWERS; + $contact_allow = implode(',', $aclFormatter->expand($user['allow_cid'])); + $group_allow = implode(',', $aclFormatter->expand($user['allow_gid'])) ?: Group::FOLLOWERS; break; } @@ -86,8 +86,8 @@ class Compose extends BaseModule $wall = $_REQUEST['wall'] ?? $type == 'post'; $contact_allow = $_REQUEST['contact_allow'] ?? $contact_allow; $group_allow = $_REQUEST['group_allow'] ?? $group_allow; - $contact_deny = $_REQUEST['contact_deny'] ?? implode(',', $aclFormatter->expand($user['deny_cid'] ?? '')); - $group_deny = $_REQUEST['group_deny'] ?? implode(',', $aclFormatter->expand($user['deny_gid'] ?? '')); + $contact_deny = $_REQUEST['contact_deny'] ?? implode(',', $aclFormatter->expand($user['deny_cid'])); + $group_deny = $_REQUEST['group_deny'] ?? implode(',', $aclFormatter->expand($user['deny_gid'])); $visibility = ($contact_allow . $user['allow_gid'] . $user['deny_cid'] . $user['deny_gid']) ? 'custom' : 'public'; $acl_contacts = Contact::selectToArray(['id', 'name', 'addr', 'micro'], ['uid' => local_user(), 'pending' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]); diff --git a/src/Util/ACLFormatter.php b/src/Util/ACLFormatter.php index 4a36f3ebf2..d194e2e67e 100644 --- a/src/Util/ACLFormatter.php +++ b/src/Util/ACLFormatter.php @@ -12,12 +12,17 @@ final class ACLFormatter /** * Turn user/group ACLs stored as angle bracketed text into arrays * - * @param string $ids A angle-bracketed list of IDs + * @param string|null $ids A angle-bracketed list of IDs * - * @return array The array based on the IDs + * @return array|null The array based on the IDs (null in case there is no list) */ - public function expand(string $ids) + public function expand(string $ids = null) { + // In case there is no ID list, return null (=> no ACL set) + if (!isset($ids)) { + return null; + } + // turn string array of angle-bracketed elements into numeric array // e.g. "<1><2><3>" => array(1,2,3); preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $ids, $matches, PREG_PATTERN_ORDER); @@ -31,12 +36,18 @@ final class ACLFormatter * @param string $item The item to sanitise */ private function sanitize(string &$item) { + // The item is an ACL int value if (intval($item)) { $item = '<' . intval(Strings::escapeTags(trim($item))) . '>'; + // The item is a allowed ACL character } elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) { $item = '<' . $item . '>'; - } else { + // The item is already a ACL string + } elseif (preg_match('/<\d+?>/', $item)) { unset($item); + // The item is not supported, so remove it (cleanup) + } else { + $item = ''; } } diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 9ab07e6d49..8b6be76b50 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -279,10 +279,10 @@ class Notifier /** @var ACLFormatter $aclFormatter */ $aclFormatter = BaseObject::getClass(ACLFormatter::class); - $allow_people = $aclFormatter->expand($parent['allow_cid'] ?? ''); - $allow_groups = Group::expand($uid, $aclFormatter->expand($parent['allow_gid'] ?? ''),true); - $deny_people = $aclFormatter->expand($parent['deny_cid'] ?? ''); - $deny_groups = Group::expand($uid, $aclFormatter->expand($parent['deny_gid'] ?? '')); + $allow_people = $aclFormatter->expand($parent['allow_cid']); + $allow_groups = Group::expand($uid, $aclFormatter->expand($parent['allow_gid']),true); + $deny_people = $aclFormatter->expand($parent['deny_cid']); + $deny_groups = Group::expand($uid, $aclFormatter->expand($parent['deny_gid'])); // if our parent is a public forum (forum_mode == 1), uplink to the origional author causing // a delivery fork. private groups (forum_mode == 2) do not uplink diff --git a/tests/src/Util/ACLFormaterTest.php b/tests/src/Util/ACLFormaterTest.php index ac5b25e6c2..630a30e40b 100644 --- a/tests/src/Util/ACLFormaterTest.php +++ b/tests/src/Util/ACLFormaterTest.php @@ -164,15 +164,14 @@ class ACLFormaterTest extends TestCase } /** - * Test expected exception in case of wrong typehint - * - * @expectedException Error + * Test nullable expand (=> no ACL set) */ public function testExpandNull() { $aclFormatter = new ACLFormatter(); - $aclFormatter->expand(null); + $this->assertNull($aclFormatter->expand(null)); + $this->assertNull($aclFormatter->expand()); } public function dataAclToString() @@ -198,6 +197,23 @@ class ACLFormaterTest extends TestCase 'input' => 'a,bsd23,4', 'assert' => '<4>', ], + /** @see https://github.com/friendica/friendica/pull/7787 */ + 'bug-7778-angle-brackets' => [ + 'input' => ["<40195>"], + 'assert' => "<40195>", + ], + Group::FOLLOWERS => [ + 'input' => [Group::FOLLOWERS, 1], + 'assert' => '<' . Group::FOLLOWERS . '><1>', + ], + Group::MUTUALS => [ + 'input' => [Group::MUTUALS, 1], + 'assert' => '<' . Group::MUTUALS . '><1>', + ], + 'wrong-angle-brackets' => [ + 'input' => ["","<123>"], + 'assert' => "<123>", + ], ]; }