From 29bd0f42bf63e28d9a71adef02af67b319144576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Mon, 24 Feb 2020 17:58:41 +0100 Subject: [PATCH] HV-1774 Do not interpret '$\A{1+1}' in message templates --- .../messageinterpolation/parser/ELState.java | 6 +++++- .../TokenCollectorTest.java | 21 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java index 9460fae057..fda95a153c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java @@ -56,7 +56,11 @@ public void handleEndTerm(char character, TokenCollector tokenCollector) throws @Override public void handleEscapeCharacter(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { - tokenCollector.transitionState( new EscapedState( this ) ); + tokenCollector.appendToToken( EL_DESIGNATOR ); + tokenCollector.appendToToken( character ); + // Do not go back to this state after the escape: $\ is not the start of an EL expression + ParserState stateAfterEscape = new MessageState(); + tokenCollector.transitionState( new EscapedState( stateAfterEscape ) ); } @Override diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenCollectorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenCollectorTest.java index 972a9e0513..ab9299f17a 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenCollectorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenCollectorTest.java @@ -8,7 +8,11 @@ import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTermType; import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageDescriptorFormatException; +import org.hibernate.validator.internal.engine.messageinterpolation.parser.Token; import org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenCollector; + +import org.assertj.core.api.Assertions; +import org.assertj.core.api.ListAssert; import org.testng.annotations.Test; /** @@ -29,10 +33,25 @@ public void testParameterWithoutOpeningBraceThrowsException() throws Exception { } @Test(expectedExceptions = MessageDescriptorFormatException.class, expectedExceptionsMessageRegExp = "HV000168.*") - public void testELExpressionWithoutOpeningBraceThrowsException() throws Exception { + public void testELExpressionDollarThenClosingBraceThrowsException() throws Exception { new TokenCollector( "$}", InterpolationTermType.EL ); } + @Test + public void testELExpressionDollarThenEscapeInterpretedAsLiterals() { + ListAssert assertion = Assertions.assertThat( + new TokenCollector( "$\\A{1+1}", InterpolationTermType.EL ) + .getTokenList() + ) + .hasSize( 2 ); + assertion.element( 0 ) + .returns( "$\\A", Token::getTokenValue ) + .returns( false, Token::isParameter ); + assertion.element( 1 ) + .returns( "{1+1}", Token::getTokenValue ) + .returns( false, Token::isParameter ); + } + @Test(expectedExceptions = MessageDescriptorFormatException.class, expectedExceptionsMessageRegExp = "HV000168.*") public void testTermWithoutClosingBraceThrowsException() throws Exception { new TokenCollector( "{foo", InterpolationTermType.PARAMETER );