Browse Source

Fixed isWritable for badly formed SpEL expressions

Before this change isWritable() could return true
for a badly formed expression. That is because the
decision about whether something is writable was made
based on the node type rather than whether the node
represented something that could actually be resolved
to be a real thing. This change ensures a resolution
check is done and isWritable() should only return
true if a subsequent setValue() will succeed.

Issue: SPR-10610
pull/678/merge
Andy Clement 10 years ago
parent
commit
03fc9e89a0
  1. 2
      spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
  2. 48
      spring-expression/src/test/java/org/springframework/expression/spel/SetValueTests.java

2
spring-expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java

@ -384,7 +384,7 @@ public class PropertyOrFieldReference extends SpelNodeImpl { @@ -384,7 +384,7 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
@Override
public boolean isWritable() {
return true;
return this.ref.isWritableProperty(this.ref.name, this.contextObject, this.evalContext);
}
}

48
spring-expression/src/test/java/org/springframework/expression/spel/SetValueTests.java

@ -75,6 +75,54 @@ public class SetValueTests extends AbstractExpressionTests { @@ -75,6 +75,54 @@ public class SetValueTests extends AbstractExpressionTests {
setValue("arrayContainer.bytes[1]", (byte) 3);
setValue("arrayContainer.chars[1]", (char) 3);
}
@Test
public void testIsWritableForInvalidExpressions_SPR10610() {
Expression e = null;
StandardEvaluationContext lContext = TestScenarioCreator.getTestEvaluationContext();
// PROPERTYORFIELDREFERENCE
// Non existent field (or property):
e = parser.parseExpression("arrayContainer.wibble");
assertFalse("Should not be writable!",e.isWritable(lContext));
e = parser.parseExpression("arrayContainer.wibble.foo");
try {
assertFalse("Should not be writable!",e.isWritable(lContext));
fail("Should have had an error because wibble does not really exist");
} catch (SpelEvaluationException see) {
// org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 15): Property or field 'wibble' cannot be found on object of type 'org.springframework.expression.spel.testresources.ArrayContainer' - maybe not public?
// at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:225)
// success!
}
// VARIABLE
// the variable does not exist (but that is OK, we should be writable)
e = parser.parseExpression("#madeup1");
assertTrue("Should be writable!",e.isWritable(lContext));
e = parser.parseExpression("#madeup2.bar"); // compound expression
assertFalse("Should not be writable!",e.isWritable(lContext));
// INDEXER
// non existent indexer (wibble made up)
e = parser.parseExpression("arrayContainer.wibble[99]");
try {
assertFalse("Should not be writable!",e.isWritable(lContext));
fail("Should have had an error because wibble does not really exist");
} catch (SpelEvaluationException see) {
// success!
}
// non existent indexer (index via a string)
e = parser.parseExpression("arrayContainer.ints['abc']");
try {
assertFalse("Should not be writable!",e.isWritable(lContext));
fail("Should have had an error because wibble does not really exist");
} catch (SpelEvaluationException see) {
// success!
}
}
@Test
public void testSetArrayElementValueAllPrimitiveTypesErrors() {

Loading…
Cancel
Save