In the RSS xml stylesheet code there is a regex with backtracking that results in an O(N^2) computation when parsing specifically-shaped RSS feeds.
Specifically, the CONTENT_PATTERN regex at lib/rss/parser.rb:394.
([^=]+)= in that regex greedily consumes characters and backtracks quadratically.
Example code:
require"rss"require"benchmark"[10000,20000,40000,80000].eachdo |n|
payload="a" * nfeed=%Q{<?xml-stylesheet #{payload}=?>\n<rss version="2.0"><channel><title>t</title><link>http://x</link><description>d</description></channel></rss>}t=Benchmark.realtime{RSS::Parser.parse(feed,false)rescuenil}printf("n=%d total_parse=%.4fs\n",n,t)endOutput on Ruby 3.4.9:
n=10000 total_parse=0.2715s
n=20000 total_parse=1.0939s
n=40000 total_parse=4.3082s
n=80000 total_parse=17.7647s
You can easily end up with multi-minute parsing times on specific XML, so we should probably fix that to improve the parse performance.
In the RSS xml stylesheet code there is a regex with backtracking that results in an O(N^2) computation when parsing specifically-shaped RSS feeds.
Specifically, the
CONTENT_PATTERNregex atlib/rss/parser.rb:394.([^=]+)=in that regex greedily consumes characters and backtracks quadratically.Example code:
Output on Ruby 3.4.9:
You can easily end up with multi-minute parsing times on specific XML, so we should probably fix that to improve the parse performance.