2009-05-29 7 views
2

J'ai besoin d'une communication client-serveur simple avec l'application iPhone, et les listes de propriétés XML me semblent être une solution simple et facile qui me permet d'éviter les problèmes avec les parseurs XML.Les plistes peuvent-ils être lus en toute sécurité à partir d'une source non fiable?

Je me demande simplement s'il est judicieux d'utiliser la classe NSPropertyListSerialization avec des données externes? Y a-t-il des caractéristiques obscures qui pourraient être exploitées?

Répondre

1

Oui, il est sûr d'utiliser NSPropertyListSerialization avec des données non fiables, mais après avoir transformé le sac d'octets en une hiérarchie de types de plist, vous devez valider ces types pour s'assurer qu'ils correspondent au format de données attendu.

Par exemple, si vous vous attendez un dictionnaire avec les touches de chaîne, et NSNumbers en tant que valeurs, vous devez valider avec quelque chose comme:

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; 

Si vous ne le faites pas, la source des données Vous pourriez avoir placé des valeurs de plist dans l'archive avec des types faussement appariés, ou des valeurs illégales qui pourraient amener votre client à se comporter mal et finir par être une faille de sécurité.

0

@Jon Hess: merci. J'ai créé la catégorie NSDictionary pour réduire le nombre requis de 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 
Questions connexes