diff --git a/spring-context/src/main/java/org/springframework/validation/DataBinder.java b/spring-context/src/main/java/org/springframework/validation/DataBinder.java index 912dad1321dc..b44aba0e7f32 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -116,6 +116,7 @@ * @author Stephane Nicoll * @author Kazuki Shimizu * @author Sam Brannen + * @author Mengqi Xu * @see #setAllowedFields * @see #setRequiredFields * @see #registerCustomEditor @@ -1087,7 +1088,13 @@ private boolean hasValuesFor(String paramPath, ValueResolver resolver) { if (name.startsWith(paramPath + "[")) { int endIndex = name.indexOf(']', paramPath.length() + 1); String rawIndex = name.substring(paramPath.length() + 1, endIndex); - int index = Integer.parseInt(rawIndex); + int index; + try { + index = Integer.parseInt(rawIndex); + } + catch (NumberFormatException ex) { + throw new IllegalArgumentException("Failed to parse index from '" + rawIndex + "'", ex); + } indexes = (indexes != null ? indexes : new TreeSet<>()); indexes.add(index); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java index 02dc5656994f..d4036ad86c98 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java @@ -34,11 +34,13 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test fixture for {@link ExtendedServletRequestDataBinder}. * * @author Rossen Stoyanchev + * @author Mengqi Xu */ class ExtendedServletRequestDataBinderTests { @@ -90,6 +92,31 @@ void createBinderViaConstructor() { assertThat(bean.someIntArray()).containsExactly(1, 2); } + @Test // gh-34205 + void createBinderViaConstructorWithInvalidIndex() { + request.addParameter("Some-Int-Array[foo]", "1"); + + ServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(null); + binder.setTargetType(ResolvableType.forClass(DataBean.class)); + binder.setNameResolver(new BindParamNameResolver()); + + assertThatThrownBy(() -> binder.construct(request)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Failed to parse index from 'foo'"); + } + + @Test // gh-34205 + void createBinderViaConstructorWithChooseConstructor() { + request.addParameter("Some-Int-Array[0]", "1"); + + ServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(null); + binder.setTargetType(ResolvableType.forClass(DataBean.class)); + binder.setNameResolver(new BindParamNameResolver()); + assertThatThrownBy(() -> binder.construct(request)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("No primary or single unique constructor found for class java.lang.Integer"); + } + @Test void uriVarsAndHeadersAddedConditionally() { request.addParameter("name", "John");