Skip to content

iOS crash in WebP decode path (SDImageWebPCoder/libwebp) on 8.13.0 #374

@garshythoel

Description

@garshythoel

Summary

Seeing a reproducible iOS crash in the WebP decode path when using FastImage with many dynamic WebP images on a screen (avatar grid/list use case).

Crash appears in SDImageWebPCoder -> libwebp decode and goes away if we avoid the SDImageWebPCoder path on iOS 14+.

Environment

  • @d11/react-native-fast-image: 8.13.0
  • React Native: 0.77.3
  • Expo: 52.0.48
  • iOS target app uses CocoaPods with:
    • RNFastImage (8.13.0)
    • SDWebImage (5.21.6)
    • SDWebImageWebPCoder (0.15.0)
    • libwebp (1.5.0)

Repro pattern

  1. Render a screen with many remote WebP images via FastImage (in our case, avatar tab/grid).
  2. Open that screen and scroll/trigger multiple image loads.
  3. App crashes with EXC_BAD_ACCESS in WebP decode.

For context: the same image set did not crash in our pre-upgrade app version; issue appeared after upgrade.

Crash stack (excerpt)

  • ExtractPalettedAlphaRows
  • VP8LDecodeAlphaImageStream
  • WebPDecode
  • -[SDImageWebPCoder sd_createWebpImageWithData:colorSpace:scaledSize:]
  • -[SDImageWebPCoder decodedImageWithData:options:]
  • -[SDImageCodersManager decodedImageWithData:options:]
  • SDImageCacheDecodeImageData
  • -[SDImageCache diskImageForKey:data:options:context:]
  • -[FFFastImageView downloadImage:options:context:]
  • -[FFFastImageView reloadImage]

Queue shown at crash: com.hackemist.SDImageCache.ioQueue.

Workaround that fixed it for us

In FFFastImageView.mm coder registration (commonInitUtils), on iOS 14+:

  • add SDImageAWebPCoder (Apple ImageIO WebP coder)
  • remove SDImageWebPCoder

Pseudo-diff:

SDImageCodersManager *codersManager = [SDImageCodersManager sharedManager];
[codersManager addCoder:[SDImageAVIFCoder sharedCoder]];

if (@available(iOS 14.0, tvOS 14.0, *)) {
  Class aWebPCoderClass = NSClassFromString(@"SDImageAWebPCoder");
  if (aWebPCoderClass && [aWebPCoderClass respondsToSelector:@selector(sharedCoder)]) {
    id aWebPCoder = [aWebPCoderClass performSelector:@selector(sharedCoder)];
    if (aWebPCoder != nil) {
      [codersManager addCoder:aWebPCoder];
    }
  }
  [codersManager removeCoder:[SDImageWebPCoder sharedCoder]];
  return;
}

[codersManager addCoder:[SDImageWebPCoder sharedCoder]];

With this change, crash stopped in our testing.

Question

Would you consider an upstream option/guard for iOS 14+ to prefer AWebP over SDImageWebPCoder (or make WebP coder selection configurable), so apps can avoid this libwebp crash path without maintaining a local patch?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions