Skip to content

Commit a91aef9

Browse files
committed
Port upstream PR package 2: Phone Recents call start (TelegramMessenger#2304), sharp fullscreen/peek stickers (TelegramMessenger#2297), DrawingContext null-buffer guard (TelegramMessenger#2217); TelegramMessenger#2315 already present
1 parent df7c926 commit a91aef9

6 files changed

Lines changed: 54 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66

77
## [Unreleased]
88

9+
## [v12.9.2-4036-pre]
10+
11+
### Fixed — порт upstream-PR, пакет 2
12+
- **#2304 (звонки из Phone Recents):** звонок, начатый из вкладки «Недавние» системного приложения Phone, открывал чат, но сам звонок не стартовал — handle активности (`TGCA<peerId>`) не распознавался. Теперь маппится напрямую на peer и запускается.
13+
- **#2297 (мыльные стикеры в fullscreen/peek):** увеличенные просмотрщики (наборы стикеров, peek) больше не блюрят ожидающий thumbnail — `blurThumbnail: false` + острый апскейл превью; peek кастомных emoji 120pt → 180pt (cap по размеру экрана).
14+
- **#2217 (SIGSEGV DrawingContext):** guard на нулевой `imageBuffer.mutableBytes` при неудачном malloc (сверхразмерный drawingSize) — вместо segfault в memset init теперь честно фейлится.
15+
16+
### Skipped
17+
- **#2315 (infinite GIF reader loop):** уже в форке — портирован ранее вместе с фиксом #2246 (zero-frame EOF → decode failure вместо вечного reopen-loop).
18+
919
## [v12.9.2-4035-pre]
1020

1121
### Fixed — порт upstream-PR, пакет 1 (стабильность + memory safety)

submodules/Display/Source/GenerateImage.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,16 @@ public class DrawingContext {
638638
self.length = self.bytesPerRow * Int(scaledSize.height)
639639

640640
self.imageBuffer = ASCGImageBuffer(length: UInt(self.length))
641+
if Int(bitPattern: self.imageBuffer.mutableBytes) == 0 {
642+
// malloc(length) failed (e.g. an oversized allocation from a bad
643+
// drawingSize). CGContext(data: nil, ...) below would silently
644+
// succeed using CG's own internal buffer, masking the failure
645+
// until the later memset(self.bytes, ...) writes through this
646+
// null pointer and segfaults. Fail the init instead, matching
647+
// the other guarded failure paths in this initializer.
648+
// (Upstream PR #2217.)
649+
return nil
650+
}
641651

642652
if opaque {
643653
self.bitmapInfo = DeviceGraphicsContextSettings.shared.opaqueBitmapInfo

submodules/StickerPackPreviewUI/Sources/StickerPreviewControllerNode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ final class StickerPreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
138138
self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(32.0), textColor: .black)
139139
break
140140
}
141-
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: itemFile, small: false, onlyFullSize: false))
141+
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: itemFile, small: false, fetched: true, onlyFullSize: false, blurThumbnail: false))
142142

143143
if let (layout, navigationBarHeight) = self.containerLayout {
144144
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)

submodules/StickerPeekUI/Sources/StickerPreviewPeekContent.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
193193
self.animationNode = nil
194194
}
195195

196-
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: file, small: false, fetched: true))
196+
self.imageNode.setSignal(chatMessageSticker(account: context.account, userLocation: .other, file: file, small: false, fetched: true, onlyFullSize: false, blurThumbnail: false))
197197
} else if case .portal = item {
198198
self._ready.set(.single(true))
199199
}
@@ -266,7 +266,7 @@ public final class StickerPreviewPeekContentNode: ASDisplayNode, PeekControllerC
266266
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
267267
let boundingSize: CGSize
268268
if self.item.file?.isCustomEmoji == true {
269-
boundingSize = CGSize(width: 120.0, height: 120.0)
269+
boundingSize = CGSize(width: 180.0, height: 180.0).fitted(size)
270270
} else if let _ = self.additionalAnimationNode {
271271
boundingSize = CGSize(width: 240.0, height: 240.0).fitted(size)
272272
} else {

submodules/StickerResources/Sources/StickerResources.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ public func chatMessageAnimatedStickerBackingData(postbox: Postbox, fileReferenc
261261
}
262262

263263

264-
public func chatMessageSticker(account: Account, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, colorSpace: CGColorSpace? = nil) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
265-
return chatMessageSticker(postbox: account.postbox, userLocation: userLocation, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, thumbnail: thumbnail, synchronousLoad: synchronousLoad, colorSpace: colorSpace)
264+
public func chatMessageSticker(account: Account, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, colorSpace: CGColorSpace? = nil, blurThumbnail: Bool = true) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
265+
return chatMessageSticker(postbox: account.postbox, userLocation: userLocation, file: file, small: small, fetched: fetched, onlyFullSize: onlyFullSize, thumbnail: thumbnail, synchronousLoad: synchronousLoad, colorSpace: colorSpace, blurThumbnail: blurThumbnail)
266266
}
267267

268268
public func chatMessageStickerPackThumbnail(postbox: Postbox, resource: MediaResource, animated: Bool = false, synchronousLoad: Bool = false, nilIfEmpty: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
@@ -318,7 +318,7 @@ public func chatMessageStickerPackThumbnail(postbox: Postbox, resource: MediaRes
318318
}
319319
}
320320

321-
public func chatMessageSticker(postbox: Postbox, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, colorSpace: CGColorSpace? = nil) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
321+
public func chatMessageSticker(postbox: Postbox, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, colorSpace: CGColorSpace? = nil, blurThumbnail: Bool = true) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
322322
let signal: Signal<Tuple3<Data?, Data?, Bool>, NoError>
323323

324324
if thumbnail {
@@ -367,7 +367,7 @@ public func chatMessageSticker(postbox: Postbox, userLocation: MediaResourceUser
367367

368368
var blurredThumbnailImage: UIImage?
369369
let thumbnailInset: CGFloat = 10.0
370-
if let thumbnailImage = thumbnailImage {
370+
if blurThumbnail, let thumbnailImage = thumbnailImage {
371371
let thumbnailSize = thumbnailImage.0.size
372372
var thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0))
373373
let thumbnailDrawingSize = thumbnailContextSize
@@ -403,6 +403,11 @@ public func chatMessageSticker(postbox: Postbox, userLocation: MediaResourceUser
403403
c.interpolationQuality = .low
404404
let thumbnailScaledInset = thumbnailInset * (fittedRect.width / blurredThumbnailImage.size.width)
405405
c.draw(blurredThumbnailImage.cgImage!, in: fittedRect.insetBy(dx: -thumbnailScaledInset, dy: -thumbnailScaledInset))
406+
} else if let thumbnailImage = thumbnailImage, let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage {
407+
c.setBlendMode(.normal)
408+
c.interpolationQuality = .medium
409+
let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true)
410+
c.draw(cgImage.masking(mask!)!, in: fittedRect)
406411
}
407412

408413
if let fullSizeImage = fullSizeImage, let cgImage = fullSizeImage.0.cgImage, let cgImageAlpha = fullSizeImage.1.cgImage {
@@ -420,7 +425,7 @@ public func chatMessageSticker(postbox: Postbox, userLocation: MediaResourceUser
420425
}
421426
}
422427

423-
public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, size: CGSize, fitzModifier: EmojiFitzModifier? = nil, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
428+
public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaResourceUserLocation, file: TelegramMediaFile, small: Bool, size: CGSize, fitzModifier: EmojiFitzModifier? = nil, fetched: Bool = false, onlyFullSize: Bool = false, thumbnail: Bool = false, synchronousLoad: Bool = false, blurThumbnail: Bool = true) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
424429
let signal: Signal<Tuple3<Data?, Data?, Bool>, NoError>
425430
if thumbnail {
426431
signal = chatMessageStickerThumbnailData(postbox: postbox, userLocation: userLocation, file: file, synchronousLoad: synchronousLoad)
@@ -464,7 +469,7 @@ public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaReso
464469

465470
var blurredThumbnailImage: UIImage?
466471
let thumbnailInset: CGFloat = 10.0
467-
if let thumbnailImage = thumbnailImage {
472+
if blurThumbnail, let thumbnailImage = thumbnailImage {
468473
let thumbnailSize = thumbnailImage.0.size
469474
var thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0))
470475
let thumbnailDrawingSize = thumbnailContextSize
@@ -502,6 +507,11 @@ public func chatMessageAnimatedSticker(postbox: Postbox, userLocation: MediaReso
502507
let thumbnailFittedRect = CGRect(origin: CGPoint(x: fittedRect.origin.x - (thumbnailFittedSize.width - fittedRect.width) / 2.0, y: fittedRect.origin.y - (thumbnailFittedSize.height - fittedRect.height) / 2.0), size: thumbnailFittedSize)
503508
let thumbnailScaledInset = thumbnailInset * (fittedRect.width / blurredThumbnailImage.size.width)
504509
c.draw(blurredThumbnailImage.cgImage!, in: thumbnailFittedRect.insetBy(dx: -thumbnailScaledInset, dy: -thumbnailScaledInset))
510+
} else if let thumbnailImage = thumbnailImage, let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage {
511+
c.setBlendMode(.normal)
512+
c.interpolationQuality = .medium
513+
let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true)
514+
c.draw(cgImage.masking(mask!)!, in: fittedRect)
505515
}
506516

507517
if let fullSizeImage = fullSizeImage, let cgImage = fullSizeImage.0.cgImage, let cgImageAlpha = fullSizeImage.1.cgImage {

submodules/TelegramUI/Sources/AppDelegate.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2760,6 +2760,21 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
27602760

27612761
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
27622762
if #available(iOS 10.0, *) {
2763+
// A call started from the iOS Phone app's Recents tab resumes as an activity whose
2764+
// handle carries the peer id (TGCA<id>) rather than a phone number; without this the
2765+
// chat opens but the call never starts (upstream PR #2304).
2766+
let startCallHandlePrefix = "TGCA"
2767+
if userActivity.activityType == NSStringFromClass(INStartCallIntent.self),
2768+
let handle = userActivity.userInfo?["handle"] as? String,
2769+
handle.hasPrefix(startCallHandlePrefix),
2770+
let peerIdValue = Int64(handle.dropFirst(startCallHandlePrefix.count)) {
2771+
let peerId = PeerId(peerIdValue)
2772+
if peerId.namespace == Namespaces.Peer.CloudUser {
2773+
self.startCallWhenReady(accountId: nil, peerId: peerId, isVideo: false)
2774+
return true
2775+
}
2776+
}
2777+
27632778
var startCallContacts: [INPerson]?
27642779
var isVideo = false
27652780
if let startCallIntent = userActivity.interaction?.intent as? SupportedStartCallIntent {

0 commit comments

Comments
 (0)