Skip to content

Commit 6a33412

Browse files
VeinGuowolfcon
andauthored
Fixed secure coding issue that classes object couldn't be decoded. (#830)
Co-authored-by: Vein Guo <[email protected]> Co-authored-by: Frank <[email protected]>
1 parent e3e7596 commit 6a33412

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

MJExtension/NSObject+MJCoding.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ - (void)mj_decode:(NSCoder *)decoder
4444
if ([ignoredCodingPropertyNames containsObject:property.name]) return;
4545

4646
// fixed `-[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber'(This will be disallowed in the future.)` warning.
47-
id value = [decoder decodeObjectOfClasses:[NSSet setWithObjects:NSNumber.class, property.type.typeClass, nil] forKey:property.name];
47+
Class genericClass = [property objectClassInArrayForClass:property.srcClass];
48+
// If genericClass exists, property.type.typeClass would be a collection type(Array, Set, Dictionary). This scenario([obj, nil, obj, nil]) would not happened.
49+
NSSet *classes = [NSSet setWithObjects:NSNumber.class,
50+
property.type.typeClass, genericClass, nil];
51+
id value = [decoder decodeObjectOfClasses:classes forKey:property.name];
4852
if (value == nil) { // 兼容以前的MJExtension版本
4953
value = [decoder decodeObjectForKey:[@"_" stringByAppendingString:property.name]];
5054
}

MJExtensionTests/MJExtensionTests.m

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#import "MJFrenchUser.h"
2121
#import "MJCat.h"
2222
#import <MJExtensionTests-Swift.h>
23+
#import "MJPerson.h"
2324

2425
@interface MJExtensionTests : XCTestCase
2526

@@ -458,6 +459,42 @@ - (void)testCoding {
458459
MJExtensionLog(@"name=%@, price=%f", decodedBag.name, decodedBag.price);
459460
}
460461

462+
- (void)testCodingModelArrayProperty {
463+
// 有 NSArray 属性 模型
464+
MJPerson *person = [[MJPerson alloc] init];
465+
person.name = @"boy1";
466+
person.isVIP = YES;
467+
468+
MJPerson *friend1 = [[MJPerson alloc] init];
469+
friend1.name = @"friend1";
470+
friend1.isVIP = YES;
471+
472+
MJPerson *friend2 = [[MJPerson alloc] init];
473+
friend2.name = @"friend2";
474+
friend2.isVIP = NO;
475+
476+
person.friends = @[friend1, friend2];
477+
person.books = @[@"book1", @"book2"];
478+
479+
NSString *file = [NSTemporaryDirectory() stringByAppendingPathComponent:@"person.data"];
480+
NSError *error = nil;
481+
// 归档
482+
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person
483+
requiringSecureCoding:YES
484+
error:&error];
485+
BOOL write = [data writeToFile:file atomically:true];
486+
XCTAssert(write);
487+
488+
// 解档
489+
NSData *readData = [NSFileManager.defaultManager contentsAtPath:file];
490+
error = nil;
491+
MJPerson *decodedPerson = [NSKeyedUnarchiver unarchivedObjectOfClass:MJPerson.class
492+
fromData:readData
493+
error:&error];
494+
XCTAssert(decodedPerson.friends.count == 2);
495+
XCTAssert(decodedPerson.books.count == 2);
496+
}
497+
461498
#pragma mark 统一转换属性名(比如驼峰转下划线)
462499
- (void)testReplacedKeyFromPropertyName121 {
463500
// 1.定义一个字典

MJExtensionTests/Model/MJPerson.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ NS_ASSUME_NONNULL_BEGIN
1212

1313
@interface MJPerson : NSObject
1414
@property (copy, nonatomic) NSString *name;
15+
@property (nonatomic) BOOL isVIP;
1516
@property (strong, nonatomic) NSArray<MJPerson *> *friends;
17+
@property (strong, nonatomic) NSArray<NSString *> *books;
1618
@end
1719

1820
NS_ASSUME_NONNULL_END

MJExtensionTests/Model/MJPerson.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
#import "MJPerson.h"
1010
#import <MJExtension/MJExtension.h>
1111

12+
// NSSecureCoding实现
13+
MJSecureCodingImplementation(MJPerson, YES)
14+
1215
@implementation MJPerson
1316
+ (NSDictionary *)mj_objectClassInArray {
14-
return @{@"friends" : @"MJPerson"};
17+
return @{@"friends": [MJPerson class],
18+
@"books": [NSString class]};
1519
}
1620
@end

0 commit comments

Comments
 (0)