Hi Quincey,

Thank you so much for the "heads-up" on this, I will be changing my App to use 
Secure Coding in the new future and it’s littered with NSArrays and 
NSDictionary properties. 

Do you know if same thing applies to dictionaries as well as arrays?

All the Best
Dave

> On 14 Feb 2016, at 08:45, Quincey Morris 
> <quinceymor...@rivergatesoftware.com> wrote:
> 
> I might be late to this party, but since I just spent hours on it, I’ll 
> document this for anyone who hasn’t run into it yet.
> 
> If you’re using NSSecureCoding, there’s a problem decoding NSArray objects. 
> You can’t use this:
> 
>       myArray = [coder decodeObjectForKey: @“myArray”];
> 
> and you can’t use this:
> 
>       myArray = [coder decodeObjectOfClass: [NSArray class] forKey: 
> @“myArray”];
> 
> The error message in the resulting exception won’t be very helpful, but it 
> means that the class of the array elements is invalid. What you actually need 
> to do is this:
> 
>       myArray = [coder decodeObjectOfClasses: [NSSet setWithObjects: [NSArray 
> class], [MyElementClass class], nil] forKey: @“myArray”];
> 
> Besides being obscure, this is also semantically incorrect, in that it 
> appears to allow decoding of objects that are not strictly arrays of 
> MyElementClass objects. (I guess this is not a security violation, since it 
> doesn’t permit an attack to substitute objects of arbitrary classes, but it 
> sure is annoying.]
> 
> Now, if you want to do this in Swift, you might be tempted to try the obvious 
> translation:
> 
>       let classes = Set<AnyClass> (arrayLiteral: [… anything here… ])
>       let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”)
> 
> but that won’t work because AnyClass isn’t Hashable. So you might try (well, 
> I tried) something like this:
> 
>       let classes = Set<NSObject> (arrayLiteral: [NSArray.self, 
> MyElementClass.self])
>       let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”)
> 
> This compiles, but it fails at run-time, with a message saying it found an 
> object of class ‘NSArray’, but only objects of classes ‘NSArray’ and 
> ‘MyElementClass’ are allowed. (!)
> 
> The solution is to fall back to an explicit NSSet object:
> 
>       let classes = NSSet (objects: NSArray.self, MyElementClass.self)
>       let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”)
> 
> There really needs to be (radar #24646135) API to decode a NSArray and 
> specify the class (or classes) of the elements. In Obj-C, something like:
> 
>       myArray = [coder decodeArrayWithObjectsOfClass: [MyElementClass class] 
> forKey: @“myArray”];
> 
> or in Swift:
> 
>       let myArray = coder.decodeArrayWithObjectsOfClass (MyElementClass.self, 
> forKey: “myArray”)
> 
> This would be particular useful in Swift, because it would give you 
> compile-time checking of the types in the assignment. (There is already a 
> Swift-only version of ‘decodeObjectOfClass’ that’s generic, so you get  the 
> “correct” return type.)
> 
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/dave%40looktowindward.com
> 
> This email sent to d...@looktowindward.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to