diff options
author | Claude Brisson <cbrisson@apache.org> | 2018-10-14 16:58:57 +0000 |
---|---|---|
committer | Claude Brisson <cbrisson@apache.org> | 2018-10-14 16:58:57 +0000 |
commit | 372506d0d576d33b4564f687206cf961c90e2e88 (patch) | |
tree | 3f101b5d252016457537d250818b38c5f953eb45 /velocity-engine-core/src/main/java/org/apache | |
parent | 8cc3695d7fbe0d7e18e85426d6f23ae4928d705b (diff) | |
download | apache-velocity-engine-372506d0d576d33b4564f687206cf961c90e2e88.tar.gz |
[VELOCITY-886] Avoid OOM in large integer loops
git-svn-id: https://svn.apache.org/repos/asf/velocity/engine/trunk@1843853 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'velocity-engine-core/src/main/java/org/apache')
-rw-r--r-- | velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java | 161 |
1 files changed, 140 insertions, 21 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java index 26ba78b7..117e2a6d 100644 --- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java +++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java @@ -26,8 +26,9 @@ import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.DuckType; import org.apache.velocity.util.StringUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.AbstractList; +import java.util.Iterator; +import java.util.ListIterator; /** * handles the range 'operator' [ n .. m ] @@ -64,6 +65,141 @@ public class ASTIntegerRange extends SimpleNode return visitor.visit(this, data); } + public static class IntegerRange extends AbstractList<Integer> + { + public class RangeIterator implements ListIterator<Integer> + { + private int value; + + public RangeIterator() + { + value = left - delta; + } + + public RangeIterator(int startIndex) + { + value = left + (startIndex - 1) * delta; + } + + @Override + public Integer next() + { + value += delta; + return value; + } + + @Override + public boolean hasPrevious() + { + return value != left - delta; + } + + @Override + public Integer previous() + { + value -= delta; + return value; + } + + @Override + public int nextIndex() + { + return (value + delta - left) * delta; + } + + @Override + public int previousIndex() + { + return (value - delta - left) * delta; + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("integer range is read only"); + } + + @Override + public void set(Integer integer) + { + throw new UnsupportedOperationException("integer range is read only"); + } + + @Override + public void add(Integer integer) + { + throw new UnsupportedOperationException("integer range is read only"); + } + + @Override + public boolean hasNext() + { + return value != right; + } + } + + private int left; + private int right; + private int delta; + + public IntegerRange(int left, int right, int delta) + { + this.left = left; + this.right = right; + this.delta = delta; + } + + @Override + public Iterator<Integer> iterator() + { + return new RangeIterator(); + } + + @Override + public Integer get(int index) + { + int ret = left + delta * index; + if (delta > 0 && ret > right || delta < 0 && ret < right) + { + throw new IndexOutOfBoundsException(); + } + return ret; + } + + @Override + public int indexOf(Object o) + { + int v = DuckType.asNumber(o).intValue(); + v -= left; + v *= delta; + return v >= 0 && v < size() ? v : -1; + } + + @Override + public int lastIndexOf(Object o) + { + return indexOf(o); + } + + @Override + public ListIterator<Integer> listIterator() + { + return new RangeIterator(); + } + + @Override + public ListIterator<Integer> listIterator(int index) + { + return new RangeIterator(index); + } + + @Override + public int size() + { + return Math.abs(right - left) + 1; + } + } + /** * does the real work. Creates an Vector of Integers with the * right value range @@ -123,7 +259,6 @@ public class ASTIntegerRange extends SimpleNode return null; } - /* * get the two integer values of the ends of the range */ @@ -132,32 +267,16 @@ public class ASTIntegerRange extends SimpleNode int r = ((Number) right).intValue(); /* - * find out how many there are - */ - - int nbrElements = Math.abs( l - r ); - nbrElements += 1; - - /* * Determine whether the increment is positive or negative. */ int delta = ( l >= r ) ? -1 : 1; /* - * Fill the range with the appropriate values. + * Return the corresponding integer range */ - List elements = new ArrayList(nbrElements); - int value = l; - - for (int i = 0; i < nbrElements; i++) - { - elements.add(value); - value += delta; - } - - return elements; + return new IntegerRange(l, r, delta); } /** |