nicklockwood / FastCoding

A faster and more flexible binary file format replacement for NSCoding, Property Lists and JSON

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NSMutableDictionary with NSNumber keys bug(reproduces on 32 bit devices only)

SiarheiFedartsou opened this issue · comments

Please pay attention on this demonstration project https://github.com/SiarheiFedartsou/FastCodingBug

It seems that it is because of tagged pointers optimization on 64 bit platforms:

    id key1 = @1;
    id key2 = @YES;
  __autoreleasing NSMutableDictionary *dict = CFBridgingRelease(CFDictionaryCreateMutable(NULL, (CFIndex)1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
    dict[key1] = @"xxx";
    dict[key2] = @"yyy";

    CFHashCode h1 = CFHash((CFTypeRef)@1);
    CFHashCode h2 = CFHash((CFTypeRef)@YES);

    Boolean e = CFEqual((CFTypeRef)@1, (CFTypeRef)@YES);

    NSLog(@"%lu %lu %u", h1, h2, e);

Result of CFEqual will be True on 64 bit platform and False on 32 bit platform. Everything will be fine after replacing CFDictionaryCreateMutable* line to NSMutableDictionary *dict = [[NSMutableDictionary alloc] init].

I think that the best fix will be substitution of CFDictionary to NSDictionary in FCReadMutableDictionary or providing custom key callbacks for kCFTypeDictionaryKeyCallBacks(call - [NSObject hash] and -[NSObject isEqual:] instead of CFHash and CFEqual).

Thanks for reporting this. It's fixed in version 3.2.

I used the latter approach (custom kCFTypeDictionaryKeyCallBacks) and I've also changed FastCoder to not encode 0 and 1 and booleans any more, so it should be double-fixed :-)