# HG changeset patch # User smarks # Date 1501695275 25200 # Node ID 4fc2a4a29f3de4714117631cfb1d7de7b997e69a # Parent 7a4b85711089d56104e8b7880f8103b1c229123b 8174109: Better queuing priorities Reviewed-by: chegar, dfuchs, rriggs, alanb, robm, rhalade, jeff, ahgross diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/io/ObjectInputStream.java --- a/src/java.base/share/classes/java/io/ObjectInputStream.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java Wed Aug 02 10:34:35 2017 -0700 @@ -1283,6 +1283,33 @@ } /** + * Checks the given array type and length to ensure that creation of such + * an array is permitted by this ObjectInputStream. The arrayType argument + * must represent an actual array type. + * + * This private method is called via SharedSecrets. + * + * @param arrayType the array type + * @param arrayLength the array length + * @throws NullPointerException if arrayType is null + * @throws IllegalArgumentException if arrayType isn't actually an array type + * @throws NegativeArraySizeException if arrayLength is negative + * @throws InvalidClassException if the filter rejects creation + */ + private void checkArray(Class arrayType, int arrayLength) throws InvalidClassException { + Objects.requireNonNull(arrayType); + if (! arrayType.isArray()) { + throw new IllegalArgumentException("not an array type"); + } + + if (arrayLength < 0) { + throw new NegativeArraySizeException(); + } + + filterCheck(arrayType, arrayLength); + } + + /** * Provide access to the persistent fields read from the input stream. */ public abstract static class GetField { @@ -3982,6 +4009,10 @@ } } + static { + SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray); + } + private void validateDescriptor(ObjectStreamClass descriptor) { ObjectStreamClassValidator validating = validator; if (validating != null) { diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/ArrayDeque.java --- a/src/java.base/share/classes/java/util/ArrayDeque.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/ArrayDeque.java Wed Aug 02 10:34:35 2017 -0700 @@ -38,6 +38,7 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import jdk.internal.misc.SharedSecrets; /** * Resizable-array implementation of the {@link Deque} interface. Array @@ -1194,6 +1195,7 @@ // Read in size and allocate array int size = s.readInt(); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size + 1); elements = new Object[size + 1]; this.tail = size; diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/ArrayList.java --- a/src/java.base/share/classes/java/util/ArrayList.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/ArrayList.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -28,6 +28,7 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import jdk.internal.misc.SharedSecrets; /** * Resizable-array implementation of the {@code List} interface. Implements @@ -814,6 +815,7 @@ if (size > 0) { // like clone(), allocate array based upon size not capacity + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size); Object[] elements = new Object[size]; // Read in all elements in the proper order. diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/HashMap.java --- a/src/java.base/share/classes/java/util/HashMap.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/HashMap.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -34,6 +34,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import jdk.internal.misc.SharedSecrets; /** * Hash table based implementation of the {@code Map} interface. This @@ -1448,6 +1449,10 @@ float ft = (float)cap * lf; threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ? (int)ft : Integer.MAX_VALUE); + + // Check Map.Entry[].class since it's the nearest public type to + // what we're actually creating. + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, cap); @SuppressWarnings({"rawtypes","unchecked"}) Node[] tab = (Node[])new Node[cap]; table = tab; diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/HashSet.java --- a/src/java.base/share/classes/java/util/HashSet.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/HashSet.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -26,6 +26,7 @@ package java.util; import java.io.InvalidObjectException; +import jdk.internal.misc.SharedSecrets; /** * This class implements the {@code Set} interface, backed by a hash table @@ -322,6 +323,13 @@ capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f), HashMap.MAXIMUM_CAPACITY); + // Constructing the backing map will lazily create an array when the first element is + // added, so check it before construction. Call HashMap.tableSizeFor to compute the + // actual allocation size. Check Map.Entry[].class since it's the nearest public type to + // what is actually created. + SharedSecrets.getJavaObjectInputStreamAccess() + .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity)); + // Create backing HashMap map = (((HashSet)this) instanceof LinkedHashSet ? new LinkedHashMap<>(capacity, loadFactor) : diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/Hashtable.java --- a/src/java.base/share/classes/java/util/Hashtable.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/Hashtable.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2017, 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 @@ -29,6 +29,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.BiFunction; +import jdk.internal.misc.SharedSecrets; /** * This class implements a hash table, which maps keys to values. Any @@ -1291,6 +1292,10 @@ if (length > elements && (length & 1) == 0) length--; length = Math.min(length, origlength); + + // Check Map.Entry[].class since it's the nearest public type to + // what we're actually creating. + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length); table = new Entry[length]; threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0; diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/IdentityHashMap.java --- a/src/java.base/share/classes/java/util/IdentityHashMap.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, 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 @@ -29,6 +29,7 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; +import jdk.internal.misc.SharedSecrets; /** * This class implements the {@code Map} interface with a hash table, using @@ -1304,7 +1305,9 @@ if (size < 0) throw new java.io.StreamCorruptedException ("Illegal mappings count: " + size); - init(capacity(size)); + int cap = capacity(size); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap); + init(cap); // Read the keys and values, and put the mappings in the table for (int i=0; i(elements); diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Wed Aug 02 10:34:35 2017 -0700 @@ -51,6 +51,7 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import jdk.internal.misc.SharedSecrets; /** * A thread-safe variant of {@link java.util.ArrayList} in which all mutative @@ -933,6 +934,7 @@ // Read in array length and allocate array int len = s.readInt(); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len); Object[] elements = new Object[len]; // Read in all elements in the proper order. diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java --- a/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java Wed Jul 26 17:44:06 2017 +0100 +++ b/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java Wed Aug 02 10:34:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,17 +25,14 @@ package jdk.internal.misc; +import java.io.InvalidClassException; import java.io.ObjectInputStream; /** - * The interface to specify methods for accessing {@code ObjectInputStream} - * @author sjiang + * Interface to specify methods for accessing {@code ObjectInputStream}. */ +@FunctionalInterface public interface JavaObjectInputStreamAccess { - /** - * Sets a descriptor validating. - * @param ois stream to have the descriptors validated - * @param validator validator used to validate a descriptor. - */ - public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator); + void checkArray(ObjectInputStream ois, Class arrayType, int arrayLength) + throws InvalidClassException; } diff -r 7a4b85711089 -r 4fc2a4a29f3d src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java --- a/src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java Wed Jul 26 17:44:06 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ -package jdk.internal.misc; - -import java.io.ObjectStreamClass; - -/** - * A callback used by {@code ObjectInputStream} to do descriptor validation. - * - * @author sjiang - */ -public interface ObjectStreamClassValidator { - /** - * This method will be called by ObjectInputStream to - * check a descriptor just before creating an object described by this descriptor. - * The object will not be created if this method throws a {@code RuntimeException}. - * @param descriptor descriptor to be checked. - */ - public void validateDescriptor(ObjectStreamClass descriptor); -} diff -r 7a4b85711089 -r 4fc2a4a29f3d test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java --- a/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java Wed Jul 26 17:44:06 2017 +0100 +++ b/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java Wed Aug 02 10:34:35 2017 -0700 @@ -36,9 +36,11 @@ import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.LongAdder; import javax.net.ssl.SSLEngineResult; @@ -165,6 +167,11 @@ interfaces, (p, m, args) -> p); Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop; + + List> classList = new ArrayList<>(); + classList.add(HashSet.class); + classList.addAll(Collections.nCopies(21, Map.Entry[].class)); + Object[][] objects = { { null, 0, -1, 0, 0, 0, Arrays.asList()}, // no callback, no values @@ -184,8 +191,7 @@ objArray.getClass(), SerialFilterTest.class, java.lang.invoke.SerializedLambda.class)}, - { deepHashSet(10), 48, -1, 50, 11, 619, - Arrays.asList(HashSet.class)}, + { deepHashSet(10), 69, 4, 50, 11, 619, classList }, { proxy.getClass(), 3, -1, 2, 2, 112, Arrays.asList(Runnable.class, java.lang.reflect.Proxy.class,