summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick May <patrick@hexane.org>2006-09-10 19:31:12 +0000
committerPatrick May <patrick@hexane.org>2006-09-10 19:31:12 +0000
commitba316d1482d036ebdca8bfac6044b58b0c149f74 (patch)
treebd4f26c54ddc5262c9dc7d7d50fe1d7a2cd5ba26
parent26926e1634ccdca8ebb407a5bba1b64747b60b31 (diff)
downloadplist-ba316d1482d036ebdca8bfac6044b58b0c149f74.tar.gz
fixed bugs, changed data elements to return StringIO
-rw-r--r--lib/plist.rb1
-rw-r--r--lib/plist/generator.rb38
-rw-r--r--lib/plist/parser.rb24
-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
6 files changed, 95 insertions, 57 deletions
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..255449e 100644
--- a/lib/plist/generator.rb
+++ b/lib/plist/generator.rb
@@ -1,11 +1,9 @@
-#--
##############################################################
# 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..ae2728d 100644
--- a/lib/plist/parser.rb
+++ b/lib/plist/parser.rb
@@ -1,11 +1,9 @@
-#--
##############################################################
# 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.
#
@@ -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__