Handle emoji with non-ASCII URL paths

This commit is contained in:
Justin Mazzocchi 2021-02-27 13:29:30 -08:00
parent 014278f855
commit 5038b2dcfa
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
5 changed files with 31 additions and 10 deletions

View file

@ -17,9 +17,9 @@ extension NSMutableAttributedString {
if !identityContext.appPreferences.shouldReduceMotion, if !identityContext.appPreferences.shouldReduceMotion,
identityContext.appPreferences.animateCustomEmojis, identityContext.appPreferences.animateCustomEmojis,
let urlString = emoji.url { let urlString = emoji.url {
imageURL = URL(string: urlString) imageURL = URL(stringEscapingPath: urlString)
} else if let staticURLString = emoji.staticUrl { } else if let staticURLString = emoji.staticUrl {
imageURL = URL(string: staticURLString) imageURL = URL(stringEscapingPath: staticURLString)
} else { } else {
imageURL = nil imageURL = nil
} }

View file

@ -8,6 +8,18 @@ extension URL {
return scheme == "http" || scheme == "https" return scheme == "http" || scheme == "https"
} }
init?(stringEscapingPath: String) {
guard let pathEscaped = stringEscapingPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
else { return nil }
let httpsColonUnescaped = pathEscaped.replacingOccurrences(
of: "https%3A",
with: "https:",
range: pathEscaped.range(of: "https%3A"))
self.init(string: httpsColonUnescaped)
}
} }
extension URL: Identifiable { extension URL: Identifiable {

View file

@ -65,6 +65,7 @@
D04F34BC25E42ADC00714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34BB25E42ADC00714251 /* SDWebImage */; }; D04F34BC25E42ADC00714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34BB25E42ADC00714251 /* SDWebImage */; };
D04F34C225E42AE500714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34C125E42AE500714251 /* SDWebImage */; }; D04F34C225E42AE500714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34C125E42AE500714251 /* SDWebImage */; };
D04F9E8E259E9C950081B0C9 /* ViewModels in Frameworks */ = {isa = PBXBuildFile; productRef = D04F9E8D259E9C950081B0C9 /* ViewModels */; }; D04F9E8E259E9C950081B0C9 /* ViewModels in Frameworks */ = {isa = PBXBuildFile; productRef = D04F9E8D259E9C950081B0C9 /* ViewModels */; };
D052DBDD25EAF01800FFB628 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; };
D05936CF25A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; }; D05936CF25A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; };
D05936D025A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; }; D05936D025A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; };
D05936DE25A937EC00754FDF /* EditThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936DD25A937EC00754FDF /* EditThumbnailView.swift */; }; D05936DE25A937EC00754FDF /* EditThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936DD25A937EC00754FDF /* EditThumbnailView.swift */; };
@ -1193,6 +1194,7 @@
D0D93EC525D9C75E00C622ED /* AutocompleteItemContentConfiguration.swift in Sources */, D0D93EC525D9C75E00C622ED /* AutocompleteItemContentConfiguration.swift in Sources */,
D059373425AAEA7000754FDF /* CompositionPollView.swift in Sources */, D059373425AAEA7000754FDF /* CompositionPollView.swift in Sources */,
D021A67B25C3E32A008A0C0D /* PlayerView.swift in Sources */, D021A67B25C3E32A008A0C0D /* PlayerView.swift in Sources */,
D052DBDD25EAF01800FFB628 /* URL+Extensions.swift in Sources */,
D021A69025C3E4B8008A0C0D /* EmojiContentConfiguration.swift in Sources */, D021A69025C3E4B8008A0C0D /* EmojiContentConfiguration.swift in Sources */,
D08E52D2257C811200FA2C5F /* ShareExtensionError+Extensions.swift in Sources */, D08E52D2257C811200FA2C5F /* ShareExtensionError+Extensions.swift in Sources */,
D00CB23D25C9305D008EF267 /* NSMutableAttributedString+Extensions.swift in Sources */, D00CB23D25C9305D008EF267 /* NSMutableAttributedString+Extensions.swift in Sources */,

View file

@ -18,15 +18,13 @@ public extension EmojiViewModel {
var system: Bool { emoji.system } var system: Bool { emoji.system }
var url: URL? { var url: String? {
guard case let .custom(emoji, _) = emoji else { return nil } guard case let .custom(emoji, _) = emoji else { return nil }
if identityContext.appPreferences.animateCustomEmojis, let urlString = emoji.url { if identityContext.appPreferences.animateCustomEmojis {
return URL(string: urlString) return emoji.url
} else if let staticURLString = emoji.staticUrl { } else {
return URL(string: staticURLString) return emoji.staticUrl
} }
return nil
} }
} }

View file

@ -76,7 +76,16 @@ private extension EmojiView {
emojiLabel.isHidden = true emojiLabel.isHidden = true
emojiLabel.text = nil emojiLabel.text = nil
imageView.isHidden = false imageView.isHidden = false
imageView.sd_setImage(with: emojiConfiguration.viewModel.url)
let url: URL?
if let urlString = emojiConfiguration.viewModel.url {
url = URL(stringEscapingPath: urlString)
} else {
url = nil
}
imageView.sd_setImage(with: url)
} }
accessibilityLabel = emojiConfiguration.viewModel.name accessibilityLabel = emojiConfiguration.viewModel.name