在今天升级到ruby-1.9.3-p392之后,rexml在尝试检索超过一定大小的xml响应时抛出一个运行时错误-一切正常,并且在接收低于25条xml记录时不会抛出任何错误,但是一旦达到某个xml响应长度阈值,我就会得到这个错误:

Error occurred while parsing request parameters.
Contents:

RuntimeError (entity expansion has grown too large):
  /.rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/rexml/text.rb:387:in `block in unnormalize'

我意识到这在最新的ruby版本中有所改变:
http://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/
作为一个快速修复,我将REXML::Document.entity_expansion_text_limit的大小改为一个更大的数字,然后错误就消失了。
有没有风险较小的解决方案?

最佳答案

当您将太多内容作为XML响应发送时,会产生此问题。
要解决此问题:需要限制单个节点中的数据(从以下文件引发错误:
ruby-2.1.2/lib/ruby/2.1.0/rexml/text.rb

# Unescapes all possible entities
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
  sum = 0
  string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
    s = Text.expand($&, doctype, filter)
    if sum + s.bytesize > Security.entity_expansion_text_limit
      raise "entity expansion has grown too large"
    else
      sum += s.bytesize
    end
    s
  }
end

该限制默认为10240,即每个节点10K数据。
rexml已经默认为每个文档只允许10000个实体替换,因此实体替换可以生成的最大文本量大约为98兆字节。(参见https://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/

08-08 02:44