Permalink
Browse files

DATACMNS-1264 - MapDataBinder now rejects improper property expressions.

We now make sure that type expressions cannot be used in SpEL expressions handled by MapDataBinder. They're gonna be rejected by considering the property not writable. SpEL expression evaluation errors are now forwarded as NotWritablePropertyException to make sure the failure gets handled as if the property referred to doesn't exist.
  • Loading branch information...
odrotbohm committed Feb 26, 2018
1 parent 3dff7ea commit 613cf08f7255056a2a2d185b6e6c0f2c50534ed3
@@ -43,6 +43,8 @@
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -177,6 +179,9 @@ public void setPropertyValue(String propertyName, @Nullable Object value) throws
StandardEvaluationContext context = new StandardEvaluationContext();
context.addPropertyAccessor(new PropertyTraversingMapAccessor(type, conversionService));
context.setTypeConverter(new StandardTypeConverter(conversionService));
context.setTypeLocator(typeName -> {
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
});
context.setRootObject(map);
Expression expression = PARSER.parseExpression(propertyName);
@@ -208,7 +213,11 @@ public void setPropertyValue(String propertyName, @Nullable Object value) throws
value = conversionService.convert(value, TypeDescriptor.forObject(value), typeDescriptor);
}
expression.setValue(context, value);
try {
expression.setValue(context, value);
} catch (SpelEvaluationException o_O) {
throw new NotWritablePropertyException(type, propertyName, "Could not write property!", o_O);
}
}
private boolean conversionRequired(@Nullable Object source, Class<?> targetType) {
@@ -28,8 +28,11 @@
import java.util.Map;
import org.junit.Test;
import org.springframework.beans.ConfigurablePropertyAccessor;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.PropertyValues;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.format.support.DefaultFormattingConversionService;
@@ -91,7 +94,29 @@ public void skipsPropertyNotExposedByTheTypeHierarchy() {
MutablePropertyValues values = new MutablePropertyValues();
values.add("somethingWeird", "Value");
assertThat(bind(values)).isEqualTo(Collections.<String, Object> emptyMap());
assertThat(bind(values)).isEqualTo(Collections.emptyMap());
}
@Test // DATACMNS-1264
public void dropsMapExpressionsForCollectionReferences() {
ConfigurablePropertyAccessor accessor = new MapDataBinder(Bar.class, new DefaultFormattingConversionService())
.getPropertyAccessor();
assertThatExceptionOfType(NotWritablePropertyException.class) //
.isThrownBy(() -> accessor.setPropertyValue("fooBar['foo']", null)) //
.withCauseInstanceOf(SpelEvaluationException.class);
}
@Test // DATACMNS-1264
public void rejectsExpressionContainingTypeExpression() {
ConfigurablePropertyAccessor accessor = new MapDataBinder(Bar.class, new DefaultFormattingConversionService())
.getPropertyAccessor();
assertThatExceptionOfType(NotWritablePropertyException.class) //
.isThrownBy(() -> accessor.setPropertyValue("fooBar[T(java.lang.String)]", null)) //
.withCauseInstanceOf(SpelEvaluationException.class);
}
private static Map<String, Object> bind(PropertyValues values) {

0 comments on commit 613cf08

Please sign in to comment.