Using the new NSKeyedArchive method on iOS 11+, use try catch on the old fireware to protect runtime crash

This commit is contained in:
DreamPiggy 2019-11-25 19:57:50 +08:00
parent 9f470954c4
commit 1df1d6a3ce
2 changed files with 32 additions and 2 deletions

View File

@ -202,7 +202,20 @@
// Check extended data
id extendedObject = image.sd_extendedObject;
if ([extendedObject conformsToProtocol:@protocol(NSCoding)]) {
NSData *extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject];
NSData *extendedData;
if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) {
NSError *error;
extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject requiringSecureCoding:NO error:&error];
if (error) {
NSLog(@"NSKeyedArchiver archive failed with error: %@", error);
}
} else {
@try {
extendedData = [NSKeyedArchiver archivedDataWithRootObject:extendedObject];
} @catch (NSException *exception) {
NSLog(@"NSKeyedArchiver archive failed with exception: %@", exception);
}
}
if (extendedData) {
[self.diskCache setExtendedData:extendedData forKey:key];
}
@ -361,7 +374,23 @@
// Check extended data
NSData *extendedData = [self.diskCache extendedDataForKey:key];
if (extendedData) {
image.sd_extendedObject = [NSKeyedUnarchiver unarchiveObjectWithData:extendedData];
id extendedObject;
if (@available(iOS 11, tvOS 11, macOS 10.13, watchOS 4, *)) {
NSError *error;
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:extendedData error:&error];
unarchiver.requiresSecureCoding = NO;
extendedObject = [unarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:&error];
if (error) {
NSLog(@"NSKeyedUnarchiver unarchive failed with error: %@", error);
}
} else {
@try {
extendedObject = [NSKeyedUnarchiver unarchiveObjectWithData:extendedData];
} @catch (NSException *exception) {
NSLog(@"NSKeyedUnarchiver unarchive failed with exception: %@", exception);
}
}
image.sd_extendedObject = extendedObject;
}
}
return image;

View File

@ -17,6 +17,7 @@
The extended object should conforms to NSCoding, which we use `NSKeyedArchiver` and `NSKeyedUnarchiver` to archive it to data, and write to disk cache.
@note The disk cache preserve both of the data and extended data with the same cache key. For manual query, use the `SDDiskCache` protocol method `extendedDataForKey:` instead.
@note You can specify arbitrary object conforms to NSCoding (NSObject protocol here is used to support object like `dispatch_data_t`, which is not NSObject subclass). If you load image from disk cache, you should check the extended object class to avoid corrupted data.
@warning This object don't need to implements NSSecureCoding (but it's recommended), because we allows arbitrary class.
*/
@property (nonatomic, strong, nullable) id<NSObject, NSCoding> sd_extendedObject;