diff options
Diffstat (limited to 'lib/plist/parser.rb')
-rwxr-xr-x | lib/plist/parser.rb | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/plist/parser.rb b/lib/plist/parser.rb index 7df9802..4de13f8 100755 --- a/lib/plist/parser.rb +++ b/lib/plist/parser.rb @@ -73,10 +73,10 @@ module Plist end TEXT = /([^<]+)/ - XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um - DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um - COMMENT_START = /\A<!--/u - COMMENT_END = /.*?-->/um + XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/m + DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/m + COMMENT_START = /\A<!--/ + COMMENT_END = /.*?-->/m def parse @@ -91,7 +91,14 @@ module Plist if @scanner.scan(COMMENT_START) @scanner.scan(COMMENT_END) elsif @scanner.scan(XMLDECL_PATTERN) + encoding = parse_encoding_from_xml_declaration(@scanner[1]) + next if encoding.nil? + + # use the specified encoding for the rest of the file + next unless String.method_defined?(:force_encoding) + @scanner.string = @scanner.rest.force_encoding(encoding) elsif @scanner.scan(DOCTYPE_PATTERN) + next elsif @scanner.scan(start_tag) @listener.tag_start(@scanner[1], nil) if (@scanner[2] =~ /\/$/) @@ -106,6 +113,22 @@ module Plist end end end + + private + + def parse_encoding_from_xml_declaration(xml_declaration) + return unless defined?(Encoding) + + xml_encoding = xml_declaration.match(/(?:\A|\s)encoding=(?:"(.*?)"|'(.*?)')(?:\s|\Z)/) + + return if xml_encoding.nil? + + begin + Encoding.find(xml_encoding[1]) + rescue ArgumentError + nil + end + end end class PTag |