我需要与iPhone应用程序进行简单的客户端 - 服务器通信,并且XML属性列表看起来非常简单和简单,这使我免于处理XML解析器代理和自己构建这些结构的麻烦。
我只是想知道将NSPropertyListSerialization类与外部数据一起使用是否明智?是否有任何模糊的plist功能可以被利用?
答案 0 :(得分:1)
是的,将NSPropertyListSerialization与不受信任的数据一起使用是安全的,但是在将字节数转换为plist类型的层次结构后,您必须验证这些类型以确保它们符合您预期的数据格式。
例如,如果您希望字典中包含字符串键,而NSNumbers作为值,则必须使用以下内容进行验证:
NSString *errorDescription = nil;
NSPropertyListFormat format = 0;
id topObject = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&errorDescription];
NSDictionary *validDictionary = nil;
if ([topObject isKindOfClass:[NSDictionary class]]) {
BOOL allNumbers = YES;
for(id value in [topObject allValues]) {
allNumbers = allNumbers && [value isKindOfClass:[NSNumber class]];
}
if (allNumbers) {
validDictionary = topObject;
}
}
return validDictionary;
如果您不这样做,数据源可能会将plist值放入存档中,匹配类型不匹配,或者非法值可能导致客户端行为不端并最终成为安全漏洞。
答案 1 :(得分:0)
NSDictionary
类别以减少所需的isKindOfClass
es。
@interface NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key;
-(NSString *)stringForKey:(NSString*)key;
-(NSDictionary *)dictionaryForKey:(NSString*)key;
@end
@implementation NSDictionary (TypedDictionary)
-(NSArray *)arrayForKey:(NSString*)key {
NSArray *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSArray class]] ? obj : nil;
}
-(NSString *)stringForKey:(NSString*)key {
NSString *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSString class]] ? obj : nil;
}
-(NSDictionary *)dictionaryForKey:(NSString*)key {
NSDictionary *obj = [self objectForKey:key];
return [obj isKindOfClass:[NSDictionary class]] ? obj : nil;
}
@end