今天升级到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
的大小更改为更大的数字,错误消失了。
风险较小的解决方案是否存在?
答案 0 :(得分:3)
当您将过多内容作为XML响应发送时,会生成此问题。
解决此问题:您需要限制单个节点中的数据(< 10k)(而不是发送整个数据,显示截断的数据并提供单独的链接以查看完整内容)
从以下文件中引发错误:
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
限制ruby-2.1.2/lib/ruby/2.1.0/rexml/text.rb
默认为10240,这意味着每个节点有10k数据。
REXML默认只允许每个文档允许10000个实体替换,因此实体替换可以生成的最大文本量大约为98兆字节。 (参考https://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/)
答案 1 :(得分:0)
这听起来像很多XML。你真的需要得到所有这些吗?也许你只能从远程服务器请求某些字段?一种选择可能是尝试另一种XML解析器(例如Nokogiri)。另一种选择可能使用XML之外的东西作为传输(JSON?Binary?)。