mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Don't read "PIC" tags as they might be too large
This commit is contained in:
parent
1eb0916e25
commit
47c4ab17a3
@ -1229,6 +1229,9 @@ final class SharedApplicationContext {
|
||||
extendNow = true
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
extendNow = false
|
||||
#endif
|
||||
sharedApplicationContext.wakeupManager.allowBackgroundTimeExtension(timeout: 4.0, extendNow: extendNow)
|
||||
})
|
||||
|
||||
@ -1300,7 +1303,20 @@ final class SharedApplicationContext {
|
||||
}
|
||||
|
||||
Logger.shared.log("App \(self.episodeId)", "remoteNotification: \(redactedPayload)")
|
||||
completionHandler(UIBackgroundFetchResult.noData)
|
||||
|
||||
if userInfo["p"] == nil {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (self.sharedContextPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { sharedApplicationContext in
|
||||
|
||||
sharedApplicationContext.wakeupManager.replaceCurrentExtensionWithExternalTime(completion: {
|
||||
completionHandler(.newData)
|
||||
}, timeout: 29.0)
|
||||
sharedApplicationContext.notificationManager.addNotification(userInfo)
|
||||
})
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
|
||||
@ -1325,261 +1341,11 @@ final class SharedApplicationContext {
|
||||
|
||||
if case PKPushType.voIP = type {
|
||||
Logger.shared.log("App \(self.episodeId)", "pushRegistry payload: \(payload.dictionaryPayload)")
|
||||
sharedApplicationContext.notificationManager.addEncryptedNotification(payload.dictionaryPayload)
|
||||
sharedApplicationContext.notificationManager.addNotification(payload.dictionaryPayload)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*private func processPushPayload(_ payload: [AnyHashable: Any], account: Account) {
|
||||
let decryptedPayload: Signal<[AnyHashable: Any]?, NoError>
|
||||
if let _ = payload["aps"] as? [AnyHashable: Any] {
|
||||
decryptedPayload = .single(payload)
|
||||
} else if var encryptedPayload = payload["p"] as? String {
|
||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+")
|
||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/")
|
||||
while encryptedPayload.count % 4 != 0 {
|
||||
encryptedPayload.append("=")
|
||||
}
|
||||
if let data = Data(base64Encoded: encryptedPayload) {
|
||||
decryptedPayload = decryptedNotificationPayload(account: account, data: data)
|
||||
|> map { value -> [AnyHashable: Any]? in
|
||||
if let value = value, let object = try? JSONSerialization.jsonObject(with: value, options: []) {
|
||||
return object as? [AnyHashable: Any]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
decryptedPayload = .single(nil)
|
||||
}
|
||||
} else {
|
||||
decryptedPayload = .single(nil)
|
||||
}
|
||||
|
||||
let _ = (decryptedPayload
|
||||
|> deliverOnMainQueue).start(next: { payload in
|
||||
guard let payload = payload else {
|
||||
return
|
||||
}
|
||||
|
||||
var redactedPayload = payload
|
||||
if var aps = redactedPayload["aps"] as? [AnyHashable: Any] {
|
||||
if Logger.shared.redactSensitiveData {
|
||||
if aps["alert"] != nil {
|
||||
aps["alert"] = "[[redacted]]"
|
||||
}
|
||||
if aps["body"] != nil {
|
||||
aps["body"] = "[[redacted]]"
|
||||
}
|
||||
}
|
||||
redactedPayload["aps"] = aps
|
||||
}
|
||||
Logger.shared.log("Apns \(self.episodeId)", "\(redactedPayload)")
|
||||
|
||||
let aps = payload["aps"] as? [AnyHashable: Any]
|
||||
|
||||
if UIApplication.shared.applicationState == .background {
|
||||
var readMessageId: MessageId?
|
||||
var isCall = false
|
||||
var isAnnouncement = false
|
||||
var isLocationPolling = false
|
||||
var isMutePolling = false
|
||||
var title: String = ""
|
||||
var body: String?
|
||||
var apnsSound: String?
|
||||
var configurationUpdate: (Int32, String, Int32, Data?)?
|
||||
if let aps = aps, let alert = aps["alert"] as? String {
|
||||
if let range = alert.range(of: ": ") {
|
||||
title = String(alert[..<range.lowerBound])
|
||||
body = String(alert[range.upperBound...])
|
||||
} else {
|
||||
body = alert
|
||||
}
|
||||
} else if let aps = aps, let alert = aps["alert"] as? [AnyHashable: AnyObject] {
|
||||
if let alertBody = alert["body"] as? String {
|
||||
body = alertBody
|
||||
if let alertTitle = alert["title"] as? String {
|
||||
title = alertTitle
|
||||
}
|
||||
}
|
||||
if let locKey = alert["loc-key"] as? String {
|
||||
if locKey == "PHONE_CALL_REQUEST" {
|
||||
isCall = true
|
||||
} else if locKey == "GEO_LIVE_PENDING" {
|
||||
isLocationPolling = true
|
||||
} else if locKey == "MESSAGE_MUTED" {
|
||||
isMutePolling = true
|
||||
}
|
||||
let string = NSLocalizedString(locKey, comment: "")
|
||||
if !string.isEmpty {
|
||||
if let locArgs = alert["loc-args"] as? [AnyObject] {
|
||||
var args: [CVarArg] = []
|
||||
var failed = false
|
||||
for arg in locArgs {
|
||||
if let arg = arg as? CVarArg {
|
||||
args.append(arg)
|
||||
} else {
|
||||
failed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if failed {
|
||||
body = "\(string)"
|
||||
} else {
|
||||
body = String(format: string, arguments: args)
|
||||
}
|
||||
} else {
|
||||
body = "\(string)"
|
||||
}
|
||||
} else {
|
||||
body = nil
|
||||
}
|
||||
} else {
|
||||
body = nil
|
||||
}
|
||||
}
|
||||
|
||||
if let aps = aps, let address = aps["addr"] as? String, let datacenterId = aps["dc"] as? Int {
|
||||
var host = address
|
||||
var port: Int32 = 443
|
||||
if let range = address.range(of: ":") {
|
||||
host = String(address[address.startIndex ..< range.lowerBound])
|
||||
if let portValue = Int(String(address[range.upperBound...])) {
|
||||
port = Int32(portValue)
|
||||
}
|
||||
}
|
||||
var secret: Data?
|
||||
if let secretString = aps["sec"] as? String {
|
||||
let data = dataWithHexString(secretString)
|
||||
if data.count == 16 || data.count == 32 {
|
||||
secret = data
|
||||
}
|
||||
}
|
||||
configurationUpdate = (Int32(datacenterId), host, port, secret)
|
||||
}
|
||||
|
||||
if let aps = aps, let sound = aps["sound"] as? String {
|
||||
apnsSound = sound
|
||||
}
|
||||
|
||||
if payload["call_id"] != nil {
|
||||
isCall = true
|
||||
}
|
||||
|
||||
if payload["announcement"] != nil {
|
||||
isAnnouncement = true
|
||||
}
|
||||
|
||||
if let body = body {
|
||||
if isAnnouncement {
|
||||
self.queuedAnnouncements.append(body)
|
||||
self.maybeDequeueAnnouncements()
|
||||
} else {
|
||||
var peerId: PeerId?
|
||||
var notificationRequestId: NotificationManagedNotificationRequestId?
|
||||
|
||||
if let fromId = payload["from_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
||||
} else if let fromId = payload["chat_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: Int32(fromIdValue.intValue))
|
||||
} else if let fromId = payload["channel_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: Int32(fromIdValue.intValue))
|
||||
}
|
||||
|
||||
if let msgId = payload["msg_id"] {
|
||||
let msgIdValue = msgId as! NSString
|
||||
if let peerId = peerId {
|
||||
notificationRequestId = .messageId(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(msgIdValue.intValue)))
|
||||
}
|
||||
} else if let randomId = payload["random_id"] {
|
||||
let randomIdValue = randomId as! NSString
|
||||
var peerId: PeerId?
|
||||
if let encryptionIdString = payload["encryption_id"] as? String, let encryptionId = Int32(encryptionIdString) {
|
||||
peerId = PeerId(namespace: Namespaces.Peer.SecretChat, id: encryptionId)
|
||||
}
|
||||
notificationRequestId = .globallyUniqueId(randomIdValue.longLongValue, peerId)
|
||||
} else {
|
||||
isMutePolling = true
|
||||
}
|
||||
|
||||
if let notificationRequestId = notificationRequestId {
|
||||
self.queuedNotificationRequests.append((title, body, apnsSound, notificationRequestId))
|
||||
self.maybeDequeueNotificationRequests()
|
||||
} else if isMutePolling {
|
||||
self.queuedMutePolling = true
|
||||
self.maybeDequeueNotificationRequests()
|
||||
}
|
||||
}
|
||||
} else if let _ = payload["max_id"] {
|
||||
var peerId: PeerId?
|
||||
|
||||
if let fromId = payload["from_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
||||
} else if let fromId = payload["chat_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: Int32(fromIdValue.intValue))
|
||||
} else if let fromId = payload["channel_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: Int32(fromIdValue.intValue))
|
||||
}
|
||||
|
||||
if let peerId = peerId {
|
||||
if let msgId = payload["max_id"] {
|
||||
let msgIdValue = msgId as! NSString
|
||||
if msgIdValue.intValue != 0 {
|
||||
readMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(msgIdValue.intValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var addedWakeups = Set<QueuedWakeup>()
|
||||
if isCall {
|
||||
addedWakeups.insert(.call)
|
||||
}
|
||||
if isLocationPolling {
|
||||
addedWakeups.insert(.backgroundLocation)
|
||||
}
|
||||
if !addedWakeups.isEmpty {
|
||||
self.queuedWakeups.formUnion(addedWakeups)
|
||||
self.maybeDequeueWakeups()
|
||||
}
|
||||
if let readMessageId = readMessageId {
|
||||
self.clearNotificationsManager?.append(readMessageId)
|
||||
self.clearNotificationsManager?.commitNow()
|
||||
|
||||
let signal = self.context.get()
|
||||
|> take(1)
|
||||
|> mapToSignal { context -> Signal<Void, NoError> in
|
||||
if let context = context {
|
||||
return context.context.account.postbox.transaction (ignoreDisabled: true, { transaction -> Void in
|
||||
transaction.applyIncomingReadMaxId(readMessageId)
|
||||
})
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
let _ = signal.start()
|
||||
}
|
||||
|
||||
if let (datacenterId, host, port, secret) = configurationUpdate {
|
||||
let signal = self.context.get()
|
||||
|> take(1)
|
||||
|> mapToSignal { context -> Signal<Void, NoError> in
|
||||
if let context = context {
|
||||
context.context.account.network.mergeBackupDatacenterAddress(datacenterId: datacenterId, host: host, port: port, secret: secret)
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
let _ = signal.start()
|
||||
}
|
||||
}
|
||||
})
|
||||
}*/
|
||||
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
|
||||
Logger.shared.log("App \(self.episodeId)", "invalidated token for \(type)")
|
||||
}
|
||||
|
@ -21,6 +21,14 @@ private final class PollStateContext {
|
||||
}
|
||||
}
|
||||
|
||||
private final class NotificationInfo {
|
||||
let dict: [AnyHashable: Any]
|
||||
|
||||
init(dict: [AnyHashable: Any]) {
|
||||
self.dict = dict
|
||||
}
|
||||
}
|
||||
|
||||
public final class SharedNotificationManager {
|
||||
private let episodeId: UInt32
|
||||
private let application: UIApplication
|
||||
@ -35,7 +43,7 @@ public final class SharedNotificationManager {
|
||||
private var accountsAndKeys: [(Account, Bool, MasterNotificationKey)]?
|
||||
private var accountsAndKeysDisposable: Disposable?
|
||||
|
||||
private var encryptedNotifications: [[AnyHashable: Any]] = []
|
||||
private var notifications: [NotificationInfo] = []
|
||||
|
||||
private var pollStateContexts: [AccountRecordId: PollStateContext] = [:]
|
||||
|
||||
@ -149,8 +157,8 @@ public final class SharedNotificationManager {
|
||||
}
|
||||
}
|
||||
|
||||
func addEncryptedNotification(_ dict: [AnyHashable: Any]) {
|
||||
self.encryptedNotifications.append(dict)
|
||||
func addNotification(_ dict: [AnyHashable: Any]) {
|
||||
self.notifications.append(NotificationInfo(dict: dict))
|
||||
|
||||
if self.accountsAndKeys != nil {
|
||||
self.process()
|
||||
@ -162,8 +170,8 @@ public final class SharedNotificationManager {
|
||||
return
|
||||
}
|
||||
var decryptedNotifications: [(Account, Bool, [AnyHashable: Any])] = []
|
||||
for dict in self.encryptedNotifications {
|
||||
if var encryptedPayload = dict["p"] as? String {
|
||||
for notification in self.notifications {
|
||||
if var encryptedPayload = notification.dict["p"] as? String {
|
||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+")
|
||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/")
|
||||
while encryptedPayload.count % 4 != 0 {
|
||||
@ -181,7 +189,7 @@ public final class SharedNotificationManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.encryptedNotifications.removeAll()
|
||||
self.notifications.removeAll()
|
||||
|
||||
for (account, isCurrent, payload) in decryptedNotifications {
|
||||
var redactedPayload = payload
|
||||
@ -206,7 +214,7 @@ public final class SharedNotificationManager {
|
||||
var isAnnouncement = false
|
||||
var isLocationPolling = false
|
||||
var notificationRequestId: NotificationManagedNotificationRequestId?
|
||||
var isMutePolling = false
|
||||
var shouldPollState = false
|
||||
var title: String = ""
|
||||
var body: String?
|
||||
var apnsSound: String?
|
||||
@ -234,7 +242,7 @@ public final class SharedNotificationManager {
|
||||
} else if locKey == "GEO_LIVE_PENDING" {
|
||||
isLocationPolling = true
|
||||
} else if locKey == "MESSAGE_MUTED" {
|
||||
isMutePolling = true
|
||||
shouldPollState = true
|
||||
} else if locKey == "MESSAGE_DELETED" {
|
||||
var peerId: PeerId?
|
||||
if let fromId = payload["from_id"] {
|
||||
@ -281,8 +289,6 @@ public final class SharedNotificationManager {
|
||||
} else {
|
||||
body = nil
|
||||
}
|
||||
} else {
|
||||
body = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,6 +332,8 @@ public final class SharedNotificationManager {
|
||||
} else {
|
||||
var peerId: PeerId?
|
||||
|
||||
shouldPollState = true
|
||||
|
||||
if let fromId = payload["from_id"] {
|
||||
let fromIdValue = fromId as! NSString
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
||||
@ -350,7 +358,7 @@ public final class SharedNotificationManager {
|
||||
}
|
||||
notificationRequestId = .globallyUniqueId(randomIdValue.longLongValue, peerId)
|
||||
} else {
|
||||
isMutePolling = true
|
||||
shouldPollState = true
|
||||
}
|
||||
}
|
||||
} else if let _ = payload["max_id"] {
|
||||
@ -386,7 +394,7 @@ public final class SharedNotificationManager {
|
||||
return
|
||||
}
|
||||
|
||||
if notificationRequestId != nil || isMutePolling || isCall {
|
||||
if notificationRequestId != nil || shouldPollState || isCall {
|
||||
if !self.inForeground || !isCurrent {
|
||||
self.beginPollingState(account: account)
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ public final class SharedWakeupManager {
|
||||
private var hasActiveAudioSessionDisposable: Disposable?
|
||||
private var tasksDisposable: Disposable?
|
||||
private var currentTask: (UIBackgroundTaskIdentifier, Double, SwiftSignalKit.Timer)?
|
||||
private var currentExternalCompletion: (() -> Void, SwiftSignalKit.Timer)?
|
||||
private var currentExternalCompletionValidationTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private var managedPausedInBackgroundPlayer: Disposable?
|
||||
|
||||
@ -201,8 +203,51 @@ public final class SharedWakeupManager {
|
||||
}
|
||||
}
|
||||
|
||||
func replaceCurrentExtensionWithExternalTime(completion: @escaping () -> Void, timeout: Double) {
|
||||
if let (currentCompletion, timer) = self.currentExternalCompletion {
|
||||
currentCompletion()
|
||||
timer.invalidate()
|
||||
self.currentExternalCompletion = nil
|
||||
}
|
||||
let timer = SwiftSignalKit.Timer(timeout: timeout - 5.0, repeat: false, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.currentExternalCompletionValidationTimer?.invalidate()
|
||||
strongSelf.currentExternalCompletionValidationTimer = nil
|
||||
if let (completion, timer) = strongSelf.currentExternalCompletion {
|
||||
strongSelf.currentExternalCompletion = nil
|
||||
timer.invalidate()
|
||||
completion()
|
||||
}
|
||||
strongSelf.checkTasks()
|
||||
}, queue: Queue.mainQueue())
|
||||
self.currentExternalCompletion = (completion, timer)
|
||||
timer.start()
|
||||
|
||||
self.currentExternalCompletionValidationTimer?.invalidate()
|
||||
let validationTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: false, completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.currentExternalCompletionValidationTimer?.invalidate()
|
||||
strongSelf.currentExternalCompletionValidationTimer = nil
|
||||
strongSelf.checkTasks()
|
||||
}, queue: Queue.mainQueue())
|
||||
self.currentExternalCompletionValidationTimer = validationTimer
|
||||
validationTimer.start()
|
||||
self.checkTasks()
|
||||
}
|
||||
|
||||
func checkTasks() {
|
||||
var hasTasksForBackgroundExtension = false
|
||||
if self.inForeground || self.hasActiveAudioSession {
|
||||
if let (completion, timer) = self.currentExternalCompletion {
|
||||
self.currentExternalCompletion = nil
|
||||
completion()
|
||||
timer.invalidate()
|
||||
}
|
||||
|
||||
if let (taskId, _, timer) = self.currentTask {
|
||||
self.currentTask = nil
|
||||
timer.invalidate()
|
||||
@ -210,13 +255,21 @@ public final class SharedWakeupManager {
|
||||
self.isInBackgroundExtension = false
|
||||
}
|
||||
} else {
|
||||
var hasTasksForBackgroundExtension = false
|
||||
for (_, _, tasks) in self.accountsAndTasks {
|
||||
if !tasks.isEmpty {
|
||||
hasTasksForBackgroundExtension = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasTasksForBackgroundExtension && self.currentExternalCompletionValidationTimer == nil {
|
||||
if let (completion, timer) = self.currentExternalCompletion {
|
||||
self.currentExternalCompletion = nil
|
||||
completion()
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
if self.activeExplicitExtensionTimer != nil {
|
||||
hasTasksForBackgroundExtension = true
|
||||
}
|
||||
@ -265,11 +318,11 @@ public final class SharedWakeupManager {
|
||||
self.isInBackgroundExtension = false
|
||||
}
|
||||
}
|
||||
self.updateAccounts()
|
||||
self.updateAccounts(hasTasks: hasTasksForBackgroundExtension)
|
||||
}
|
||||
|
||||
private func updateAccounts() {
|
||||
if self.inForeground || self.hasActiveAudioSession || self.isInBackgroundExtension || self.activeExplicitExtensionTimer != nil {
|
||||
private func updateAccounts(hasTasks: Bool) {
|
||||
if self.inForeground || self.hasActiveAudioSession || self.isInBackgroundExtension || (hasTasks && self.currentExternalCompletion != nil) || self.activeExplicitExtensionTimer != nil {
|
||||
for (account, primary, tasks) in self.accountsAndTasks {
|
||||
if (self.inForeground && primary) || !tasks.isEmpty || (self.activeExplicitExtensionTimer != nil && primary) {
|
||||
account.shouldBeServiceTaskMaster.set(.single(.always))
|
||||
|
@ -791,7 +791,7 @@ typedef struct ID3v2EMFunc {
|
||||
|
||||
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
|
||||
{ "GEO", "GEOB", read_geobtag, free_geobtag },
|
||||
{ "PIC", "APIC", read_apic, free_apic },
|
||||
//{ "PIC", "APIC", read_apic, free_apic },
|
||||
{ "CHAP","CHAP", read_chapter, free_chapter },
|
||||
{ "PRIV","PRIV", read_priv, free_priv },
|
||||
{ NULL }
|
||||
|
Loading…
x
Reference in New Issue
Block a user