AddressSanitizer reports heap-buffer-overflow DRImagePlaceholderHelper.m:151
There is a problem where a fillColor is [UIColor lightGreyColor] and imageCachedForSize:isAvatar:fillColor:text: assumes there are four components to the UIColor but there are only two.
This happens from placerholderImageWithSize: where the fillColor is hard-coded to [UIColor lightGrayColor].
To reproduce this:
Open the Example project Edit the Scheme (I'm using iPhone 7 Plus (10.0)) Run > Diagnostics - check the box to enable Address Sanitizer Launch the Example It will stop pretty quickly with the error message I mentioned and the following text in the console
================================================================= ==40294==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000030900 at pc 0x00010de3075c bp 0x7fff51dd2b90 sp 0x7fff51dd2b88 READ of size 8 at 0x607000030900 thread T0 #0 0x10de3075b in -[DRImagePlaceholderHelper imageCachedForSize:isAvatar:fillColor:text:] DRImagePlaceholderHelper.m:151 #1 0x10de2f91f in -[DRImagePlaceholderHelper placerholderImageWithSize:text:fillColor:] DRImagePlaceholderHelper.m:111 #2 0x10de2ee4b in -[DRImagePlaceholderHelper placerholderImageWithSize:fillColor:] DRImagePlaceholderHelper.m:99 #3 0x10de2e85c in -[DRImagePlaceholderHelper placerholderImageWithSize:] DRImagePlaceholderHelper.m:92 #4 0x10de2ae74 in -[UIImageView(Placeholder) fillWithPlaceholderImage] UIImageView+Placeholder.m:16 #5 0x10de326b8 in -[ViewController viewDidLoad] ViewController.m:22 #6 0x10f50406c in -[UIViewController loadViewIfRequired] (UIKit+0x1c906c) #7 0x10f50449f in -[UIViewController view] (UIKit+0x1c949f) #8 0x10f3ce044 in -[UIWindow addRootViewControllerViewIfPossible] (UIKit+0x93044) #9 0x10f3ce795 in -[UIWindow _setHidden:forced:] (UIKit+0x93795) #10 0x10f3e20a8 in -[UIWindow makeKeyAndVisible] (UIKit+0xa70a8) #11 0x10f35b258 in -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] (UIKit+0x20258) #12 0x10f3613b8 in -[UIApplication _runWithMainScene:transitionContext:completion:] (UIKit+0x263b8) #13 0x10f35e538 in -[UIApplication workspaceDidEndTransaction:] (UIKit+0x23538) #14 0x11434276a in FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK (FrontBoardServices+0x3b76a) #15 0x1143425e3 in -[FBSSerialQueue _performNext] (FrontBoardServices+0x3b5e3) #16 0x11434296c in -[FBSSerialQueue _performNextFromRunLoopSource] (FrontBoardServices+0x3b96c) #17 0x111a6e310 in CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION (CoreFoundation+0x9c310) #18 0x111a5359b in __CFRunLoopDoSources0 (CoreFoundation+0x8159b) #19 0x111a52a85 in __CFRunLoopRun (CoreFoundation+0x80a85) #20 0x111a52493 in CFRunLoopRunSpecific (CoreFoundation+0x80493) #21 0x10f35cdb5 in -[UIApplication _run] (UIKit+0x21db5) #22 0x10f362f33 in UIApplicationMain (UIKit+0x27f33) #23 0x10de3189e in main main.m:16 #24 0x110ea168c in start (libdyld.dylib+0x468c)
0x607000030900 is located 0 bytes to the right of 80-byte region [0x6070000308b0,0x607000030900) allocated by thread T0 here: #0 0x10defdbd0 in __sanitizer_mz_malloc (libclang_rt.asan_iossim_dynamic.dylib+0x49bd0) #1 0x1129248d1 in malloc_zone_malloc (libsystem_malloc.dylib+0xe8d1) #2 0x1119d5a56 in _CFRuntimeCreateInstance (CoreFoundation+0x3a56) #3 0x10f0632d4 in CGTypeCreateInstance (CoreGraphics+0x4382d4) #4 0x10eeb833e in create_color (CoreGraphics+0x28d33e) #5 0x10f67a061 in -[UIDeviceWhiteColor _createCGColorWithAlpha:] (UIKit+0x33f061) #6 0x10f67a454 in -[UIDeviceWhiteColor CGColor] (UIKit+0x33f454) #7 0x10de3066b in -[DRImagePlaceholderHelper imageCachedForSize:isAvatar:fillColor:text:] DRImagePlaceholderHelper.m:150 #8 0x10de2f91f in -[DRImagePlaceholderHelper placerholderImageWithSize:text:fillColor:] DRImagePlaceholderHelper.m:111 #9 0x10de2ee4b in -[DRImagePlaceholderHelper placerholderImageWithSize:fillColor:] DRImagePlaceholderHelper.m:99 #10 0x10de2e85c in -[DRImagePlaceholderHelper placerholderImageWithSize:] DRImagePlaceholderHelper.m:92 #11 0x10de2ae74 in -[UIImageView(Placeholder) fillWithPlaceholderImage] UIImageView+Placeholder.m:16 #12 0x10de326b8 in -[ViewController viewDidLoad] ViewController.m:22 #13 0x10f50406c in -[UIViewController loadViewIfRequired] (UIKit+0x1c906c) #14 0x10f50449f in -[UIViewController view] (UIKit+0x1c949f) #15 0x10f3ce044 in -[UIWindow addRootViewControllerViewIfPossible] (UIKit+0x93044) #16 0x10f3ce795 in -[UIWindow _setHidden:forced:] (UIKit+0x93795) #17 0x10f3e20a8 in -[UIWindow makeKeyAndVisible] (UIKit+0xa70a8) #18 0x10f35b258 in -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] (UIKit+0x20258) #19 0x10f3613b8 in -[UIApplication _runWithMainScene:transitionContext:completion:] (UIKit+0x263b8) #20 0x10f35e538 in -[UIApplication workspaceDidEndTransaction:] (UIKit+0x23538) #21 0x11434276a in FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK (FrontBoardServices+0x3b76a) #22 0x1143425e3 in -[FBSSerialQueue _performNext] (FrontBoardServices+0x3b5e3) #23 0x11434296c in -[FBSSerialQueue _performNextFromRunLoopSource] (FrontBoardServices+0x3b96c) #24 0x111a6e310 in CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION (CoreFoundation+0x9c310) #25 0x111a5359b in __CFRunLoopDoSources0 (CoreFoundation+0x8159b) #26 0x111a52a85 in __CFRunLoopRun (CoreFoundation+0x80a85) #27 0x111a52493 in CFRunLoopRunSpecific (CoreFoundation+0x80493) #28 0x10f35cdb5 in -[UIApplication _run] (UIKit+0x21db5) #29 0x10f362f33 in UIApplicationMain (UIKit+0x27f33)
SUMMARY: AddressSanitizer: heap-buffer-overflow DRImagePlaceholderHelper.m:151 in -[DRImagePlaceholderHelper imageCachedForSize:isAvatar:fillColor:text:] Shadow bytes around the buggy address: 0x1c0e000060d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0e000060e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0e000060f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0e00006100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0e00006110: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00 =>0x1c0e00006120:[fa]fa fa fa 00 00 00 00 00 00 00 00 00 00 fa fa 0x1c0e00006130: fa fa 00 00 00 00 00 00 00 00 00 00 fa fa fa fa 0x1c0e00006140: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 0x1c0e00006150: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 0x1c0e00006160: 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 0x1c0e00006170: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==40294==ABORTING AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
This is the fix if anyone cares:
-
(NSString*)colorAsString:(UIColor*)color { const CGFloat *componentsP = CGColorGetComponents(color.CGColor); NSInteger count = MIN(CGColorGetNumberOfComponents(color.CGColor), 4); CGFloat components[4] = { 0, 0, 0, 0 };
for (NSInteger i = 0; i < count; i++) { components[i] = componentsP[i]; }
NSString *colorAsString = [NSString stringWithFormat:@"%f,%f,%f,%f", components[0], components[1], components[2], components[3]];
return colorAsString; } And call it like NSString *colorAsString = [self colorAsString:color]; from both imageCachedForSize:isAvatar:fillColor:text: and cacheImage: isAvatar: fillColor:text: