Skip to content

Commit 481a574

Browse files
mkurzjhoeller
authored andcommitted
Apply auto-grow limit to direct field binding
DataBinder applies its auto-grow collection limit to bean property access, but direct field access left DirectFieldAccessor at its default limit. Pass DataBinder's configured limit into DirectFieldBindingResult and apply it to the DirectFieldAccessor. Closes gh-36861 Signed-off-by: Matthias Kurz <m.kurz@irregular.at>
1 parent 85a8868 commit 481a574

3 files changed

Lines changed: 53 additions & 1 deletion

File tree

spring-context/src/main/java/org/springframework/validation/DataBinder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ public void initDirectFieldAccess() {
341341
*/
342342
protected AbstractPropertyBindingResult createDirectFieldBindingResult() {
343343
DirectFieldBindingResult result = new DirectFieldBindingResult(getTarget(),
344-
getObjectName(), isAutoGrowNestedPaths());
344+
getObjectName(), isAutoGrowNestedPaths(), getAutoGrowCollectionLimit());
345345

346346
if (this.conversionService != null) {
347347
result.initConversion(this.conversionService);

spring-context/src/main/java/org/springframework/validation/DirectFieldBindingResult.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.jspecify.annotations.Nullable;
2020

2121
import org.springframework.beans.ConfigurablePropertyAccessor;
22+
import org.springframework.beans.DirectFieldAccessor;
2223
import org.springframework.beans.PropertyAccessorFactory;
2324

2425
/**
@@ -41,6 +42,8 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
4142

4243
private final boolean autoGrowNestedPaths;
4344

45+
private final int autoGrowCollectionLimit;
46+
4447
private transient @Nullable ConfigurablePropertyAccessor directFieldAccessor;
4548

4649

@@ -60,9 +63,24 @@ public DirectFieldBindingResult(@Nullable Object target, String objectName) {
6063
* @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value
6164
*/
6265
public DirectFieldBindingResult(@Nullable Object target, String objectName, boolean autoGrowNestedPaths) {
66+
this(target, objectName, autoGrowNestedPaths, Integer.MAX_VALUE);
67+
}
68+
69+
/**
70+
* Create a new {@code DirectFieldBindingResult} for the given target.
71+
* @param target the target object to bind onto
72+
* @param objectName the name of the target object
73+
* @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value
74+
* @param autoGrowCollectionLimit the limit for array and collection auto-growing
75+
* @since 7.1
76+
*/
77+
public DirectFieldBindingResult(@Nullable Object target, String objectName,
78+
boolean autoGrowNestedPaths, int autoGrowCollectionLimit) {
79+
6380
super(objectName);
6481
this.target = target;
6582
this.autoGrowNestedPaths = autoGrowNestedPaths;
83+
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
6684
}
6785

6886

@@ -82,6 +100,7 @@ public final ConfigurablePropertyAccessor getPropertyAccessor() {
82100
this.directFieldAccessor = createDirectFieldAccessor();
83101
this.directFieldAccessor.setExtractOldValueForEditor(true);
84102
this.directFieldAccessor.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
103+
((DirectFieldAccessor) this.directFieldAccessor).setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
85104
}
86105
return this.directFieldAccessor;
87106
}

spring-context/src/test/java/org/springframework/validation/DataBinderFieldAccessTests.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package org.springframework.validation;
1818

1919
import java.beans.PropertyEditorSupport;
20+
import java.util.List;
2021
import java.util.Map;
2122

2223
import org.junit.jupiter.api.Test;
2324

25+
import org.springframework.beans.InvalidPropertyException;
2426
import org.springframework.beans.MutablePropertyValues;
2527
import org.springframework.beans.NotWritablePropertyException;
2628
import org.springframework.beans.NullValueInNestedPathException;
@@ -134,6 +136,25 @@ void nestedBindingWithDisabledAutoGrow() {
134136
binder.bind(pvs));
135137
}
136138

139+
@Test
140+
void directFieldAccessHonorsDefaultAutoGrowCollectionLimit() {
141+
FieldAccessForm target = new FieldAccessForm();
142+
DataBinder binder = new DataBinder(target);
143+
binder.initDirectFieldAccess();
144+
145+
MutablePropertyValues pvs = new MutablePropertyValues();
146+
pvs.add("items[255].name", "value");
147+
binder.bind(pvs);
148+
149+
assertThat(target.items).hasSize(256);
150+
assertThat(target.items.get(255).name).isEqualTo("value");
151+
152+
MutablePropertyValues outOfBounds = new MutablePropertyValues();
153+
outOfBounds.add("items[256].name", "too-far");
154+
assertThatExceptionOfType(InvalidPropertyException.class).isThrownBy(() ->
155+
binder.bind(outOfBounds));
156+
}
157+
137158
@Test
138159
void bindingWithErrorsAndCustomEditors() {
139160
FieldAccessBean rod = new FieldAccessBean();
@@ -176,4 +197,16 @@ public String getAsText() {
176197
assertThat(tb.getSpouse()).isNotNull();
177198
});
178199
}
200+
201+
202+
static class FieldAccessForm {
203+
204+
public List<FieldAccessItem> items;
205+
}
206+
207+
208+
static class FieldAccessItem {
209+
210+
public String name;
211+
}
179212
}

0 commit comments

Comments
 (0)