You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/06/29 03:19:50 UTC

groovy git commit: GROOVY-2972: ObjectRange.size() should return Integer.MAX_VALUE on overflow

Repository: groovy
Updated Branches:
  refs/heads/master 941b3c57f -> f529b787d


GROOVY-2972: ObjectRange.size() should return Integer.MAX_VALUE on overflow


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f529b787
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f529b787
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f529b787

Branch: refs/heads/master
Commit: f529b787dd0732a9c65505910807c1b0e7a84785
Parents: 941b3c5
Author: Thibault Kruse <th...@gmx.de>
Authored: Sun Nov 1 13:05:36 2015 +0100
Committer: paulk <pa...@asert.com.au>
Committed: Wed Jun 29 12:59:49 2016 +1000

----------------------------------------------------------------------
 src/main/groovy/lang/ObjectRange.java     | 30 ++++++++++++++++++++------
 src/test/groovy/lang/ObjectRangeTest.java |  5 +++++
 2 files changed, 28 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/f529b787/src/main/groovy/lang/ObjectRange.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/ObjectRange.java b/src/main/groovy/lang/ObjectRange.java
index 927e1e8..b3be8eb 100644
--- a/src/main/groovy/lang/ObjectRange.java
+++ b/src/main/groovy/lang/ObjectRange.java
@@ -271,33 +271,49 @@ public class ObjectRange extends AbstractList implements Range {
 
     public int size() {
         if (size == -1) {
+            int tempsize = 0;
             if ((from instanceof Integer || from instanceof Long)
                     && (to instanceof Integer || to instanceof Long)) {
                 // let's fast calculate the size
-                long fromNum = ((Number) from).longValue();
-                long toNum = ((Number) to).longValue();
-                size = (int) (toNum - fromNum + 1);
+                BigInteger fromNum = new BigInteger(from.toString());
+                BigInteger toNum = new BigInteger(to.toString());
+                BigInteger sizeNum = toNum.subtract(fromNum).add(new BigInteger("1"));
+                tempsize = sizeNum.intValue();
+                if (!BigInteger.valueOf(tempsize).equals(sizeNum)) {
+                    tempsize = Integer.MAX_VALUE;
+                }
             } else if (from instanceof Character && to instanceof Character) {
                 // let's fast calculate the size
                 char fromNum = (Character) from;
                 char toNum = (Character) to;
-                size = toNum - fromNum + 1;
+                tempsize = toNum - fromNum + 1;
             } else if (((from instanceof BigDecimal || from instanceof BigInteger ) && to instanceof Number) ||
                     ((to instanceof BigDecimal || to instanceof BigInteger) && from instanceof Number)) {
                 // let's fast calculate the size
                 BigDecimal fromNum = new BigDecimal(from.toString());
                 BigDecimal toNum = new BigDecimal(to.toString());
                 BigInteger sizeNum = toNum.subtract(fromNum).add(new BigDecimal(1.0)).toBigInteger();
-                size = sizeNum.intValue();
+                tempsize = sizeNum.intValue();
+                if (!BigInteger.valueOf(tempsize).equals(sizeNum)) {
+                    tempsize = Integer.MAX_VALUE;
+                }
             } else {
                 // let's brute-force calculate the size by iterating start to end
                 Iterator iter = new StepIterator(this, 1);
-                int tempsize = 0;
                 while (iter.hasNext()) {
                     tempsize++;
+                    // integer overflow
+                    if (tempsize < 0) {
+                        break;
+                    }
                     iter.next();
                 }
-                size = tempsize;            }
+            }
+            // integer overflow
+            if (tempsize < 0) {
+                tempsize = Integer.MAX_VALUE;
+            }
+            size = tempsize;
         }
         return size;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/f529b787/src/test/groovy/lang/ObjectRangeTest.java
----------------------------------------------------------------------
diff --git a/src/test/groovy/lang/ObjectRangeTest.java b/src/test/groovy/lang/ObjectRangeTest.java
index fc0e8bc..fb64ab2 100644
--- a/src/test/groovy/lang/ObjectRangeTest.java
+++ b/src/test/groovy/lang/ObjectRangeTest.java
@@ -69,6 +69,11 @@ public class ObjectRangeTest extends TestCase {
         assertEquals(5, mixed.size());
         mixed = createRange('7',  new BigDecimal("59.5"));
         assertEquals(5, mixed.size());
+
+        // integer overflow cases
+        assertEquals(Integer.MAX_VALUE, new ObjectRange(0L, Integer.MAX_VALUE).size());
+        assertEquals(Integer.MAX_VALUE, new ObjectRange(Long.MIN_VALUE, Long.MAX_VALUE).size());
+        assertEquals(Integer.MAX_VALUE, new ObjectRange(new BigInteger("-10"), new BigInteger(Long.toString((long) Integer.MAX_VALUE) + 1L)).size());
     }
 
     public void testProperties() {