8225397: Integer value miscalculation in toString() method of BitSet
authorigerasim
Thu, 06 Jun 2019 17:20:19 -0700
changeset 55274 8cd2d6dee328
parent 55273 64b76867851b
child 55275 0a7af38ef32a
8225397: Integer value miscalculation in toString() method of BitSet Reviewed-by: aph
src/java.base/share/classes/java/util/BitSet.java
test/jdk/java/util/BitSet/HugeToString.java
--- a/src/java.base/share/classes/java/util/BitSet.java	Thu Jun 06 16:06:10 2019 -0700
+++ b/src/java.base/share/classes/java/util/BitSet.java	Thu Jun 06 17:20:19 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1182,9 +1182,13 @@
     public String toString() {
         checkInvariants();
 
+        final int MAX_INITIAL_CAPACITY = Integer.MAX_VALUE - 8;
         int numBits = (wordsInUse > 128) ?
             cardinality() : wordsInUse * BITS_PER_WORD;
-        StringBuilder b = new StringBuilder(6*numBits + 2);
+        // Avoid overflow in the case of a humongous numBits
+        int initialCapacity = (numBits <= (MAX_INITIAL_CAPACITY - 2) / 6) ?
+            6 * numBits + 2 : MAX_INITIAL_CAPACITY;
+        StringBuilder b = new StringBuilder(initialCapacity);
         b.append('{');
 
         int i = nextSetBit(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/BitSet/HugeToString.java	Thu Jun 06 17:20:19 2019 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8225397
+ * @summary Integer value miscalculation in toString() method of BitSet
+ * @run main/othervm -Xms250m HugeToString
+ */
+
+import java.util.BitSet;
+
+public final class HugeToString {
+
+    public static void main(String[] args) {
+        BitSet bs = new BitSet(500_000_000);
+        bs.flip(0, 500_000_000);
+        try {
+            bs.toString();
+        } catch (OutOfMemoryError expected) {
+        } catch (Throwable t) {
+            throw new AssertionError("Unexpected exception", t);
+        }
+    }
+}