From 62631bfe33d92e5e3e55e05cccea7d60c71adbc9 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 8 Nov 2016 17:47:29 +0100 Subject: [PATCH] Detect invalid configuration for autoGrowCollectionLimit on DataBinder Issue: SPR-14888 --- .../validation/DataBinder.java | 6 ++- .../validation/DataBinderTests.java | 37 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) 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 b80bce63cf8..9daa94f3716 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -235,8 +235,12 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { * Specify the limit for array and collection auto-growing. *

Default is 256, preventing OutOfMemoryErrors in case of large indexes. * Raise this limit if your auto-growing needs are unusually high. + * @see #initBeanPropertyAccess() + * @see org.springframework.beans.BeanWrapper#setAutoGrowCollectionLimit */ public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) { + Assert.state(this.bindingResult == null, + "DataBinder is already initialized - call setAutoGrowCollectionLimit before other configuration methods"); this.autoGrowCollectionLimit = autoGrowCollectionLimit; } diff --git a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java index bdb12118b96..a2a9fc8bcd5 100644 --- a/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java +++ b/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java @@ -36,7 +36,9 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.beans.InvalidPropertyException; import org.springframework.beans.MutablePropertyValues; @@ -69,9 +71,14 @@ import static org.junit.Assert.*; * @author Rod Johnson * @author Juergen Hoeller * @author Rob Harrop + * @author Kazuki Shimizu */ public class DataBinderTests { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test public void testBindingNoErrors() throws Exception { TestBean rod = new TestBean(); @@ -1982,6 +1989,30 @@ public class DataBinderTests { assertEquals("age", binder.getBindingResult().getFieldError("age").getField()); } + @Test // SPR-14888 + public void testSetAutoGrowCollectionLimit() { + BeanWithIntegerList tb = new BeanWithIntegerList(); + DataBinder binder = new DataBinder(tb); + binder.setAutoGrowCollectionLimit(257); + MutablePropertyValues pvs = new MutablePropertyValues(); + pvs.add("integerList[256]", "1"); + + binder.bind(pvs); + assertEquals(257, tb.getIntegerList().size()); + assertEquals(Integer.valueOf(1), tb.getIntegerList().get(256)); + assertEquals(Integer.valueOf(1), binder.getBindingResult().getFieldValue("integerList[256]")); + } + + @Test // SPR-14888 + public void testSetAutoGrowCollectionLimitAfterInitialization() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("DataBinder is already initialized - call setAutoGrowCollectionLimit before other configuration methods"); + + DataBinder binder = new DataBinder(new BeanWithIntegerList()); + binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); + binder.setAutoGrowCollectionLimit(257); + } + @SuppressWarnings("unused") private static class BeanWithIntegerList { @@ -2112,7 +2143,7 @@ public class DataBinderTests { private List list; public GrowingList() { - this.list = new ArrayList(); + this.list = new ArrayList<>(); } public List getWrappedList() { @@ -2200,8 +2231,8 @@ public class DataBinderTests { private final Map f; public Form() { - f = new HashMap(); - f.put("list", new GrowingList()); + f = new HashMap<>(); + f.put("list", new GrowingList<>()); } public Map getF() {