Dearchiving array of floats in 10.13.2 broken

)I've already reported this bug and raised a DTS incident to get it looked at, but I'm also putting it out there in case anyone else runs into it, or can suggest a workaround within app code. (Bug # 35926492)


10.13.2 breaks the function [-NSKeyedDearchiver decodeArrayOfObjCType:count:at:] when the obj-C type is @encode(float) ("f"). It now throws an exception as follows: *** -[_NSKeyedCoderOldStyleArray initWithCoder:]: unable to decode element in array of size (4) and count (6).

Note that all OS up to 10.13.1 work fine.


A test project reproduces the issue with the following code:


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

  NSString* path = [@"~/Desktop/testArchive.plist" stringByExpandingTildeInPath];

  float testValues[] = {1.0, 2.0, 3.5, 4.6, 3.1415926, 0.0};

  NSMutableData* testArchive = [NSMutableData data];

  NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:testArchive];

  [archiver encodeArrayOfObjCType:@encode(float) count:6 at:testValues];
  [archiver finishEncoding];

  [testArchive writeToFile:path atomically:YES];

     // now read it back in and see if it can be dearchived - in 10.13.2, this will throw an exception.

  NSData* readArchive = [NSData dataWithContentsOfFile:path];
  NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:readArchive];

  float readValues[6];

  [unarchiver decodeArrayOfObjCType:@encode(float) count:6 at:readValues]; //<--- throws
  [unarchiver finishDecoding];

  for( int i = 0; i < 6; ++i )
       NSAssert( readValues[i] == testValues[i], @"dearchived data does not match values archived");
}


Note that there are probably better, more robust ways to archive a list of floats. I'm not looking for suggestions about that. The issue is that there are thousands of archives out there in customer land that I need to be able to read.


I've tried substituting the class _NSKeyedCoderOldStyleArray with my own to see if I can read the archive keys directly - I can get NS.count, NS.size and NS.type OK, but $0..$n, nope. Quincey Morris suggested that the actual keys may not literally be these, which is what the archive file contains. I've tried without the leading $ symbol, but with no luck. Someone may know how the keys are changed when dearchiving which might give me a possible workaround.

Replies

Let me know your email address and I'll send it to you directly.

Hi Mapdiva,

Here is my email address. c2j.jct@free.fr

Thank you very much.