SPR-7209: parsing poorly formed Elvis expressions

This commit is contained in:
Andy Clement 2010-05-18 18:44:40 +00:00
parent ae56f3a361
commit 101d8381ef
3 changed files with 59 additions and 1 deletions

View File

@ -42,7 +42,7 @@ public class Elvis extends SpelNodeImpl {
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
TypedValue value = children[0].getValueInternal(state);
if (value.getValue()!=null) {
if (value.getValue()!=null && !((value.getValue() instanceof String) && ((String)value.getValue()).length()==0)) {
return value;
} else {
return children[1].getValueInternal(state);

View File

@ -135,14 +135,26 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
if (moreTokens()) {
Token t = peekToken();
if (t.kind==TokenKind.ASSIGN) { // a=b
if (expr==null) {
expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1));
}
nextToken();
SpelNodeImpl assignedValue = eatLogicalOrExpression();
return new Assign(toPos(t),expr,assignedValue);
} else if (t.kind==TokenKind.ELVIS) { // a?:b (a if it isn't null, otherwise b)
if (expr==null) {
expr = new NullLiteral(toPos(t.startpos-1,t.endpos-2));
}
nextToken(); // elvis has left the building
SpelNodeImpl valueIfNull = eatExpression();
if (valueIfNull==null) {
valueIfNull = new NullLiteral(toPos(t.startpos+1,t.endpos+1));
}
return new Elvis(toPos(t),expr,valueIfNull);
} else if (t.kind==TokenKind.QMARK) { // a?b:c
if (expr==null) {
expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1));
}
nextToken();
SpelNodeImpl ifTrueExprValue = eatExpression();
eatToken(TokenKind.COLON);

View File

@ -627,4 +627,50 @@ public class SpringEL300Tests extends ExpressionTestCase {
// end bean resolver tests
@Test
public void elvis_SPR7209_1() {
StandardEvaluationContext eContext = new StandardEvaluationContext(new XX());
Expression expr = null;
// Different parts of elvis expression are null
expr = new SpelExpressionParser().parseRaw("(?:'default')");
Assert.assertEquals("default", expr.getValue());
expr = new SpelExpressionParser().parseRaw("?:'default'");
Assert.assertEquals("default", expr.getValue());
expr = new SpelExpressionParser().parseRaw("?:");
Assert.assertEquals(null, expr.getValue());
// Different parts of ternary expression are null
try {
expr = new SpelExpressionParser().parseRaw("(?'abc':'default')");
expr.getValue(eContext);
Assert.fail();
} catch (SpelEvaluationException see ) {
Assert.assertEquals(SpelMessage.TYPE_CONVERSION_ERROR,see.getMessageCode());
}
expr = new SpelExpressionParser().parseRaw("(false?'abc':null)");
Assert.assertEquals(null, expr.getValue());
// Assignment
try {
expr = new SpelExpressionParser().parseRaw("(='default')");
expr.getValue(eContext);
Assert.fail();
} catch (SpelEvaluationException see ) {
Assert.assertEquals(SpelMessage.SETVALUE_NOT_SUPPORTED,see.getMessageCode());
}
}
@Test
public void elvis_SPR7209_2() {
Expression expr = null;
// Have empty string treated as null for elvis
expr = new SpelExpressionParser().parseRaw("?:'default'");
Assert.assertEquals("default", expr.getValue());
expr = new SpelExpressionParser().parseRaw("\"\"?:'default'");
Assert.assertEquals("default", expr.getValue());
expr = new SpelExpressionParser().parseRaw("''?:'default'");
Assert.assertEquals("default", expr.getValue());
}
}