2009-05-29 40 views
2

我需要與iPhone應用程序進行簡單的客戶端 - 服務器通信,並且XML屬性列表看起來像是非常簡單和簡單的解決方案,這使我省卻了處理XML解析器委託並自行構建這些結構的麻煩。plist可以安全地從不受信任的來源讀取?

我只是想知道使用NSPropertyListSerialization類與外部數據是明智的嗎?是否有任何可以被利用的晦澀plist功能?

回答

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值放入存檔中,但存在錯誤匹配類型或非法值,這些值可能會導致您的客戶端行爲異常並最終成爲安全漏洞。

0

@Jon Hess:謝謝。我創建了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