如何将NSSecureCoding与id对象一起使用

时间:2015-07-09 02:56:37

标签: objective-c nssecurecoding

我正在创建链接列表并使用容器对对象,下一个和以前的属性进行分组。像Foundation集合一样,我希望它能够实现NSSecureCoding。这是宣言:

@interface ListContainer : NSObject <NSCopying, NSSecureCoding>

@property (readonly, nonatomic) id object;
@property (nonatomic) ListContainer * next;
@property (nonatomic) ListContainer * previous;

@end

当实现- initWithCoder:方法时,我发现我不知道该对象使用哪个类:

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];

    if (self) {

        _object = [aDecoder decodeObjectOfClass:<#(__unsafe_unretained Class)#> forKey:@"object"];

        BOOL nextIsNil = [aDecoder decodeBoolForKey:@"nextIsNil"];

        if (!nextIsNil) {

            // Decode next
            _next = [aDecoder decodeObjectOfClass:[ListContainer class] forKey:@"next"];

            if (_next == nil) {
                return nil;
            }

            // Link the nodes manually to prevent infinite recursion
            self.next.previous = self;
        }
    }

    return self;
}

我应该使用-decodeObjectForKey:吗?它仍然是安全的编码吗?

1 个答案:

答案 0 :(得分:1)

我最后向Cocoa的邮件列表发布了同样的问题,最有趣的讨论发生了。一些亮点:

  

[...]制作一个正常的NSArray,如NSString,NSNumber,编码   它,用decodeObjectForClasses解码它,没有类。你会   在阵列上失败。将NSArray添加到允许的类列表中   .. 有用。所以,你认为,NSArray会盲目地解码任何东西   它不再安全。

     

添加自定义类的对象   实现对阵列的安全编码,它将开始失败   再次。 NSArray和其他集合类型允许元素   已知的安全系统类型,如NSString,但在任何外部都失败   那。 [...]

此时我明白NSArray并不像我预期的那样行事。安全编码似乎不再那么安全:

  

这似乎远非理想[...]它解码了一组   已知实现NSSecureCoding的类是错误的,IMO,两个   原因[...]

     

1)包含的类实现NSSecureCoding 的事实   并不意味着我期待它。 [...]

     

2)它限制了可以存储的类。 [...]

获得一个我在替代攻击中没有预料到的课程尤其可怕。显然,可可的承诺是不同的:

  

[...]如果您直接使用NSArray()或其他集合类   你的编码,你需要检查你得到的东西。他们是   “安全”解码到Apple认为解码它们的程度   不会导致缓冲区溢出等,这就是你所能得到的   默认即可。 [...]

所以,不,NSSecureCoding不保证容器的安全编码,或者至少它不保证类型检查,你必须自己做。甚至在我最初假设的Cocoa原生数据结构中也没有(有理由,我仍然认为)。

Props去Roland King做了很多努力。您可以看到完整的对话here