Skip to content

Commit

Permalink
adding more nokogiri tests and making the main rails tests pass
Browse files Browse the repository at this point in the history
[#2190 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information
tenderlove authored and jeremy committed Mar 11, 2009
1 parent fa45540 commit b9e021d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
21 changes: 14 additions & 7 deletions activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -1,3 +1,5 @@
require 'nokogiri'

# = XmlMini Nokogiri implementation
module ActiveSupport
module XmlMini_Nokogiri #:nodoc:
Expand All @@ -10,7 +12,9 @@ def parse(string)
if string.blank?
{}
else
Nokogiri::XML(string).to_hash
doc = Nokogiri::XML(string)
raise doc.errors.first if doc.errors.length > 0
doc.to_hash
end
end

Expand All @@ -31,8 +35,8 @@ module Node
def to_hash(hash = {})
hash[name] ||= attributes_as_hash

walker = lambda { |child, memo, callback|
next if child.blank?
walker = lambda { |memo, parent, child, callback|
next if child.blank? && 'file' != parent['type']

if child.text?
(memo[CONTENT_ROOT] ||= '') << child.content
Expand All @@ -41,18 +45,21 @@ def to_hash(hash = {})

name = child.name

child_hash = child.attributes_as_hash
if memo[name]
memo[name] = [memo[name]].flatten
memo[name] << child.attributes_as_hash
memo[name] << child_hash
else
memo[name] = child.attributes_as_hash
memo[name] = child_hash
end

# Recusively walk children
child.children.each { |c| callback.call(c, memo[name], callback) }
child.children.each { |c|
callback.call(child_hash, child, c, callback)
}
}

children.each { |c| walker.call(c, hash[name], walker) }
children.each { |c| walker.call(hash[name], self, c, walker) }
hash
end

Expand Down
7 changes: 6 additions & 1 deletion activesupport/test/core_ext/hash_ext_test.rb
Expand Up @@ -884,7 +884,12 @@ def test_array_values_are_not_sorted
end

def test_expansion_count_is_limited
expected = defined?(LibXML) ? LibXML::XML::Error : RuntimeError
expected = {
'ActiveSupport::XmlMini_REXML' => 'RuntimeError',
'ActiveSupport::XmlMini_Nokogiri' => 'Nokogiri::XML::SyntaxError',
'ActiveSupport::XmlMini_LibXML' => 'LibXML::XML::Error',
}[ActiveSupport::XmlMini.backend.name].constantize

assert_raise expected do
attack_xml = <<-EOT
<?xml version="1.0" encoding="UTF-8"?>
Expand Down
47 changes: 47 additions & 0 deletions activesupport/test/xml_mini/nokogiri_engine_test.rb
Expand Up @@ -21,6 +21,42 @@ def teardown
XmlMini.backend = @default_backend
end

def test_file_from_xml
hash = Hash.from_xml(<<-eoxml)
<blog>
<logo type="file" name="logo.png" content_type="image/png">
</logo>
</blog>
eoxml
assert hash.has_key?('blog')
assert hash['blog'].has_key?('logo')

file = hash['blog']['logo']
assert_equal 'logo.png', file.original_filename
assert_equal 'image/png', file.content_type
end

def test_exception_thrown_on_expansion_attack
assert_raise Nokogiri::XML::SyntaxError do
attack_xml = <<-EOT
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE member [
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
<!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
<!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
<!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
<!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
<!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
]>
<member>
&a;
</member>
EOT
Hash.from_xml(attack_xml)
end
end

def test_setting_nokogiri_as_backend
XmlMini.backend = 'Nokogiri'
assert_equal XmlMini_Nokogiri, XmlMini.backend
Expand All @@ -31,6 +67,17 @@ def test_blank_returns_empty_hash
assert_equal({}, XmlMini.parse(''))
end

def test_array_type_makes_an_array
assert_equal_rexml(<<-eoxml)
<blog>
<posts type="array">
<post>a post</post>
<post>another post</post>
</posts>
</blog>
eoxml
end

def test_one_node_document_as_hash
assert_equal_rexml(<<-eoxml)
<products/>
Expand Down

0 comments on commit b9e021d

Please sign in to comment.