首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用NSSecureCoding来保证集合类的内容?

如何使用NSSecureCoding来保证集合类的内容?
EN

Stack Overflow用户
提问于 2014-03-13 16:07:03
回答 5查看 5K关注 0票数 3

我有一个SGBContainer类的对象,它有一个名为objects的数组,它包含SGBObject类的对象。目前,它们都实现了NSCoding,但没有实现NSSecureCoding。-initWithCoder: for SGBContainer如下所示:

代码语言:javascript
复制
- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [self init];
    if (self)
    {
        _objects = [aCoder decodeObjectForKey:@"objects"];
    }
}

我想切换到使用NSSecureCoding,从我所知道的来看,这意味着将上面的内容更改为:

代码语言:javascript
复制
- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [self init];
    if (self)
    {
        _objects = [aCoder decodeObjectOfClass:[NSArray class] forKey:@"objects"];
    }
}

...which没有多大的改进,因为不管它们的类是什么,数组的内容都会被实例化。如何确保数组只包含类SGBObject的对象而不实例化它们?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-03-23 05:14:15

虽然从文档中看它一点也不清楚(听起来只是一个奇怪的不语法方法名称),但这就是-decodeObjectOfClasses:forKey:所做的。你会做如下的事情:

代码语言:javascript
复制
NSSet *classes = [NSSet setWithObjects:[NSArray class], [SGBObject class], nil];
_objects = [aCoder decodeObjectOfClasses:classes forKey:@"objects"];

(在到期时贷记:参见NSSecureCoding trouble with collections of custom class)

票数 9
EN

Stack Overflow用户

发布于 2014-03-13 16:11:50

使用NSSecureCoding没有直接的方法,因为NSCoder不知道集合。您必须手动清理数组,以确保它只包含SGBObject类型的对象(公平地说,该对象与NSSecureCoding的用途相违背)。

另一种方法是自己对数组进行编码和解码,而不是依赖NSCoder来实现。

票数 1
EN

Stack Overflow用户

发布于 2017-11-15 19:37:57

Sean .的答案是正确的,但有一个警告:如果数组中的类是基类,则基金会不能保证它们的类类型。例如,下面的代码演示了这个问题:

代码语言:javascript
复制
@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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22384366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档