-
-
Notifications
You must be signed in to change notification settings - Fork 29.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
plistlib fails to parse bplist with 0x80 UID values #70894
Comments
libplist raises an invalid file exception on loading properly formed binary plists containing UID (0x80) values. The binary files were tested for form with plutil. Comments at line 706 state the value is defined but not in use in plists, and the object is not handled. However, I find them frequently in bplists, e.g., iOS Snapchat application files. I have attached a proposed patch that I have tested on these files and can now successfully parse them with the _read_object method in the _BinaryPlistParser class. My proposed patch is pasted below for others consideration while waiting for the issue to be resolved. 706,707c706,708
Thanks for your consideration. |
Here is the version of the patch suitable for the Rietveld. John, could you perhaps provide an example file that uses UID values? Also, the code is identical to handling of 0x50 token, perhaps it could be incorporated into it. |
UID is rather int than bytes. And I would use a special UID type. According to Apple's sources [1], the size of UID data is tokenL+1, not self._get_size(tokenL). [1] http://www.opensource.apple.com/source/CF/CF-1153.18/CFBinaryPList.c |
I’m sorry, but the files in which I detected the problem cannot be circulated. I will try to create a test account on Snapchat and generate some test data, but I can’t do this anytime soon.
|
I’m glad you found it in the Apple specification. I looked, but missed it. I would absolutely defer to you on your assessment of the decoding.
|
Based on the format specification pointed to by Serhiy, perhaps this a better patch, correcting size from previous patch submission and treating: 706,707c706,708
I have compared output with OS X plutil and plistlib.load() with this patch and the values are identical for UID fields. |
How can you create plist files that contain UID values using Apple's APIs? The plist library is meant to be interoperable with files created using Apple's APIs for creating plist files, and I didn't find an API that created UID values at the time. |
The size of UID data is just tokenL + 1, not self._get_size(tokenL + 1). FYI, the code for support UIDs and other types was proposed in bpo-14455, but was excluded from the final patch. |
Note that I'm still -1 on merging this patch because it is unclear how to create such plist files using public Apple APIs. P.S. The low-level code for creating and reading binary plist files appears to be used for more than juist plist archives. |
Hello, I have attached a file extracted from the database of the 2Do App for iOS and macOS. The file contains information about tags used in the app. plistlib cannot currently parse this file because it lacks the ability to read byte 0x80 (UID). I believe the documentation for generating these type of files can be found at: https://developer.apple.com/documentation/foundation/nskeyedarchiver |
@bigfootjon: Cocoa keyed archives are not plist files. |
But they use the plist format for serialization (as plists theirself use the XML format). https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSKeyedArchiver.swift Direct support of keyed archives would be better to implement in third-party package. But we can provide the support for low-level operations. For distinguishing UIDs from integers and for being able to create plist files containing UIDs we need a special purposed class plist.UID. It will be a simpler wrapper around int with few methods: __index__(), __repr__(), __reduce__(). |
@serhiy.storchaka: I've implemented a UID wrapper class I've also updated the parser and writer classes to support the UID wrapper. The implementations for reading/writing XML UID tags match the implementations given by Apple's plutil distributed with macOS: UID(x) becomes {'CF$UID': int(x)} |
Ping |
I'm still not too happy about supporting UIDs in plistlib, especially because I'm not sure it that's all that's needed. AFAIK I removed more types that the underlying encoder supported from plistlib because those are never used in plist files. The swift encoder for keyed archives is probably not the code that's actually used on the OS, AFAIK that still is Objective-C code. P.S. I changed the version selection to 3.8, adding support for UIDs would be a feature change and not suited for back ports. |
Support for KeyedArchives are not limited to the Swift implementation I linked to. They have been supported since Mac OS X since 10.2 (long before Swift came around). The documentation (https://developer.apple.com/documentation/foundation/nskeyedarchiver?language=objc) shows that NSKeyedArchive can only output in plist format since outputFormat is of type NSPropertyListFormat (allowing to output in either XML or binary). The other unimplemented binary token types (URL, UUID, set, ordset) are not used under NSKeyedArchive (see the "Encoding Data and Objects" section of the documentation mentioned above) so there's no concern that supporting 0x80 (UID) will suddenly necessitate implementing the other unimplemented types. If you feel that it would be necessary to implement them in order to accept the patch I would be happy to try and implement them. I know I certainly have an use case (reading to-do list data from the 2Do app) and the creator of this bug wanted to read SnapChat data files. Currently, I am using a hot-patched plistlib._BinaryPlistParser to read the data I need (see attached for a snippet) and I would rather not do that, but if you think my use case scope does not warrant inclusion in the standard library then I'll just have to deal with that. |
Ping |
I recently upgraded my python version and my hot-patch broke due to changes in bpo-32072 (GH-4455). It reminded me of this b.p.o., and after reading through the messages to remind myself where the patch stood I realized that my tone friendly towards the end was not overly. @ronaldoussoren, I apologize if I offended. In other news, I re-implemented the patch (and filed a new pull-request) due to the following:
|
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: