2013-03-23 11 views
10

Nach dem Upgrade auf Ruby-1.9.3-p392 heute, REXML löst einen Laufzeitfehler beim Versuch, eine XML-Antwort über eine bestimmte Größe abrufen - alles funktioniert gut und kein Fehler ausgelöst wird, wenn unter 25 XML-Datensätze empfangen, aber sobald ein bestimmtes XML-Antwortlängen-Schwellenwert erreicht ist, ich diese Fehlermeldung erhalten:REXML :: RuntimeError (Entity-Erweiterung ist zu groß gewachsen)

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' 

ich weiß, dies wurde in der neuesten Ruby-Version geändert: http://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/

Als schnelle Lösung habe ich die Größe von REXML::Document.entity_expansion_text_limit zu einer größeren Zahl geändert und die Fehler geht weg.

Gibt es eine weniger riskante Lösung?

+0

Meine Version von P392 sagt, dass es diese Einstellung nicht einmal erkennt. Führt zu einem Fehlschlagen der Bereitstellung. – AKWF

Antwort

0

Das klingt wie eine Menge von XML. Müssen Sie wirklich alles bekommen? Vielleicht können Sie nur bestimmte Felder vom Remote-Server anfordern? Eine Option könnte sein, einen anderen XML-Parser auszuprobieren (z. B. Nokogiri). Eine andere Möglichkeit, etwas anderes als XML als Transport zu verwenden (JSON? Binary?).

+0

Ich ziehe Artikelinventar für Einzelhandelsgeschäfte durch Quickbooks Web Connector und Point of Sale ... alle diese Läden haben mehr als 25 Artikel auf Lager, daher zieht das große XML. – user2203451

3

Dieses Problem wird generiert, wenn Sie zu viel Inhalt als XML-Antwort senden.

um dieses Problem zu beheben: Sie müssen die Daten (< 10k) in dem einzelnen Knoten beschränken (Anstatt die gesamten Daten zu senden, abgeschnittene Daten zeigen, und einen separaten Link bietet vollen Inhalt zu sehen)

Den Fehler wird aus der folgenden Datei erhöht: 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 

die Grenze ruby-2.1.2/lib/ruby/2.1.0/rexml/text.rb standardmäßig auf 10240 die 10K-Daten pro Knoten bedeutet.

REXML verwendet standardmäßig standardmäßig nur 10000 Entitätssubstitutionen pro Dokument, sodass die maximale Textmenge, die durch die Entitätssubstitution generiert werden kann, rund 98 Megabyte beträgt. (Siehe https://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/)

+1

danke Sir für diese wertvolle Antwort .... B-) –