Skip to content

Commit

Permalink
Fix an infinite loop when tapping an unjoined room alias.
Browse files Browse the repository at this point in the history
  • Loading branch information
pixlwave committed Aug 3, 2022
1 parent 6feca6b commit f398c7f
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 27 deletions.
21 changes: 6 additions & 15 deletions Riot/Modules/Application/LegacyAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -1296,8 +1296,6 @@ - (BOOL)handleUniversalLinkWithParameters:(UniversalLinkParameters*)universalLin
BOOL continueUserActivity = NO;
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];

MXLogDebug(@"[AppDelegate] Universal link: handleUniversalLinkFragment: %@", fragment);

// Make sure we have plain utf8 character for separators
fragment = [fragment stringByRemovingPercentEncoding];
MXLogDebug(@"[AppDelegate] Universal link: handleUniversalLinkFragment: %@", fragment);
Expand All @@ -1313,17 +1311,8 @@ - (BOOL)handleUniversalLinkWithParameters:(UniversalLinkParameters*)universalLin
// Sanity check
if (!pathParams.count)
{
// Handle simple room links with aliases/identifiers as UniversalLink will not parse these.
NSString* absoluteUrl = [universalLink.url.absoluteString stringByRemovingPercentEncoding];
if ([MXTools isMatrixRoomAlias:absoluteUrl]
|| [MXTools isMatrixRoomIdentifier:absoluteUrl])
{
pathParams = @[absoluteUrl];
}
else {
MXLogDebug(@"[AppDelegate] Universal link: Error: No path parameters");
return NO;
}
MXLogFailure(@"[AppDelegate] Universal link: Error: No path parameters");
return NO;
}

NSString *roomIdOrAlias;
Expand Down Expand Up @@ -1499,9 +1488,11 @@ - (BOOL)handleUniversalLinkWithParameters:(UniversalLinkParameters*)universalLin
if (newFragment && ![newFragment isEqualToString:fragment])
{
self->universalLinkFragmentPendingRoomAlias = @{resolution.roomId: roomIdOrAlias};


// Create a new link with the updated fragment, otherwise we loop back round resolving the room ID infinitely.
UniversalLink *newLink = [[UniversalLink alloc] initWithUrl:universalLink.url updatedFragment:newFragment];
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newFragment
universalLink:universalLink
universalLink:newLink
presentationParameters:presentationParameters];
[self handleUniversalLinkWithParameters:newParameters];
}
Expand Down
10 changes: 5 additions & 5 deletions Riot/Modules/Common/Recents/RecentsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -1602,11 +1602,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath

if (roomIdOrAlias.length)
{
// Open the room or preview it
NSString *fragment = [NSString stringWithFormat:@"/room/%@", [MXTools encodeURIComponent:roomIdOrAlias]];
NSURL *url = [NSURL URLWithString:[MXTools permalinkToRoom:fragment]];
UniversalLink *link = [[UniversalLink alloc] initWithUrl:url];
[[AppDelegate theDelegate] handleUniversalLinkFragment:fragment fromLink:link];
// Create a permalink to open or preview the room.
NSString *permalink = [MXTools permalinkToRoom:roomIdOrAlias];
NSURL *permalinkURL = [NSURL URLWithString:permalink];
UniversalLink *link = [[UniversalLink alloc] initWithUrl:permalinkURL];
[[AppDelegate theDelegate] handleUniversalLinkFragment:permalinkURL.fragment fromLink:link];
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
Expand Down
7 changes: 4 additions & 3 deletions Riot/Modules/Room/RoomViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -4279,10 +4279,11 @@ - (BOOL)dataSource:(MXKDataSource *)dataSource shouldDoAction:(NSString *)action

NSString *roomIdOrAlias = absoluteURLString;

// Open the room or preview it
NSString *fragment = [NSString stringWithFormat:@"/room/%@", [MXTools encodeURIComponent:roomIdOrAlias]];
// Create a permalink to open or preview the room.
NSString *permalink = [MXTools permalinkToRoom:roomIdOrAlias];
NSURL *permalinkURL = [NSURL URLWithString:permalink];

[self handleUniversalLinkFragment:fragment fromURL:url];
[self handleUniversalLinkFragment:permalinkURL.fragment fromURL:permalinkURL];
}
// Preview the clicked group
else if ([MXTools isMatrixGroupIdentifier:absoluteURLString])
Expand Down
5 changes: 5 additions & 0 deletions Riot/Utils/UniversalLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ NS_ASSUME_NONNULL_BEGIN
/// @param url original url
- (id)initWithUrl:(NSURL *)url;

/// An Initializer that preserves the original URL, but parses the parameters from an updated fragment.
/// @param url original url
/// @param fragment the updated fragment to parse.
- (id)initWithUrl:(NSURL *)url updatedFragment:(NSString *)fragment;

@end

NS_ASSUME_NONNULL_END
23 changes: 19 additions & 4 deletions Riot/Utils/UniversalLink.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,22 @@ - (id)initWithUrl:(NSURL *)url
_url = url;

// Extract required parameters from the link
[self parsePathAndQueryParams];
[self parsePathAndQueryParamsForURL:url];
}
return self;
}

- (id)initWithUrl:(NSURL *)url updatedFragment:(NSString *)fragment
{
self = [super init];
if (self)
{
_url = url;

// Update the url with the fragment
NSURLComponents *components = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];
components.fragment = fragment;
[self parsePathAndQueryParamsForURL:components.URL];
}
return self;
}
Expand All @@ -38,12 +53,12 @@ Extract params from the URL fragment part (after '#') of a vector.im Universal l
The fragment can contain a '?'. So there are two kinds of parameters: path params and query params.
It is in the form of /[pathParam1]/[pathParam2]?[queryParam1Key]=[queryParam1Value]&[queryParam2Key]=[queryParam2Value]
*/
- (void)parsePathAndQueryParams
- (void)parsePathAndQueryParamsForURL:(NSURL *)url
{
NSArray<NSString*> *pathParams;
NSMutableDictionary *queryParams = [NSMutableDictionary dictionary];

NSArray<NSString*> *fragments = [_url.fragment componentsSeparatedByString:@"?"];
NSArray<NSString*> *fragments = [url.fragment componentsSeparatedByString:@"?"];

// Extract path params
pathParams = [[fragments[0] stringByRemovingPercentEncoding] componentsSeparatedByString:@"/"];
Expand All @@ -57,7 +72,7 @@ - (void)parsePathAndQueryParams
}];

// Extract query params
NSURLComponents *components = [NSURLComponents componentsWithURL:_url resolvingAgainstBaseURL:NO];
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
for (NSURLQueryItem *item in components.queryItems)
{
if (item.value)
Expand Down
1 change: 1 addition & 0 deletions changelog.d/6492.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Universal Links: Fix an infinite loop when handling a universal link for an unjoined room (or in some cases a crash).

0 comments on commit f398c7f

Please sign in to comment.