【问题标题】:REXML :: RuntimeError (entity expansion has grown too large)REXML :: RuntimeError(实体扩展已变得太大)
【发布时间】:2013-03-23 23:06:43
【问题描述】:

今天升级到 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 的大小更改为更大的数字,错误就消失了。

有没有风险较小的解决方案?

【问题讨论】:

  • 我的 p392 版本说它甚至无法识别该设置。导致我的部署失败。

标签: ruby-on-rails ruby rexml


【解决方案1】:

当您发送太多内容作为 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

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/

【讨论】:

    【解决方案2】:

    这听起来像是很多 XML。你真的需要得到所有吗?也许您可以从远程服务器请求某些字段?一种选择可能是尝试另一个 XML 解析器(例如Nokogiri)。另一种选择可能是使用 XML 以外的东西作为传输(JSON?二进制?)。

    【讨论】:

    • 我正在通过 Quickbooks Web 连接器和销售点提取零售商店的商品库存...所有这些商店都有超过 25 种商品库存,因此需要大量 XML。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2021-03-22
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    相关资源
    最近更新 更多