Description
FULL PRODUCT VERSION :
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
SunOS opteron 5.11 snv_125 i86pc i386 i86pc
A DESCRIPTION OF THE PROBLEM :
It is possible to create BigInteger so large that its bit length larger than Integer.MAX_VALUE. In these case bitLength() method returns negative "int" value and toByteArray() method crashes.
IMHO, the range of possible BigInteger values should be limited either to a range
[-2^Integer.MAX_VALUE,2^Integer.MAX_VALUE-1] with bit length <= Integer.MAX_VALUE
or to a symmetrical range
[-2^Integer.MAX_VALUE+1,2^Integer.MAX_VALUE-1].
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Save "Source code for an executable test case" as TestLargeBigInteger.java
2) javac TestLargeBigInteger.java
3) java TestLargeBigInteger
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect ArithmeticExceptionon when the result of shiftLeft() method is out of suggested BigInteger range.
--------------------
Exception in thread "main" java.lang.ArithmeticException: BigInteger overflow
at java_math.BigInteger.<init>(BigInteger.java:949)
at java_math.BigInteger.shiftLeft(BigInteger.java:2129)
at TestLargeBigInteger.main(TestLargeBigInteger.java:6)
ACTUAL -
The bitLength() method returns negative result and toByteArray method throws an exception.
-------------------------
bitLength=-2147483648
java.lang.NegativeArraySizeException
at java.math.BigInteger.toByteArray(BigInteger.java:2667)
at TestLargeBigInteger.main(TestLargeBigInteger.java:9)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.math.BigInteger;
public class TestLargeBigInteger {
public static void main(String[] args) {
BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE); // x = 2^Integer.MAX_VALUE;
System.out.println("bitLength="+x.bitLength());
try {
byte[] bytes = x.toByteArray();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I am preparing a fix and a test for this bug:
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/java_math/src/java_math/BigInteger.java?rev=17
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/HugeValues.java?rev=17
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/ExtremeShiftingTests.java?rev=17
However I'm going to test more before I submit a WebRev.
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
SunOS opteron 5.11 snv_125 i86pc i386 i86pc
A DESCRIPTION OF THE PROBLEM :
It is possible to create BigInteger so large that its bit length larger than Integer.MAX_VALUE. In these case bitLength() method returns negative "int" value and toByteArray() method crashes.
IMHO, the range of possible BigInteger values should be limited either to a range
[-2^Integer.MAX_VALUE,2^Integer.MAX_VALUE-1] with bit length <= Integer.MAX_VALUE
or to a symmetrical range
[-2^Integer.MAX_VALUE+1,2^Integer.MAX_VALUE-1].
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Save "Source code for an executable test case" as TestLargeBigInteger.java
2) javac TestLargeBigInteger.java
3) java TestLargeBigInteger
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect ArithmeticExceptionon when the result of shiftLeft() method is out of suggested BigInteger range.
--------------------
Exception in thread "main" java.lang.ArithmeticException: BigInteger overflow
at java_math.BigInteger.<init>(BigInteger.java:949)
at java_math.BigInteger.shiftLeft(BigInteger.java:2129)
at TestLargeBigInteger.main(TestLargeBigInteger.java:6)
ACTUAL -
The bitLength() method returns negative result and toByteArray method throws an exception.
-------------------------
bitLength=-2147483648
java.lang.NegativeArraySizeException
at java.math.BigInteger.toByteArray(BigInteger.java:2667)
at TestLargeBigInteger.main(TestLargeBigInteger.java:9)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.math.BigInteger;
public class TestLargeBigInteger {
public static void main(String[] args) {
BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE); // x = 2^Integer.MAX_VALUE;
System.out.println("bitLength="+x.bitLength());
try {
byte[] bytes = x.toByteArray();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I am preparing a fix and a test for this bug:
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/java_math/src/java_math/BigInteger.java?rev=17
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/HugeValues.java?rev=17
http://kenai.com/projects/rigorousnum/sources/java_math/content/trunk/BigIntegerTests/src/ExtremeShiftingTests.java?rev=17
However I'm going to test more before I submit a WebRev.
Attachments
Issue Links
- duplicates
-
JDK-8011942 BigInteger returns an int for bitLength()
- Closed
- relates to
-
JDK-6371401 java.math.BigInteger.shift(Integer.MIN_VALUE) throws StackOverflowError
- Resolved
-
JDK-8021203 BigInteger.doubleValue/floatValue returns 0.0 instead of Infinity
- Closed
-
JDK-8021204 Constructor BigInteger(String val, int radix) doesn't detect overflow
- Closed
-
JDK-8027595 Enable BigInteger overflow tests in JTREG
- Closed
-
JDK-8022780 Incorrect BigInteger division because of MutableBigInteger.bitLength() overflow
- Closed
(1 relates to)