From 0ffd7ff1f0c6516ba0b8558ad164b693490bcad4 Mon Sep 17 00:00:00 2001 From: Alexander Zhuravlev Date: Fri, 9 Sep 2022 00:47:49 +0300 Subject: [PATCH] Fix NPE when GraphQL argument is a list with a null element --- .../graphql/data/GraphQlArgumentBinder.java | 2 +- .../data/GraphQlArgumentBinderTests.java | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java index 5adb35129..ce63da994 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java @@ -213,7 +213,7 @@ private Collection createCollection( int i = 0; for (Object rawValue : rawCollection) { segments.push("[" + i++ + "]"); - if (elementClass.isAssignableFrom(rawValue.getClass())) { + if (rawValue == null || elementClass.isAssignableFrom(rawValue.getClass())) { collection.add((T) rawValue); } else if (rawValue instanceof Map) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java index b9862ff89..fdaa94793 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java @@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironmentImpl; +import org.assertj.core.api.CollectionAssert; import org.junit.jupiter.api.Test; import org.springframework.core.ResolvableType; @@ -281,6 +282,44 @@ void shouldUseTargetCollectionType() throws Exception { assertThat(((ItemSetHolder) result).getItems()).hasSize(5); } + @Test + @SuppressWarnings("unchecked") + void list() throws Exception { + Object result = this.binder.bind( + environment("{\"key\": [\"1\", \"2\", \"3\"]}"), + "key", + ResolvableType.forClassWithGenerics(List.class, String.class) + ); + + assertThat(result).isNotNull().isInstanceOf(List.class); + new CollectionAssert<>((List) result).containsExactly("1", "2", "3"); + } + + @Test + @SuppressWarnings("unchecked") + void listWithNullItem() throws Exception { + Object result = this.binder.bind( + environment("{\"key\": [\"1\", null, \"3\"]}"), + "key", + ResolvableType.forClassWithGenerics(List.class, String.class) + ); + + assertThat(result).isNotNull().isInstanceOf(List.class); + new CollectionAssert<>((List) result).containsExactly("1", null, "3"); + } + + @Test + @SuppressWarnings("unchecked") + void emptyList() throws Exception { + Object result = this.binder.bind( + environment("{\"key\": []}"), + "key", + ResolvableType.forClassWithGenerics(List.class, String.class) + ); + + assertThat(result).isNotNull().isInstanceOf(List.class); + new CollectionAssert<>((List) result).isEmpty(); + } @SuppressWarnings("unchecked") private DataFetchingEnvironment environment(String jsonPayload) throws JsonProcessingException {