NSUserDefaults writes to wrong prefs file if app name begins with "Plist"

Originator:bewebste
Number:rdar://11841756 Date Originated:10-Jul-2012 11:33 AM
Status:Closed Resolved:
Product:OS X Product Version:10.8/12A269
Classification:Serious Bug Reproducible:Always
 
Summary:
NSUserDefaults reads/writes to an incorrect location in ~/Library/Preferences if the last component of the persistent domain being read/written begins with the string "Plist". For example, if you have an app with a bundle identifier of "com.mac.bwebster.PlistEditPro", in Lion and earlier, values set on NSUserDefaults will get written to ~/Library/Preferences/com.mac.bwebster.PlistEditPro.plist, but in Mountain Lion build 12A269, the values instead get written to ~/Library/Preferences/com.mac.bwebster.plist. The symptom of this is that when launching the app on Mountain Lion, all the user's settings will be forgotten, since they are not being read from the correct file.

Steps to reproduce:
I have attached a sample project that demonstrates the problem. The project contains two targets: PlistDefaultsTest, and UnfrozenCavemanDefaultsTest. The two targets have identical code and build settings, the only difference being the target name and bundle identifier used by the two applications.

Each scheme has a pre-action script for the Run action which copies a test plist containing a value for the key "testKey1" into ~/Library/Preferences, to emulate the setup where a user had been running the application on a previous OS X release. So, PlistDefaultsTest puts a plist at ~/Library/Preferences/com.mycompany.PlistDefaultsTest.plist and UnfrozenCavemanDefaultsTest puts the same data at ~/Library/Preferences/com.mycompany.UnfrozenCavemanDefaultsTest.plist

The app itself simply reads the value for "testKey1" both using NSUserDefaults and then by reading its preferences plist file manually, compares the two fetched values, and prints out whether they are equal into the app's window. It also calls setObject:forKey: on NSUserDefaults for the key "testKey2", to test where that value gets written out to disk.

Expected results:
Both apps should behave identically, with the value read from NSUserDefaults matching the one read manually from the preferences plist file.

Actual results:
1. The UnfrozenCavemanDefaultsTest app reports success, but the PlistDefaultsTest app reports failure.
2. After running the PlistDefaultsTest app, a new file named "com.mycompany.plist" will be created in ~/Library/Preferences containing the "testKey1" value that was set using -[NSUserDefaults setObject:forKey:]. The file "com.mycompany.PlistDefaultsTest.plist" is unchanged.

Regression:
This bug appears to also be present on build 12A256 (a.k.a. 10.8 DP4). I have not tested against any previous 10.8 seeds.

Notes:
I haven't tried exhaustive variations on the bundle identifier, but it does seem to be just that last component, and only when it starts with "Plist".

10-Jul-2012 11:33 AM Brian Webster:
'PlistUserDefaultsTests.zip' was successfully uploaded

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!