mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-29 18:03:32 -04:00
This prevents `CONCAT` from using an unbounded amount of memory by hooking it's temporary value into the circuit breaker. To do so, it makes *all* `ExpressionEvaluator`s `Releasable`. Most of the changes in this PR just plumb that through to every evaluator. The rest of the changes correctly release evaluators after their use. I considered another tactic but didn't like it as much, even though the number of changes would be smaller - I could have created a fresh, `Releasable` temporary value for every `Page`. It would be pretty contained keep the releasable there. But I wanted to share the temporary state across runs to avoid a bunch of allocations. Here's a script that used to crash before this PR but is fine after: ``` curl -uelastic:password -XDELETE localhost:9200/test curl -HContent-Type:application/json -uelastic:password -XPUT localhost:9200/test -d'{ "mappings": { "properties": { "short": { "type": "keyword" } } } }' curl -HContent-Type:application/json -uelastic:password -XPUT localhost:9200/test/_doc/1?refresh -d'{"short": "short"}' echo -n '{"query": "FROM test ' > /tmp/evil for i in {0..9}; do echo -n '| EVAL short = CONCAT(short' >> /tmp/evil for j in {1..9}; do echo -n ', short' >> /tmp/evil done echo -n ')' >> /tmp/evil done echo '| EVAL len = LENGTH(short) | KEEP len"}'>> /tmp/evil curl -HContent-Type:application/json -uelastic:password -XPOST localhost:9200/_query?pretty --data-binary @/tmp/evil ```
1 line
No EOL
877 B
XML
1 line
No EOL
877 B
XML