Ticket #123: ticket_123.patch

File ticket_123.patch, 2.3 kB (added by rubys, 5 months ago)

test case and fix

  • test/entity.rb

     
    141141                assert_equal("&", REXML::Text.new("&", false, nil, true).to_s) 
    142142                #assert_equal("&", REXML::Text.new("&", false, false).to_s) 
    143143        end 
     144 
     145        def test_single_pass_unnormalization 
     146                assert_equal '&&', Text::unnormalize('&&') 
     147        end 
    144148end 
  • src/rexml/text.rb

     
    308308 
    309309    # Unescapes all possible entities 
    310310    def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil ) 
    311       rv = string.clone 
    312       rv.gsub!( /\r\n?/, "\n" ) 
    313       matches = rv.scan( REFERENCE ) 
    314       return rv if matches.size == 0 
    315       rv.gsub!( NUMERICENTITY ) {|m| 
    316         m=$1 
    317         m = "0#{m}" if m[0] == ?x 
    318         [Integer(m)].pack('U*') 
    319       } 
    320       matches.collect!{|x|x[0]}.compact! 
    321       if matches.size > 0 
    322         if doctype 
    323           matches.each do |entity_reference| 
    324             unless filter and filter.include?(entity_reference) 
    325               entity_value = doctype.entity( entity_reference ) 
    326               re = /&#{entity_reference};/ 
    327               rv.gsub!( re, entity_value ) if entity_value 
    328             end 
     311      string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) { |ref| 
     312        if ref[1] == ?# 
     313          if ref[2] == ?x 
     314            [ref[3...-1].to_i(16)].pack('U*') 
     315          else 
     316            [ref[2...-1].to_i].pack('U*') 
    329317          end 
     318        elsif ref == '&' 
     319          '&' 
     320        elsif filter and filter.include?( ref[1...-1] ) 
     321          ref 
     322        elsif doctype 
     323          doctype.entity( ref[1...-1] ) or ref 
    330324        else 
    331           matches.each do |entity_reference| 
    332             unless filter and filter.include?(entity_reference) 
    333               entity_value = DocType::DEFAULT_ENTITIES[ entity_reference ] 
    334               re = /&#{entity_reference};/ 
    335               rv.gsub!( re, entity_value.value ) if entity_value 
    336             end 
    337           end 
     325          entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ] 
     326          entity_value ? entity_value.value : ref 
    338327        end 
    339         rv.gsub!( /&/, '&' ) 
    340       end 
    341       rv 
     328      } 
    342329    end 
    343330  end 
    344331end