// // FLEXRuntimeSafety.m // FLEX // // Created by Tanner on 3/25/17. // #import "FLEXRuntimeSafety.h" NSUInteger const kFLEXKnownUnsafeClassCount = 19; Class * _UnsafeClasses = NULL; CFSetRef FLEXKnownUnsafeClasses = nil; CFSetRef FLEXKnownUnsafeIvars = nil; #define FLEXClassPointerOrCFNull(name) \ (NSClassFromString(name) ?: (__bridge id)kCFNull) #define FLEXIvarOrCFNull(cls, name) \ (class_getInstanceVariable([cls class], name) ?: (void *)kCFNull) __attribute__((constructor)) static void FLEXRuntimeSafteyInit() { FLEXKnownUnsafeClasses = CFSetCreate( kCFAllocatorDefault, (const void **)(uintptr_t)FLEXKnownUnsafeClassList(), kFLEXKnownUnsafeClassCount, nil ); Ivar unsafeIvars[] = { FLEXIvarOrCFNull(NSURL, "_urlString"), FLEXIvarOrCFNull(NSURL, "_baseURL"), }; FLEXKnownUnsafeIvars = CFSetCreate( kCFAllocatorDefault, (const void **)unsafeIvars, sizeof(unsafeIvars), nil ); } const Class * FLEXKnownUnsafeClassList() { if (!_UnsafeClasses) { const Class ignored[] = { FLEXClassPointerOrCFNull(@"__ARCLite__"), FLEXClassPointerOrCFNull(@"__NSCFCalendar"), FLEXClassPointerOrCFNull(@"__NSCFTimer"), FLEXClassPointerOrCFNull(@"NSCFTimer"), FLEXClassPointerOrCFNull(@"__NSGenericDeallocHandler"), FLEXClassPointerOrCFNull(@"NSAutoreleasePool"), FLEXClassPointerOrCFNull(@"NSPlaceholderNumber"), FLEXClassPointerOrCFNull(@"NSPlaceholderString"), FLEXClassPointerOrCFNull(@"NSPlaceholderValue"), FLEXClassPointerOrCFNull(@"Object"), FLEXClassPointerOrCFNull(@"VMUArchitecture"), FLEXClassPointerOrCFNull(@"JSExport"), FLEXClassPointerOrCFNull(@"__NSAtom"), FLEXClassPointerOrCFNull(@"_NSZombie_"), FLEXClassPointerOrCFNull(@"_CNZombie_"), FLEXClassPointerOrCFNull(@"__NSMessage"), FLEXClassPointerOrCFNull(@"__NSMessageBuilder"), FLEXClassPointerOrCFNull(@"FigIrisAutoTrimmerMotionSampleExport"), // Temporary until we have our own type encoding parser; // setVectors: has an invalid type encoding and crashes NSMethodSignature FLEXClassPointerOrCFNull(@"_UIPointVector"), }; assert((sizeof(ignored) / sizeof(Class)) == kFLEXKnownUnsafeClassCount); _UnsafeClasses = (Class *)malloc(sizeof(ignored)); memcpy(_UnsafeClasses, ignored, sizeof(ignored)); } return _UnsafeClasses; } NSSet * FLEXKnownUnsafeClassNames() { static NSSet *set = nil; if (!set) { NSArray *ignored = @[ @"__ARCLite__", @"__NSCFCalendar", @"__NSCFTimer", @"NSCFTimer", @"__NSGenericDeallocHandler", @"NSAutoreleasePool", @"NSPlaceholderNumber", @"NSPlaceholderString", @"NSPlaceholderValue", @"Object", @"VMUArchitecture", @"JSExport", @"__NSAtom", @"_NSZombie_", @"_CNZombie_", @"__NSMessage", @"__NSMessageBuilder", @"FigIrisAutoTrimmerMotionSampleExport", @"_UIPointVector", ]; set = [NSSet setWithArray:ignored]; assert(set.count == kFLEXKnownUnsafeClassCount); } return set; }