[前][次][番号順一覧][スレッド一覧]

ruby-changes:27332

From: usa <ko1@a...>
Date: Fri, 22 Feb 2013 18:36:00 +0900 (JST)
Subject: [ruby-changes:27332] usa:r39384 (trunk): * lib/rexml/document.rb (REXML::Document.entity_expansion_text_limit):

usa	2013-02-22 18:35:46 +0900 (Fri, 22 Feb 2013)

  New Revision: 39384

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39384

  Log:
    * lib/rexml/document.rb (REXML::Document.entity_expansion_text_limit):
      new attribute to read/write entity expansion text limit.  the default
      limit is 10Kb.
    
    * lib/rexml/text.rb (REXML::Text.unnormalize): check above attribute.

  Modified files:
    trunk/ChangeLog
    trunk/lib/rexml/document.rb
    trunk/lib/rexml/text.rb
    trunk/test/rexml/test_entity.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 39383)
+++ ChangeLog	(revision 39384)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Feb 22 18:31:46 2013  Aaron Patterson <aaron@t...>
+
+	* lib/rexml/document.rb (REXML::Document.entity_expansion_text_limit):
+	  new attribute to read/write entity expansion text limit.  the default
+	  limit is 10Kb.
+
+	* lib/rexml/text.rb (REXML::Text.unnormalize): check above attribute.
+
 Fri Feb 22 17:36:23 2013  NARUSE, Yui  <naruse@r...>
 
 	* test/test_rbconfig.rb (TestRbConfig): fix r39372.
Index: lib/rexml/document.rb
===================================================================
--- lib/rexml/document.rb	(revision 39383)
+++ lib/rexml/document.rb	(revision 39384)
@@ -255,6 +255,18 @@ module REXML https://github.com/ruby/ruby/blob/trunk/lib/rexml/document.rb#L255
       return @@entity_expansion_limit
     end
 
+    @@entity_expansion_text_limit = 10_240
+
+    # Set the entity expansion limit. By default the limit is set to 10240.
+    def Document::entity_expansion_text_limit=( val )
+      @@entity_expansion_text_limit = val
+    end
+
+    # Get the entity expansion limit. By default the limit is set to 10000.
+    def Document::entity_expansion_text_limit
+      return @@entity_expansion_text_limit
+    end
+
     attr_reader :entity_expansion_count
 
     def record_entity_expansion
Index: lib/rexml/text.rb
===================================================================
--- lib/rexml/text.rb	(revision 39383)
+++ lib/rexml/text.rb	(revision 39384)
@@ -380,25 +380,35 @@ module REXML https://github.com/ruby/ruby/blob/trunk/lib/rexml/text.rb#L380
 
     # Unescapes all possible entities
     def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
+      sum = 0
       string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
-        ref = $&
-        if ref[1] == ?#
-          if ref[2] == ?x
-            [ref[3...-1].to_i(16)].pack('U*')
-          else
-            [ref[2...-1].to_i].pack('U*')
-          end
-        elsif ref == '&amp;'
-          '&'
-        elsif filter and filter.include?( ref[1...-1] )
-          ref
-        elsif doctype
-          doctype.entity( ref[1...-1] ) or ref
+        s = Text.expand($&, doctype, filter)
+        if sum + s.bytesize > Document.entity_expansion_text_limit
+          raise "entity expansion has grown too large"
         else
-          entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
-          entity_value ? entity_value.value : ref
+          sum += s.bytesize
         end
+        s
       }
     end
+
+    def Text.expand(ref, doctype, filter)
+      if ref[1] == ?#
+        if ref[2] == ?x
+          [ref[3...-1].to_i(16)].pack('U*')
+        else
+          [ref[2...-1].to_i].pack('U*')
+        end
+      elsif ref == '&amp;'
+        '&'
+      elsif filter and filter.include?( ref[1...-1] )
+        ref
+      elsif doctype
+        doctype.entity( ref[1...-1] ) or ref
+      else
+        entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
+        entity_value ? entity_value.value : ref
+      end
+    end
   end
 end
Index: test/rexml/test_entity.rb
===================================================================
--- test/rexml/test_entity.rb	(revision 39383)
+++ test/rexml/test_entity.rb	(revision 39384)
@@ -104,6 +104,24 @@ class EntityTester < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/rexml/test_entity.rb#L104
     assert_equal source, out
   end
 
+  def test_entity_string_limit
+    template = '<!DOCTYPE bomb [ <!ENTITY a "^" > ]> <bomb>$</bomb>'
+    len      = 5120 # 5k per entity
+    template.sub!(/\^/, "B" * len)
+
+    # 10k is OK
+    entities = '&a;' * 2 # 5k entity * 2 = 10k
+    xmldoc = REXML::Document.new(template.sub(/\$/, entities))
+    assert_equal(len * 2, xmldoc.root.text.bytesize)
+
+    # above 10k explodes
+    entities = '&a;' * 3 # 5k entity * 2 = 15k
+    xmldoc = REXML::Document.new(template.sub(/\$/, entities))
+    assert_raises(RuntimeError) do
+      xmldoc.root.text
+    end
+  end
+
   def test_raw
     source = '<!DOCTYPE foo [
 <!ENTITY ent "replace">

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]