我有一个SGBContainer类的对象,它有一个名为objects的数组,它包含SGBObject类的对象。目前,它们都实现了NSCoding,但没有实现NSSecureCoding。-initWithCoder: for SGBContainer如下所示:
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [self init];
if (self)
{
_objects = [aCoder decodeObjectForKey:@"objects"];
}
}我想切换到使用NSSecureCoding,从我所知道的来看,这意味着将上面的内容更改为:
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [self init];
if (self)
{
_objects = [aCoder decodeObjectOfClass:[NSArray class] forKey:@"objects"];
}
}...which没有多大的改进,因为不管它们的类是什么,数组的内容都会被实例化。如何确保数组只包含类SGBObject的对象而不实例化它们?
发布于 2015-03-23 05:14:15
虽然从文档中看它一点也不清楚(听起来只是一个奇怪的不语法方法名称),但这就是-decodeObjectOfClasses:forKey:所做的。你会做如下的事情:
NSSet *classes = [NSSet setWithObjects:[NSArray class], [SGBObject class], nil];
_objects = [aCoder decodeObjectOfClasses:classes forKey:@"objects"];(在到期时贷记:参见NSSecureCoding trouble with collections of custom class)
发布于 2014-03-13 16:11:50
使用NSSecureCoding没有直接的方法,因为NSCoder不知道集合。您必须手动清理数组,以确保它只包含SGBObject类型的对象(公平地说,该对象与NSSecureCoding的用途相违背)。
另一种方法是自己对数组进行编码和解码,而不是依赖NSCoder来实现。
发布于 2017-11-15 19:37:57
Sean .的答案是正确的,但有一个警告:如果数组中的类是基类,则基金会不能保证它们的类类型。例如,下面的代码演示了这个问题:
@implementation Serializable
- (id)initWithCoder:(NSCoder *)aDecoder {
return [super init];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
}
+ (BOOL)supportsSecureCoding {
return YES;
}
@end
int main(int argc, const char * argv[]) {
NSArray *foo = @[ @1, @"Gotcha", [Serializable new] ];
NSMutableData *archive = [NSMutableData data];
NSKeyedArchiver *archiver =
[[NSKeyedArchiver alloc] initForWritingWithMutableData:archive];
archiver.requiresSecureCoding = YES;
[archiver encodeObject:foo forKey:@"root"];
[archiver finishEncoding];
NSKeyedUnarchiver *unarchiver =
[[NSKeyedUnarchiver alloc] initForReadingWithData:archive];
unarchiver.requiresSecureCoding = YES;
NSSet *classes = [NSSet setWithArray:@[ [NSArray class], [Serializable class] ]];
// Should throw, but it does not.
NSArray *loaded = [unarchiver decodeObjectOfClasses:classes forKey:NSKeyedArchiveRootObjectKey];
if (loaded.count > 2 && ![loaded[0] isKindOfClass:[Serializable class]]) {
NSLog(@"Successfully performed object substitution attack.");
NSLog(@"Class: %@", [loaded[0] class]); // All 3 objects are
return 1;
}
return 0;
}https://stackoverflow.com/questions/22384366
复制相似问题