changeset 8240:bd37c6d3f3d0

Add tests for NPE when calling tryAdvance/forEachRemaining with a null consumer.
author psandoz
date Wed, 17 Apr 2013 11:39:48 +0200
parents 344772588886
children bb563e90c4fb
files src/share/classes/java/util/ArrayList.java src/share/classes/java/util/PriorityQueue.java src/share/classes/java/util/Vector.java test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java
diffstat 5 files changed, 117 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/ArrayList.java	Wed Apr 17 00:21:38 2013 -0400
+++ b/src/share/classes/java/util/ArrayList.java	Wed Apr 17 11:39:48 2013 +0200
@@ -1362,6 +1362,8 @@
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
             int hi = getFence(), i = index;
             if (i < hi) {
                 index = i + 1;
--- a/src/share/classes/java/util/PriorityQueue.java	Wed Apr 17 00:21:38 2013 -0400
+++ b/src/share/classes/java/util/PriorityQueue.java	Wed Apr 17 11:39:48 2013 +0200
@@ -852,6 +852,8 @@
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
             int hi = getFence(), lo = index;
             if (lo >= 0 && lo < hi) {
                 index = lo + 1;
--- a/src/share/classes/java/util/Vector.java	Wed Apr 17 00:21:38 2013 -0400
+++ b/src/share/classes/java/util/Vector.java	Wed Apr 17 11:39:48 2013 +0200
@@ -1368,6 +1368,8 @@
         @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
             int i;
+            if (action == null)
+                throw new NullPointerException();
             if (getFence() > (i = index)) {
                 index = i + 1;
                 action.accept((E)array[i]);
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java	Wed Apr 17 00:21:38 2013 -0400
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/SpliteratorTraversingAndSplittingTest.java	Wed Apr 17 11:39:48 2013 +0200
@@ -42,6 +42,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.ConcurrentModificationException;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -187,6 +188,8 @@
 
                 @Override
                 public boolean tryAdvance(Consumer<? super Integer> action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (it.hasNext()) {
                         action.accept(it.next());
                         return true;
@@ -196,7 +199,7 @@
                     }
                 }
             }
-            db.add("new Spliterators.AbstractAdvancingSpliterator()",
+            db.add("new Spliterators.AbstractSpliterator()",
                    () -> new SpliteratorFromIterator(exp.iterator(), exp.size()));
 
             // Collections
@@ -426,6 +429,13 @@
 
     @Test(dataProvider = "Spliterator<Integer>")
     @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testNullPointerException(String description, Collection exp, Supplier<Spliterator> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining(null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance(null));
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
     public void testForEach(String description, Collection exp, Supplier<Spliterator> s) {
         testForEach(exp, s, (Consumer<Object> b) -> b);
     }
@@ -531,6 +541,8 @@
 
                 @Override
                 public boolean tryAdvance(IntConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -577,6 +589,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((IntConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((IntConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
     public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
         testForEach(exp, s, intBoxingConsumer());
     }
@@ -676,6 +694,8 @@
 
                 @Override
                 public boolean tryAdvance(LongConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -729,6 +749,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongNullPointerException(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((LongConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((LongConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
     public void testLongForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
         testForEach(exp, s, longBoxingConsumer());
     }
@@ -828,6 +854,8 @@
 
                 @Override
                 public boolean tryAdvance(DoubleConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -881,6 +909,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleNullPointerException(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((DoubleConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((DoubleConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
     public void testDoubleForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
         testForEach(exp, s, doubleBoxingConsumer());
     }
@@ -1278,4 +1312,22 @@
         });
         return result;
     }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        assertTrue(expected.isInstance(caught),
+                   String.format("Exception thrown %s not an instance of %s",
+                                 caught.getClass().getName(), expected.getName()));
+    }
+
 }
--- a/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java	Wed Apr 17 00:21:38 2013 -0400
+++ b/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java	Wed Apr 17 11:39:48 2013 +0200
@@ -184,6 +184,8 @@
 
                 @Override
                 public boolean tryAdvance(Consumer<? super Integer> action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (it.hasNext()) {
                         action.accept(it.next());
                         return true;
@@ -193,7 +195,7 @@
                     }
                 }
             }
-            db.add("new Spliterators.AbstractAdvancingSpliterator()",
+            db.add("new Spliterators.AbstractSpliterator()",
                    () -> new SpliteratorFromIterator(exp.iterator(), exp.size()));
 
             // Collections
@@ -373,23 +375,23 @@
             // Collections.synchronized/unmodifiable/checked wrappers
             db.addCollection(Collections::unmodifiableCollection);
             db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c)));
-            db.addCollection(c -> Collections.unmodifiableSortedSet(new TreeSet<Integer>(c)));
-            db.addList(c -> Collections.unmodifiableList(new ArrayList(c)));
+            db.addCollection(c -> Collections.unmodifiableSortedSet(new TreeSet<>(c)));
+            db.addList(c -> Collections.unmodifiableList(new ArrayList<>(c)));
             db.addMap(Collections::unmodifiableMap);
             db.addMap(m -> Collections.unmodifiableSortedMap(new TreeMap<>(m)));
 
             db.addCollection(Collections::synchronizedCollection);
             db.addCollection(c -> Collections.synchronizedSet(new HashSet<>(c)));
-            db.addCollection(c -> Collections.synchronizedSortedSet(new TreeSet<Integer>(c)));
-            db.addList(c -> Collections.synchronizedList(new ArrayList(c)));
+            db.addCollection(c -> Collections.synchronizedSortedSet(new TreeSet<>(c)));
+            db.addList(c -> Collections.synchronizedList(new ArrayList<>(c)));
             db.addMap(Collections::synchronizedMap);
             db.addMap(m -> Collections.synchronizedSortedMap(new TreeMap<>(m)));
 
             db.addCollection(c -> Collections.checkedCollection(c, Integer.class));
             db.addCollection(c -> Collections.checkedQueue(new ArrayDeque<>(c), Integer.class));
             db.addCollection(c -> Collections.checkedSet(new HashSet<>(c), Integer.class));
-            db.addCollection(c -> Collections.checkedSortedSet(new TreeSet<Integer>(c), Integer.class));
-            db.addList(c -> Collections.checkedList(new ArrayList(c), Integer.class));
+            db.addCollection(c -> Collections.checkedSortedSet(new TreeSet<>(c), Integer.class));
+            db.addList(c -> Collections.checkedList(new ArrayList<>(c), Integer.class));
             db.addMap(c -> Collections.checkedMap(c, Integer.class, Integer.class));
             db.addMap(m -> Collections.checkedSortedMap(new TreeMap<>(m), Integer.class, Integer.class));
 
@@ -423,6 +425,13 @@
 
     @Test(dataProvider = "Spliterator<Integer>")
     @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testNullPointerException(String description, Collection exp, Supplier<Spliterator> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining(null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance(null));
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
     public void testForEach(String description, Collection exp, Supplier<Spliterator> s) {
         testForEach(exp, s, (Consumer<Object> b) -> b);
     }
@@ -528,6 +537,8 @@
 
                 @Override
                 public boolean tryAdvance(IntConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -574,6 +585,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((IntConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((IntConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
     public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
         testForEach(exp, s, intBoxingConsumer());
     }
@@ -673,6 +690,8 @@
 
                 @Override
                 public boolean tryAdvance(LongConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -726,6 +745,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongNullPointerException(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((LongConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((LongConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
     public void testLongForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
         testForEach(exp, s, longBoxingConsumer());
     }
@@ -825,6 +850,8 @@
 
                 @Override
                 public boolean tryAdvance(DoubleConsumer action) {
+                    if (action == null)
+                        throw new NullPointerException();
                     if (index < a.length) {
                         action.accept(a[index++]);
                         return true;
@@ -878,6 +905,12 @@
     }
 
     @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleNullPointerException(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((DoubleConsumer) null));
+        executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((DoubleConsumer) null));
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
     public void testDoubleForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
         testForEach(exp, s, doubleBoxingConsumer());
     }
@@ -1275,4 +1308,22 @@
         });
         return result;
     }
+
+    private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        assertTrue(expected.isInstance(caught),
+                   String.format("Exception thrown %s not an instance of %s",
+                                 caught.getClass().getName(), expected.getName()));
+    }
+
 }