From f1345aadf5879659c186a1dac7915f47d6c1cd14 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 20 Jul 2020 07:04:45 +0200 Subject: [PATCH 1/2] Defensively access existing beanDefinitionMap entries See gh-22263 --- .../beans/factory/support/DefaultListableBeanFactory.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 9f0cb3c2635..5576a31fe09 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -652,8 +652,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public String[] getBeanNamesForAnnotation(Class annotationType) { List result = new ArrayList<>(); for (String beanName : this.beanDefinitionNames) { - BeanDefinition beanDefinition = this.beanDefinitionMap.get(beanName); - if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { + BeanDefinition bd = this.beanDefinitionMap.get(beanName); + if (bd != null && !bd.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) { result.add(beanName); } } @@ -1057,8 +1057,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto for (String bdName : this.beanDefinitionNames) { if (!beanName.equals(bdName)) { BeanDefinition bd = this.beanDefinitionMap.get(bdName); - // Ensure bd is non-null due to potential concurrent modification - // of the beanDefinitionMap. + // Ensure bd is non-null due to potential concurrent modification of beanDefinitionMap. if (bd != null && beanName.equals(bd.getParentName())) { resetBeanDefinition(bdName); } From 65e601090fd831dadcf20a18d7e90fde8b5a87cf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 20 Jul 2020 07:07:17 +0200 Subject: [PATCH 2/2] Copy queryParams MultiValueMap through addAll (for independent List entries) Closes gh-25423 --- .../web/util/UriComponentsBuilder.java | 2 +- .../web/util/UriComponentsBuilderTests.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index f07065be85f..e98856167fa 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -157,7 +157,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { this.port = other.port; this.pathBuilder = other.pathBuilder.cloneBuilder(); this.uriVariables.putAll(other.uriVariables); - this.queryParams.putAll(other.queryParams); + this.queryParams.addAll(other.queryParams); this.fragment = other.fragment; this.encodeTemplate = other.encodeTemplate; this.charset = other.charset; diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index d19c2740a29..7fe6bfa1fbc 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -918,30 +918,32 @@ class UriComponentsBuilderTests { assertThat(components.toString()).isEqualTo(""); } - @Test + @Test // gh-25243 void testCloneAndMerge() { UriComponentsBuilder builder1 = UriComponentsBuilder.newInstance(); - builder1.scheme("http").host("e1.com").path("/p1").pathSegment("ps1").queryParam("q1").fragment("f1").encode(); + builder1.scheme("http").host("e1.com").path("/p1").pathSegment("ps1").queryParam("q1", "x").fragment("f1").encode(); - UriComponentsBuilder builder2 = (UriComponentsBuilder) builder1.clone(); + UriComponentsBuilder builder2 = builder1.cloneBuilder(); builder2.scheme("https").host("e2.com").path("p2").pathSegment("{ps2}").queryParam("q2").fragment("f2"); + builder1.queryParam("q1", "y"); // one more entry for an existing parameter + UriComponents result1 = builder1.build(); assertThat(result1.getScheme()).isEqualTo("http"); assertThat(result1.getHost()).isEqualTo("e1.com"); assertThat(result1.getPath()).isEqualTo("/p1/ps1"); - assertThat(result1.getQuery()).isEqualTo("q1"); + assertThat(result1.getQuery()).isEqualTo("q1=x&q1=y"); assertThat(result1.getFragment()).isEqualTo("f1"); UriComponents result2 = builder2.buildAndExpand("ps2;a"); assertThat(result2.getScheme()).isEqualTo("https"); assertThat(result2.getHost()).isEqualTo("e2.com"); assertThat(result2.getPath()).isEqualTo("/p1/ps1/p2/ps2%3Ba"); - assertThat(result2.getQuery()).isEqualTo("q1&q2"); + assertThat(result2.getQuery()).isEqualTo("q1=x&q2"); assertThat(result2.getFragment()).isEqualTo("f2"); } - @Test // gh-24772 + @Test // gh-24772 void testDeepClone() { HashMap vars = new HashMap<>(); vars.put("ps1", "foo"); @@ -951,7 +953,7 @@ class UriComponentsBuilderTests { builder1.scheme("http").host("e1.com").userInfo("user:pwd").path("/p1").pathSegment("{ps1}") .pathSegment("{ps2}").queryParam("q1").fragment("f1").uriVariables(vars).encode(); - UriComponentsBuilder builder2 = (UriComponentsBuilder) builder1.clone(); + UriComponentsBuilder builder2 = builder1.cloneBuilder(); UriComponents result1 = builder1.build(); assertThat(result1.getScheme()).isEqualTo("http");