8254090: Collectors.toUnmodifiableList exposes shared secret

Co-authored-by: Tagir F. Valeev <tvaleev@openjdk.org>
Reviewed-by: psandoz
This commit is contained in:
Stuart Marks 2020-10-12 17:22:21 +00:00
parent df1f132b67
commit d7128e7dac
2 changed files with 64 additions and 7 deletions

View file

@ -277,7 +277,7 @@ public final class Collectors {
*/
public static <T>
Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
return new CollectorImpl<>(ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
@ -293,13 +293,18 @@ public final class Collectors {
* <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
* @since 10
*/
@SuppressWarnings("unchecked")
public static <T>
Collector<T, ?, List<T>> toUnmodifiableList() {
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
return new CollectorImpl<>(ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
list -> (List<T>)SharedSecrets.getJavaUtilCollectionAccess()
.listFromTrustedArray(list.toArray()),
list -> {
if (list.getClass() == ArrayList.class) { // ensure it's trusted
return SharedSecrets.getJavaUtilCollectionAccess()
.listFromTrustedArray(list.toArray());
} else {
throw new IllegalArgumentException();
}
},
CH_NOID);
}
@ -319,7 +324,7 @@ public final class Collectors {
*/
public static <T>
Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
return new CollectorImpl<>(HashSet::new, Set::add,
(left, right) -> {
if (left.size() < right.size()) {
right.addAll(left); return right;
@ -348,7 +353,7 @@ public final class Collectors {
@SuppressWarnings("unchecked")
public static <T>
Collector<T, ?, Set<T>> toUnmodifiableSet() {
return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
return new CollectorImpl<>(HashSet::new, Set::add,
(left, right) -> {
if (left.size() < right.size()) {
right.addAll(left); return right;

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/*
* @test
* @bug 8254090
* @summary Test for Collectors.toUnmodifiableList().
*/
public class CollectorToUnmodListTest {
@SuppressWarnings("unchecked")
@Test
public void testFinisher() {
String[] array = { "x", "y", "z" };
List<String> in = new ArrayList<>() {
public Object[] toArray() {
return array;
}
};
var finisher = (Function<List<String>, List<String>>)Collectors.<String>toUnmodifiableList().finisher();
assertThrows(IllegalArgumentException.class, () -> finisher.apply(in));
}
}