From 0cffb73cbe880a1fd1aefc29f91cff8e1a7c3cf4 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 12 Oct 2024 18:47:33 +0300 Subject: [PATCH] Enforce rawType to be a Class in ParameterizedTypeImpl Enforce rawType to be a Class in ParameterizedTypeImpl Enforce rawType to be a Class in ParameterizedTypeImpl --- .../com/google/gson/internal/$Gson$Types.java | 9 ++++---- .../com/google/gson/reflect/TypeToken.java | 22 ++++++------------- .../google/gson/reflect/TypeTokenTest.java | 10 --------- 3 files changed, 11 insertions(+), 30 deletions(-) diff --git a/gson/src/main/java/com/google/gson/internal/$Gson$Types.java b/gson/src/main/java/com/google/gson/internal/$Gson$Types.java index 8a65031d1a..a89f6df381 100644 --- a/gson/src/main/java/com/google/gson/internal/$Gson$Types.java +++ b/gson/src/main/java/com/google/gson/internal/$Gson$Types.java @@ -58,7 +58,7 @@ public final class $Gson$Types { */ public static ParameterizedType newParameterizedTypeWithOwner( Type ownerType, Type rawType, Type... typeArguments) { - return new ParameterizedTypeImpl(ownerType, rawType, typeArguments); + return new ParameterizedTypeImpl(ownerType, (Class) rawType, typeArguments); } /** @@ -112,7 +112,7 @@ public static Type canonicalize(Type type) { } else if (type instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType) type; return new ParameterizedTypeImpl( - p.getOwnerType(), p.getRawType(), p.getActualTypeArguments()); + p.getOwnerType(), (Class) p.getRawType(), p.getActualTypeArguments()); } else if (type instanceof GenericArrayType) { GenericArrayType g = (GenericArrayType) type; @@ -519,10 +519,9 @@ private static final class ParameterizedTypeImpl implements ParameterizedType, S @SuppressWarnings("serial") private final Type[] typeArguments; - public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) { - // TODO: Should this enforce that rawType is a Class? See JDK implementation of - // the ParameterizedType interface and https://bugs.openjdk.org/browse/JDK-8250659 + public ParameterizedTypeImpl(Type ownerType, Class rawType, Type... typeArguments) { requireNonNull(rawType); + if (ownerType == null && requiresOwnerType(rawType)) { throw new IllegalArgumentException("Must specify owner type for " + rawType); } diff --git a/gson/src/main/java/com/google/gson/reflect/TypeToken.java b/gson/src/main/java/com/google/gson/reflect/TypeToken.java index 49de430039..076ce89291 100644 --- a/gson/src/main/java/com/google/gson/reflect/TypeToken.java +++ b/gson/src/main/java/com/google/gson/reflect/TypeToken.java @@ -45,7 +45,7 @@ * *

If the type arguments of the parameterized type are only available at runtime, for example * when you want to create a {@code List} based on a {@code Class} representing the element - * type, the method {@link #getParameterized(Type, Type...)} can be used. + * type, the method {@link #getParameterized(Class, Type...)} can be used. * * @author Bob Lee * @author Sven Mawson @@ -379,27 +379,19 @@ public static TypeToken get(Class type) { *

If {@code rawType} is a non-generic class and no type arguments are provided, this method * simply delegates to {@link #get(Class)} and creates a {@code TypeToken(Class)}. * - * @throws IllegalArgumentException If {@code rawType} is not of type {@code Class}, or if the - * type arguments are invalid for the raw type + * @throws IllegalArgumentException If the type arguments are invalid for the raw type */ - public static TypeToken getParameterized(Type rawType, Type... typeArguments) { + public static TypeToken getParameterized(Class rawType, Type... typeArguments) { Objects.requireNonNull(rawType); Objects.requireNonNull(typeArguments); - // Perform basic validation here because this is the only public API where users - // can create malformed parameterized types - if (!(rawType instanceof Class)) { - // See also https://bugs.openjdk.org/browse/JDK-8250659 - throw new IllegalArgumentException("rawType must be of type Class, but was " + rawType); - } - Class rawClass = (Class) rawType; - TypeVariable[] typeVariables = rawClass.getTypeParameters(); + TypeVariable[] typeVariables = rawType.getTypeParameters(); int expectedArgsCount = typeVariables.length; int actualArgsCount = typeArguments.length; if (actualArgsCount != expectedArgsCount) { throw new IllegalArgumentException( - rawClass.getName() + rawType.getName() + " requires " + expectedArgsCount + " type arguments, but got " @@ -408,14 +400,14 @@ public static TypeToken getParameterized(Type rawType, Type... typeArguments) // For legacy reasons create a TypeToken(Class) if the type is not generic if (typeArguments.length == 0) { - return get(rawClass); + return get((Class) rawType); } // Check for this here to avoid misleading exception thrown by ParameterizedTypeImpl if ($Gson$Types.requiresOwnerType(rawType)) { throw new IllegalArgumentException( "Raw type " - + rawClass.getName() + + ((Class) rawType).getName() + " is not supported because it requires specifying an owner type"); } diff --git a/gson/src/test/java/com/google/gson/reflect/TypeTokenTest.java b/gson/src/test/java/com/google/gson/reflect/TypeTokenTest.java index ddc6b92973..bb047c17b3 100644 --- a/gson/src/test/java/com/google/gson/reflect/TypeTokenTest.java +++ b/gson/src/test/java/com/google/gson/reflect/TypeTokenTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -186,16 +185,7 @@ public void testParameterizedFactory_Invalid() { NullPointerException.class, () -> TypeToken.getParameterized(List.class, new Type[] {null})); - GenericArrayType arrayType = (GenericArrayType) TypeToken.getArray(String.class).getType(); IllegalArgumentException e = - assertThrows( - IllegalArgumentException.class, - () -> TypeToken.getParameterized(arrayType, new Type[0])); - assertThat(e) - .hasMessageThat() - .isEqualTo("rawType must be of type Class, but was java.lang.String[]"); - - e = assertThrows( IllegalArgumentException.class, () -> TypeToken.getParameterized(String.class, Number.class));