From 51529a7ebfb3305a5d3d95e4a77df90fae60688d Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Sun, 31 Jan 2021 13:59:26 -0800 Subject: [PATCH] Guard against invalid URLs --- DB/Sources/DB/Content/AccountRecord.swift | 2 +- DB/Sources/DB/Content/StatusRecord.swift | 2 +- DB/Sources/DB/Entities/Identity.swift | 6 +++--- Mastodon/Sources/Mastodon/Entities/Account.swift | 4 ++-- Mastodon/Sources/Mastodon/Entities/Status.swift | 4 ++-- .../Sources/ServiceLayer/Services/AccountService.swift | 4 ++-- .../ViewModels/View Models/ReportViewModel.swift | 2 +- .../ViewModels/View Models/StatusViewModel.swift | 10 ++++++++-- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/DB/Sources/DB/Content/AccountRecord.swift b/DB/Sources/DB/Content/AccountRecord.swift index 2c1adcb..d827a5b 100644 --- a/DB/Sources/DB/Content/AccountRecord.swift +++ b/DB/Sources/DB/Content/AccountRecord.swift @@ -15,7 +15,7 @@ struct AccountRecord: ContentDatabaseRecord, Hashable { let followingCount: Int let statusesCount: Int let note: HTML - let url: URL + let url: String let avatar: URL let avatarStatic: URL let header: URL diff --git a/DB/Sources/DB/Content/StatusRecord.swift b/DB/Sources/DB/Content/StatusRecord.swift index be8acbb..2e9109e 100644 --- a/DB/Sources/DB/Content/StatusRecord.swift +++ b/DB/Sources/DB/Content/StatusRecord.swift @@ -21,7 +21,7 @@ struct StatusRecord: ContentDatabaseRecord, Hashable { let favouritesCount: Int let repliesCount: Int let application: Application? - let url: URL? + let url: String? let inReplyToId: Status.Id? let inReplyToAccountId: Account.Id? let reblogId: Status.Id? diff --git a/DB/Sources/DB/Entities/Identity.swift b/DB/Sources/DB/Entities/Identity.swift index 97b2d34..7f0a583 100644 --- a/DB/Sources/DB/Entities/Identity.swift +++ b/DB/Sources/DB/Entities/Identity.swift @@ -33,7 +33,7 @@ public extension Identity { public let identityId: Identity.Id public let username: String public let displayName: String - public let url: URL + public let url: String public let avatar: URL public let avatarStatic: URL public let header: URL @@ -52,8 +52,8 @@ public extension Identity { } var handle: String { - if let account = account, let host = account.url.host { - return account.url.lastPathComponent.appending("@").appending(host) + if let urlString = account?.url, let url = URL(string: urlString), let host = url.host { + return url.lastPathComponent.appending("@").appending(host) } return instance?.title ?? url.host ?? url.absoluteString diff --git a/Mastodon/Sources/Mastodon/Entities/Account.swift b/Mastodon/Sources/Mastodon/Entities/Account.swift index 0d43455..f1c5b7d 100644 --- a/Mastodon/Sources/Mastodon/Entities/Account.swift +++ b/Mastodon/Sources/Mastodon/Entities/Account.swift @@ -13,7 +13,7 @@ public final class Account: Codable, Identifiable { public let followingCount: Int public let statusesCount: Int public let note: HTML - public let url: URL + public let url: String public let avatar: URL public let avatarStatic: URL public let header: URL @@ -35,7 +35,7 @@ public final class Account: Codable, Identifiable { followingCount: Int, statusesCount: Int, note: HTML, - url: URL, + url: String, avatar: URL, avatarStatic: URL, header: URL, diff --git a/Mastodon/Sources/Mastodon/Entities/Status.swift b/Mastodon/Sources/Mastodon/Entities/Status.swift index 6e8f3fe..99ace95 100644 --- a/Mastodon/Sources/Mastodon/Entities/Status.swift +++ b/Mastodon/Sources/Mastodon/Entities/Status.swift @@ -29,7 +29,7 @@ public final class Status: Codable, Identifiable { public let favouritesCount: Int @DecodableDefault.Zero public private(set) var repliesCount: Int public let application: Application? - public let url: URL? + public let url: String? public let inReplyToId: Status.Id? public let inReplyToAccountId: Account.Id? public let reblog: Status? @@ -60,7 +60,7 @@ public final class Status: Codable, Identifiable { favouritesCount: Int, repliesCount: Int, application: Application?, - url: URL?, + url: String?, inReplyToId: Status.Id?, inReplyToAccountId: Account.Id?, reblog: Status?, diff --git a/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift b/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift index 24afeba..0523d8d 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/AccountService.swift @@ -34,10 +34,10 @@ public struct AccountService { public extension AccountService { var isLocal: Bool { - account.url.host == mastodonAPIClient.instanceURL.host + URL(string: account.url)?.host == mastodonAPIClient.instanceURL.host } - var domain: String? { account.url.host } + var domain: String? { URL(string: account.url)?.host } func follow() -> AnyPublisher { relationshipAction(.accountsFollow(id: account.id)) diff --git a/ViewModels/Sources/ViewModels/View Models/ReportViewModel.swift b/ViewModels/Sources/ViewModels/View Models/ReportViewModel.swift index a79f12a..62c76c9 100644 --- a/ViewModels/Sources/ViewModels/View Models/ReportViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/ReportViewModel.swift @@ -38,7 +38,7 @@ public extension ReportViewModel { var accountName: String { "@".appending(accountService.account.acct) } var accountHost: String { - accountService.account.url.host ?? "" + URL(string: accountService.account.url)?.host ?? "" } var isLocalAccount: Bool { accountService.isLocal } diff --git a/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift b/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift index 7add244..c48399b 100644 --- a/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/StatusViewModel.swift @@ -121,7 +121,11 @@ public extension StatusViewModel { var muted: Bool { statusService.status.displayStatus.muted } - var sharingURL: URL? { statusService.status.displayStatus.url } + var sharingURL: URL? { + guard let urlString = statusService.status.displayStatus.url else { return nil } + + return URL(string: urlString) + } var isPollExpired: Bool { statusService.status.displayStatus.poll?.expired ?? true } @@ -297,7 +301,9 @@ public extension StatusViewModel { } func shareStatus() { - guard let url = statusService.status.displayStatus.url else { return } + guard let urlString = statusService.status.displayStatus.url, + let url = URL(string: urlString) + else { return } eventsSubject.send(Just(.share(url)).setFailureType(to: Error.self).eraseToAnyPublisher()) }