diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java index 1eb1226706f..eb86e5bea8d 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java @@ -336,7 +336,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser { if (maybeEatMethodOrProperty(nullSafeNavigation) || maybeEatFunctionOrVar() || maybeEatProjection(nullSafeNavigation) || maybeEatSelection(nullSafeNavigation)) { return pop(); } - raiseInternalException(t.startpos,SpelMessage.UNEXPECTED_DATA_AFTER_DOT,toString(peekToken())); + if (peekToken()==null) { + // unexpectedly ran out of data + raiseInternalException(t.startpos,SpelMessage.OOD); + } else { + raiseInternalException(t.startpos,SpelMessage.UNEXPECTED_DATA_AFTER_DOT,toString(peekToken())); + } return null; } diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java index 1e38f1450ae..354ccedddeb 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java @@ -20,8 +20,8 @@ import java.util.List; import java.util.Map; import junit.framework.Assert; -import org.junit.Test; +import org.junit.Test; import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; @@ -222,6 +222,20 @@ public class EvaluationTests extends ExpressionTestCase { "org.springframework.expression.spel.testresources.Inventor"); } + @Test + public void testRogueTrailingDotCausesNPE_SPR6866() { + try { + new SpelExpressionParser().parseExpression("placeOfBirth.foo."); + Assert.fail("Should have failed to parse"); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.OOD,spe.getMessageCode()); + Assert.assertEquals(16,spe.getPosition()); + } + } + + // nested properties @Test public void testPropertiesNested01() {