fix(display): guard DrawingContext against malloc-null image buffer

ASCGImageBuffer.initWithLength: calls malloc(length) with no null check.
When length is oversized (e.g. from a bad drawingSize during chat photo
layout), malloc can return NULL. CGContext(data: nil, ...) silently
succeeds anyway — CoreGraphics falls back to its own internally-managed
buffer, masking the failure. The later memset(self.bytes, 0, self.length)
in DrawingContext.init then writes through the null imageBuffer pointer
and segfaults (confirmed via crash report: ESR = Data Abort byte write
Translation fault, FAR = 0x0, __bzero on the stack, ASCGImageBuffer
visible in nearby registers — device crash while scrolling chats,
build 33193).

Fail the init gracefully (return nil) as soon as the buffer comes back
null, matching the other guarded failure paths already in this
initializer (non-positive size, CGContext creation failure).
This commit is contained in:
ankuper 2026-07-02 14:11:40 -04:00
parent 6e370e06d1
commit ffbe9ed418

View file

@ -638,6 +638,15 @@ public class DrawingContext {
self.length = self.bytesPerRow * Int(scaledSize.height)
self.imageBuffer = ASCGImageBuffer(length: UInt(self.length))
if Int(bitPattern: self.imageBuffer.mutableBytes) == 0 {
// malloc(length) failed (e.g. an oversized allocation from a bad
// drawingSize). CGContext(data: nil, ...) below would silently
// succeed using CG's own internal buffer, masking the failure
// until the later memset(self.bytes, ...) writes through this
// null pointer and segfaults. Fail the init instead, matching
// the other guarded failure paths in this initializer.
return nil
}
if opaque {
self.bitmapInfo = DeviceGraphicsContextSettings.shared.opaqueBitmapInfo