aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org/apache
diff options
context:
space:
mode:
authorClaude Brisson <cbrisson@apache.org>2018-10-14 16:58:57 +0000
committerClaude Brisson <cbrisson@apache.org>2018-10-14 16:58:57 +0000
commit372506d0d576d33b4564f687206cf961c90e2e88 (patch)
tree3f101b5d252016457537d250818b38c5f953eb45 /velocity-engine-core/src/main/java/org/apache
parent8cc3695d7fbe0d7e18e85426d6f23ae4928d705b (diff)
downloadapache-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.java161
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);
}
/**