diff options
author | Ben Bleything <ben@bleything.net> | 2006-09-11 02:23:25 +0000 |
---|---|---|
committer | Ben Bleything <ben@bleything.net> | 2006-09-11 02:23:25 +0000 |
commit | e3074d4f536abe635d75a5ab3201f60284668782 (patch) | |
tree | 4ae25b80c1945495ef9e07d164c113e16db80625 | |
parent | c056f689848cdbe92a0201c0af93f5be6430134e (diff) | |
download | plist-e3074d4f536abe635d75a5ab3201f60284668782.tar.gz |
merge trunk changes into parser injection removal branch
-rw-r--r-- | CHANGELOG | 5 | ||||
-rw-r--r-- | Rakefile | 15 | ||||
-rw-r--r-- | lib/plist.rb | 1 | ||||
-rw-r--r-- | lib/plist/generator.rb | 40 | ||||
-rw-r--r-- | lib/plist/parser.rb | 26 | ||||
-rw-r--r-- | test/assets/test_empty_key.plist | 13 | ||||
-rw-r--r-- | test/test_generator_basic_types.rb | 34 | ||||
-rw-r--r-- | test/test_parser.rb | 42 |
8 files changed, 115 insertions, 61 deletions
@@ -1 +1,6 @@ = plist - All-purpose Property List manipulation library + +2006-09-10: + + Added encoding / decoding for entities (& etc) + + Changed parsing of <data> elements to return StringIO objects + + Fixed bug with empty <key> tags
\ No newline at end of file @@ -40,12 +40,23 @@ Rake::TestTask.new { |t| t.verbose = true } -desc "Clean pkg and rdoc, remove .bak files" -task :clean => [ :clobber_rdoc, :clobber_package ] do +desc "Clean pkg, coverage, and rdoc; remove .bak files" +task :clean => [ :clobber_rdoc, :clobber_package, :clobber_coverage ] do puts cmd = "find . -type f -name *.bak -delete" `#{cmd}` end +task :clobber_coverage do + puts cmd = "rm -rf coverage" + `#{cmd}` +end + +desc "Generate coverage analysis with rcov (requires rcov to be installed)" +task :rcov => [ :clobber_coverage ] do + puts cmd = "rcov -Ilib --xrefs -T test/*.rb" + puts `#{cmd}` +end + desc "Strip trailing whitespace and fix newlines for all release files" task :fix_whitespace => [ :clean ] do RELEASE_FILES.each do |filename| diff --git a/lib/plist.rb b/lib/plist.rb index 814bf0a..e0ea72d 100644 --- a/lib/plist.rb +++ b/lib/plist.rb @@ -10,6 +10,7 @@ # # This is the main file for plist. Everything interesting happens in Plist and Plist::Emit. +require 'cgi' require 'plist/generator' require 'plist/parser' diff --git a/lib/plist/generator.rb b/lib/plist/generator.rb index c44c979..a1bb367 100644 --- a/lib/plist/generator.rb +++ b/lib/plist/generator.rb @@ -1,12 +1,10 @@ -#-- -############################################################## +#--########################################################### # Copyright 2006, Ben Bleything <ben@bleything.net> and # # Patrick May <patrick@hexane.org> # # # # Distributed under the MIT license. # ############################################################## #++ - # === Save a plist # You can turn the variables back into a plist string: # @@ -56,9 +54,9 @@ module Plist # expected plist classes (plist@hexane.org) def to_plist( header = true ) if (header) - Plist::_xml(self.to_plist_fragment) + Plist::_xml(self.to_plist_node) else - self.to_plist_fragment + self.to_plist_node end end end @@ -66,66 +64,66 @@ end class String include Plist::Emit - def to_plist_fragment - "<string>#{self}</string>" + def to_plist_node + "<string>#{CGI::escapeHTML(self)}</string>" end end class Symbol include Plist::Emit - def to_plist_fragment - "<string>#{self}</string>" + def to_plist_node + "<string>#{CGI::escapeHTML(self.to_s)}</string>" end end class Float include Plist::Emit - def to_plist_fragment + def to_plist_node "<real>#{self}</real>" end end class Time include Plist::Emit - def to_plist_fragment + def to_plist_node "<date>#{self.utc.strftime('%Y-%m-%dT%H:%M:%SZ')}</date>" end end class Date include Plist::Emit - def to_plist_fragment + def to_plist_node "<date>#{self.strftime('%Y-%m-%dT%H:%M:%SZ')}</date>" end end class Integer include Plist::Emit - def to_plist_fragment + def to_plist_node "<integer>#{self}</integer>" end end class FalseClass include Plist::Emit - def to_plist_fragment + def to_plist_node "<false/>" end end class TrueClass include Plist::Emit - def to_plist_fragment + def to_plist_node "<true/>" end end class Array include Plist::Emit - def to_plist_fragment + def to_plist_node fragment = "<array>\n" self.each do |e| - element_plist = e.to_plist_fragment + element_plist = e.to_plist_node element_plist.each do |l| fragment += "\t#{l.chomp}\n" end @@ -137,11 +135,11 @@ end class Hash include Plist::Emit - def to_plist_fragment + def to_plist_node fragment = "<dict>\n" self.keys.sort.each do |k| - fragment += "\t<key>#{k}</key>\n" - element_plist = self[k].to_plist_fragment + fragment += "\t<key>#{CGI::escapeHTML(k)}</key>\n" + element_plist = self[k].to_plist_node element_plist.each do |l| fragment += "\t#{l.chomp}\n" end @@ -155,7 +153,7 @@ require 'stringio' [ IO, StringIO ].each do |io_class| io_class.module_eval do include Plist::Emit - def to_plist_fragment + def to_plist_node self.rewind data = self.read diff --git a/lib/plist/parser.rb b/lib/plist/parser.rb index a92b997..81d8b88 100644 --- a/lib/plist/parser.rb +++ b/lib/plist/parser.rb @@ -1,12 +1,10 @@ -#-- -############################################################## +#--########################################################### # Copyright 2006, Ben Bleything <ben@bleything.net> and # # Patrick May <patrick@hexane.org> # # # # Distributed under the MIT license. # ############################################################## #++ -# # Plist parses Mac OS X xml property list files into ruby data structures. # # === Load a plist file @@ -162,13 +160,13 @@ XML class PKey < PTag def to_ruby - text + CGI::unescapeHTML(text || '') end end class PString < PTag def to_ruby - text || '' + CGI::unescapeHTML(text || '') end end @@ -212,15 +210,21 @@ XML end require 'base64' - require 'tempfile' class PData < PTag def to_ruby - tf = Tempfile.new("plist.tmp") - tf.write Base64.decode64(text.gsub(/\s+/,'')) - tf.close + # replacing Tempfile with StringIO + # think it might be a bit nicer + #require 'tempfile' + #tf = Tempfile.new("plist.tmp") + #tf.write Base64.decode64(text.gsub(/\s+/,'')) + #tf.close # is this a good idea? - tf.open - tf + #tf.open + #tf + io = StringIO.new + io.write Base64.decode64(text.gsub(/\s+/,'')) + io.rewind + io end end end diff --git a/test/assets/test_empty_key.plist b/test/assets/test_empty_key.plist new file mode 100644 index 0000000..5b37513 --- /dev/null +++ b/test/assets/test_empty_key.plist @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> + <dict> + <key>key</key> + <dict> + <key></key> + <string>1</string> + <key>subkey</key> + <string>2</string> + </dict> + </dict> +</plist>
\ No newline at end of file diff --git a/test/test_generator_basic_types.rb b/test/test_generator_basic_types.rb index 3483373..ed59757 100644 --- a/test/test_generator_basic_types.rb +++ b/test/test_generator_basic_types.rb @@ -49,4 +49,38 @@ class TestBasicTypes < Test::Unit::TestCase assert_equal wrap('date', test_date.strftime('%Y-%m-%dT%H:%M:%SZ')), [test_date].to_plist(false) assert_equal wrap('date', test_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')), [test_datetime].to_plist(false) end + + # generater tests from patrick's plist.rb code + def test_to_plist + assert_equal( Plist::_xml("<string>Hello, World</string>"), "Hello, World".to_plist ) + assert_equal( Plist::_xml("<real>151936595.697543</real>"), 151936595.697543.to_plist ) + assert_equal( Plist::_xml("<date>2006-04-21T16:47:58Z</date>"), DateTime.parse("2006-04-21T16:47:58Z").to_plist ) + assert_equal( Plist::_xml("<integer>999000</integer>"), 999000.to_plist ) + assert_equal( Plist::_xml("<false/>"), false.to_plist ) + assert_equal( Plist::_xml("<true/>"), true.to_plist ) + + assert_equal( Plist::_xml("<array>\n\t<true/>\n\t<false/>\n</array>"), + [ true, false ].to_plist ) + + assert_equal( Plist::_xml("<dict>\n\t<key>False</key>\n\t<false/>\n\t<key>True</key>\n\t<true/>\n</dict>"), + { 'True' => true, 'False' => false }.to_plist ) + + source = File.open("test/assets/AlbumData.xml") { |f| f.read } + + result = Plist::parse_xml(source) + + assert_equal( result, Plist::parse_xml(result.to_plist) ) + + File.delete('hello.plist') if File.exists?('hello.plist') + "Hello, World".save_plist('hello.plist') + assert_equal( Plist::_xml("<string>Hello, World</string>"), + File.open('hello.plist') {|f| f.read } ) + File.delete('hello.plist') if File.exists?('hello.plist') + end + + def test_escape_string_values + assert_equal( Plist::_xml("<string><plist></string>"), "<plist>".to_plist ) + assert_equal( Plist::_xml("<string>Fish & Chips</string>"), "Fish & Chips".to_plist ) + end + end diff --git a/test/test_parser.rb b/test/test_parser.rb index 2e94a1c..5aeda6c 100644 --- a/test/test_parser.rb +++ b/test/test_parser.rb @@ -54,6 +54,7 @@ class TestPlist < Test::Unit::TestCase end + # uncomment this test to work on speed optimization #def test_load_something_big # plist = Plist::parse_xml( "~/Pictures/iPhoto Library/AlbumData.xml" ) #end @@ -66,33 +67,6 @@ class TestPlist < Test::Unit::TestCase assert_equal( "2007-10-25T12:36:35Z", result.first['Expires'].to_s ) end - def test_to_plist - assert_equal( Plist::_xml("<string>Hello, World</string>"), "Hello, World".to_plist ) - assert_equal( Plist::_xml("<real>151936595.697543</real>"), 151936595.697543.to_plist ) - assert_equal( Plist::_xml("<date>2006-04-21T16:47:58Z</date>"), DateTime.parse("2006-04-21T16:47:58Z").to_plist ) - assert_equal( Plist::_xml("<integer>999000</integer>"), 999000.to_plist ) - assert_equal( Plist::_xml("<false/>"), false.to_plist ) - assert_equal( Plist::_xml("<true/>"), true.to_plist ) - - assert_equal( Plist::_xml("<array>\n\t<true/>\n\t<false/>\n</array>"), - [ true, false ].to_plist ) - - assert_equal( Plist::_xml("<dict>\n\t<key>False</key>\n\t<false/>\n\t<key>True</key>\n\t<true/>\n</dict>"), - { 'True' => true, 'False' => false }.to_plist ) - - source = File.open("test/assets/AlbumData.xml") { |f| f.read } - - result = Plist::parse_xml(source) - - assert_equal( result, Plist::parse_xml(result.to_plist) ) - - File.delete('hello.plist') if File.exists?('hello.plist') - "Hello, World".save_plist('hello.plist') - assert_equal( Plist::_xml("<string>Hello, World</string>"), - File.open('hello.plist') {|f| f.read } ) - File.delete('hello.plist') if File.exists?('hello.plist') - end - # this functionality is credited to Mat Schaffer, # who discovered the plist with the data tag # supplied the test data, and provided the parsing code. @@ -109,6 +83,20 @@ class TestPlist < Test::Unit::TestCase end + # bug fix for empty <key> + # reported by Matthias Peick <matthias@peick.de> + # reported and fixed by Frederik Seiffert <ego@frederikseiffert.de> + def test_empty_dict_key + data = Plist::parse_xml("test/assets/test_empty_key.plist"); + assert_equal("2", data['key']['subkey']) + end + + # bug fix for decoding entities + # reported by Matthias Peick <matthias@peick.de> + def test_decode_entities + data = Plist::parse_xml(Plist::_xml('<string>Fish & Chips</string>')) + assert_equal('Fish & Chips', data) + end end __END__ |