Skip to content

Commit

Permalink
Validate instances created by InstanceCreator
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcono1234 committed Jul 25, 2023
1 parent 79ae239 commit c5311bd
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ static String checkInstantiable(Class<?> c) {
return null;
}

private static <T> T useInstanceCreator(InstanceCreator<T> instanceCreator, Type type, Class<?> rawType) {
T instance = instanceCreator.createInstance(type);
if (instance == null) {
throw new RuntimeException("InstanceCreator " + instanceCreator + " returned null for type " + type);
}

if (!rawType.isInstance(instance)) {
throw new ClassCastException("InstanceCreator " + instanceCreator + " created instance of wrong type;"
+ " expected " + rawType.getName() + " but got instance of unrelated type " + instance.getClass().getName());
}
return instance;
}

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
final Type type = typeToken.getType();
final Class<? super T> rawType = typeToken.getRawType();
Expand All @@ -100,7 +113,7 @@ public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
if (typeCreator != null) {
return new ObjectConstructor<T>() {
@Override public T construct() {
return typeCreator.createInstance(type);
return useInstanceCreator(typeCreator, type, rawType);
}
};
}
Expand All @@ -112,7 +125,7 @@ public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
if (rawTypeCreator != null) {
return new ObjectConstructor<T>() {
@Override public T construct() {
return rawTypeCreator.createInstance(type);
return useInstanceCreator(rawTypeCreator, type, rawType);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.gson.functional;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Expand All @@ -33,7 +34,7 @@
import org.junit.Test;

/**
* Functional Test exercising custom serialization only. When test applies to both
* Functional Test exercising custom deserialization only. When test applies to both
* serialization and deserialization then add it to CustomTypeAdapterTest.
*
* @author Inderjeet Singh
Expand Down Expand Up @@ -129,4 +130,48 @@ class SubTreeSet<T> extends TreeSet<T> {}
assertThat(set.first()).isEqualTo("b");
assertThat(set.getClass()).isEqualTo(SubTreeSet.class);
}

private static class CustomClass {}

@Test
public void testInstanceCreatorReturnsNull() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(CustomClass.class, new InstanceCreator<CustomClass>() {
@Override
public CustomClass createInstance(Type type) {
return null;
}

@Override
public String toString() {
return "bad-instance-creator";
}
})
.create();

RuntimeException e = assertThrows(RuntimeException.class, () -> gson.fromJson("{}", CustomClass.class));
assertThat(e).hasMessageThat().isEqualTo("InstanceCreator bad-instance-creator returned null for"
+ " type class " + CustomClass.class.getName());
}

@Test
public void testInstanceCreatorReturnsWrongInstance() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(CustomClass.class, new InstanceCreator<String>() {
@Override
public String createInstance(Type type) {
return "test";
}

@Override
public String toString() {
return "bad-instance-creator";
}
})
.create();

ClassCastException e = assertThrows(ClassCastException.class, () -> gson.fromJson("{}", CustomClass.class));
assertThat(e).hasMessageThat().isEqualTo("InstanceCreator bad-instance-creator created instance of wrong type;"
+ " expected " + CustomClass.class.getName() + " but got instance of unrelated type java.lang.String");
}
}

0 comments on commit c5311bd

Please sign in to comment.