mixpanel / mixpanel-iphone

Official iOS (Objective-C) Tracking Library for Mixpanel Analytics
http://mixpanel.com
Apache License 2.0
1.05k stars 567 forks source link

Runtime exception from NSKeyedUnarchiver unarchivedObjectOfClass:fromData:error #985

Closed pouriaalmassi closed 2 years ago

pouriaalmassi commented 2 years ago

Integration Method: CocoaPods Xcode Version: Version 13.2.1 (13C100) Library Version: 4.1.2 Platform: iOS Language: Swift Description: I recently hit a runtime error in our project in the method + (id)unarchiveFromFile:(NSString *)filePath asClass:(Class)class. Expected Behavior: App should not have this runtime exception.

The error in question

*** -[NSKeyedUnarchiver validateAllowedClass:forKey:]: NSSecureCoding allowed classes list contains [NSObject class], which bypasses security by allowing any Objective-C class to be implicitly decoded. Consider reducing the scope of allowed classes during decoding by listing only the classes you expect to decode, or a more specific base class than NSObject. This will become an error in the future. Allowed class list: {(
    "'NSObject' (0x10e5222e8) [/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib]"
)}

The offending method

+ (id)unarchiveFromFile:(NSString *)filePath asClass:(Class)class
{
    id unarchivedData = nil;
    @try {
        if (@available(iOS 11, macOS 10.13, tvOS 11, watchOS 4, *)) {
            NSError *error = nil;
            NSData *data = [NSData dataWithContentsOfFile:filePath];
            unarchivedData = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSObject class] fromData:data error:&error];
            if (error) {
                MPLogError(@"%@ got error while unarchiving data in %@: %@", self, filePath, error);
            }
        } else {
            unarchivedData = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        }
        // this check is inside the try-catch as the unarchivedData may be a non-NSObject, not responding to `isKindOfClass:` or `respondsToSelector:`
        if (![unarchivedData isKindOfClass:class]) {
            unarchivedData = nil;
        }
        MPLogInfo(@"%@ unarchived data from %@: %@", self, filePath, unarchivedData);
    }
    @catch (NSException *exception) {
        MPLogError(@"%@ unable to unarchive data in %@, starting fresh", self, filePath);
        // Reset un archived data
        unarchivedData = nil;
        // Remove the (possibly) corrupt data from the disk
        NSError *error = NULL;
        BOOL removed = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
        if (!removed) {
            MPLogWarning(@"%@ unable to remove archived file at %@ - %@", self, filePath, error);
        }
    }
    return unarchivedData;
}
jaredmixpanel commented 2 years ago

@pouriaalmassi this issue has already been fixed in the latest version, v4.1.3, please update and let us know if there are any other issues.