From 88d4de73c22b9153a63c773307792ef10c503bc8 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 4 Mar 2019 19:51:16 -0500 Subject: [PATCH] Fix potential NPE when extracting data from query params. Fixes #3405 --- .../RibbonClientHttpRequestFactoryTests.java | 3 +++ .../ribbon/test/TestAutoConfiguration.java | 9 +++++-- .../util/RequestContentDataExtractor.java | 1 + .../util/RequestContentDataExtractorTest.java | 25 +++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java index 1d6a078ba..d4321c351 100644 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java +++ b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java @@ -65,6 +65,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen public class RibbonClientHttpRequestFactoryTests { @Rule + /** + * JUnit rule + */ public final ExpectedException exceptionRule = ExpectedException.none(); @LoadBalanced diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java index 00eee7992..7c291f0aa 100644 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java +++ b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java @@ -38,14 +38,19 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager; @AutoConfigureBefore(SecurityAutoConfiguration.class) public class TestAutoConfiguration { + /** + * User name + */ public static final String USER = "user"; + /** + * Password + */ public static final String PASSWORD = "{noop}password"; @Configuration @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration - extends WebSecurityConfigurerAdapter { + static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter { TestSecurityConfiguration() { super(true); diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java index c2f62b5cf..6c948a478 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java @@ -98,6 +98,7 @@ public final class RequestContentDataExtractor { if (listOfOnlyQueryParams != null) { listOfOnlyQueryParams = listOfOnlyQueryParams.stream() + .filter(queryParam -> queryParam != null) .map(param -> uriDecode(param, Charset.defaultCharset())) .collect(Collectors.toList()); if (!listOfOnlyQueryParams.containsAll(listOfAllParams)) { diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java index d043d0072..539331e2d 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java @@ -16,7 +16,9 @@ package org.springframework.cloud.netflix.zuul.util; +import java.io.IOException; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -26,6 +28,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.http.HttpEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -140,4 +143,26 @@ public class RequestContentDataExtractorTest { assertThat(result.size()).isEqualTo(0); } + @Test + public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryValueIsNull() + throws IOException { + // when + Map paramMap = new HashMap<>(); + paramMap.put("uid", new String[] { "foo", "bar" }); + when(request.getQueryString()).thenReturn("uid"); + when(request.getParameterMap()).thenReturn(paramMap); + when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); + + // action + Map> result = RequestContentDataExtractor.extract(request); + + // then + List uidResult = new LinkedList(); + uidResult.add(new HttpEntity<>("foo")); + uidResult.add(new HttpEntity<>("bar")); + assertThat(result).isNotNull(); + assertThat(result).containsEntry("uid", uidResult); + assertThat(result.size()).isEqualTo(1); + } + }