summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bleything <ben@bleything.net>2006-09-11 02:23:25 +0000
committerBen Bleything <ben@bleything.net>2006-09-11 02:23:25 +0000
commite3074d4f536abe635d75a5ab3201f60284668782 (patch)
tree4ae25b80c1945495ef9e07d164c113e16db80625
parentc056f689848cdbe92a0201c0af93f5be6430134e (diff)
downloadplist-e3074d4f536abe635d75a5ab3201f60284668782.tar.gz
merge trunk changes into parser injection removal branch
-rw-r--r--CHANGELOG5
-rw-r--r--Rakefile15
-rw-r--r--lib/plist.rb1
-rw-r--r--lib/plist/generator.rb40
-rw-r--r--lib/plist/parser.rb26
-rw-r--r--test/assets/test_empty_key.plist13
-rw-r--r--test/test_generator_basic_types.rb34
-rw-r--r--test/test_parser.rb42
8 files changed, 115 insertions, 61 deletions
diff --git a/CHANGELOG b/CHANGELOG
index dd4f06d..a0bedff 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1 +1,6 @@
= plist - All-purpose Property List manipulation library
+
+2006-09-10:
+ + Added encoding / decoding for entities (&amp; etc)
+ + Changed parsing of <data> elements to return StringIO objects
+ + Fixed bug with empty <key> tags \ No newline at end of file
diff --git a/Rakefile b/Rakefile
index 510d423..628b106 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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>&lt;plist&gt;</string>"), "<plist>".to_plist )
+ assert_equal( Plist::_xml("<string>Fish &amp; 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 &amp; Chips</string>'))
+ assert_equal('Fish & Chips', data)
+ end
end
__END__