ckruse / CFPropertyList

Read, write and manipulate both binary and XML property lists as defined by apple
MIT License
212 stars 47 forks source link

Format error! (CFFormatError) on nil key when using REXML parser #29

Closed dayglojesus closed 10 years ago

dayglojesus commented 10 years ago

When CFPropertyList falls back to using REXML for parsing and it encounters a nil key, it raises. This is east to reproduce using the file referenced below.

#!/usr/bin/ruby

require 'rubygems'
require 'cfpropertylist'

file = '/System/Library/Security/authorization.plist'

plist = CFPropertyList::List.new(:file => file)
# CFPropertyList.native_types(plist.value)

Results:

/Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbREXMLParser.rb:101:in `block in import_xml': Format error! (CFFormatError)
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/element.rb:905:in `block in each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/xpath.rb:67:in `each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/xpath.rb:67:in `each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/element.rb:905:in `each'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbREXMLParser.rb:93:in `import_xml'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbREXMLParser.rb:102:in `block in import_xml'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/element.rb:905:in `block in each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/xpath.rb:67:in `each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/xpath.rb:67:in `each'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rexml/element.rb:905:in `each'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbREXMLParser.rb:93:in `import_xml'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbREXMLParser.rb:23:in `load'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbCFPropertyList.rb:347:in `load'
    from /Library/Ruby/Gems/2.0.0/gems/CFPropertyList-2.2.5/lib/rbCFPropertyList.rb:247:in `initialize'
    from /Users/bcw/Desktop/foo.rb:8:in `new'
    from /Users/bcw/Desktop/foo.rb:8:in `<main>'
dayglojesus commented 10 years ago

As per the Twitters, this...

require "rexml/document"
file = '/System/Library/Security/authorization.plist'
File.open(file) { |fd| doc = REXML::Document.new(fd) }

Parses correctly.

dayglojesus commented 10 years ago

The file referenced exists on all Macs. If you need me to send it you, I'll need your email address.

ckruse commented 10 years ago

Ok, found the problem. It was caused by a nil return of REXML for an empty tag (like <key></key>) instead of an empty string. Per se this is correct behavior, but XML plists interpret this as an empty string.

dayglojesus commented 10 years ago

Confirmed. Thanks for the fix, Christian!