From 3f40278e57e104279a5fa68d6d529a1ed8614528 Mon Sep 17 00:00:00 2001 From: kevin pollet Date: Mon, 31 Jan 2011 15:16:59 +0100 Subject: [PATCH 1/6] HV-376: Fix regular expression used for path parsing. Allows all valid Java identifiers as property path parameter in validateValue and validateProperty methods as specified in Java Language Specification (chapter 3.8). --- .../src/main/java/org/hibernate/validator/engine/PathImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java index f154c01b55..a74a7fae9e 100644 --- a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java +++ b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java @@ -31,6 +31,7 @@ /** * @author Hardy Ferentschik * @author Gunnar Morling + * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public final class PathImpl implements Path, Serializable { @@ -43,7 +44,7 @@ public final class PathImpl implements Path, Serializable { * * @see Regular expression tester */ - private static final Pattern PATH_PATTERN = Pattern.compile( "(\\w+)(\\[(\\w*)\\])?(\\.(.*))*" ); + private static final Pattern PATH_PATTERN = Pattern.compile( "(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)(\\[(\\w*)\\])?(\\.(.*))*" ); private static final int PROPERTY_NAME_GROUP = 1; private static final int INDEXED_GROUP = 2; private static final int INDEX_GROUP = 3; From 18616dc4bc512b95b28aa4ea7cdea209099af9ad Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Thu, 3 Feb 2011 10:31:24 +0100 Subject: [PATCH 2/6] HV-376: Add tests for parsing of Java identifiers. --- .../validator/test/engine/PathImplTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/PathImplTest.java b/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/PathImplTest.java index 5ff081f753..411e9ecabf 100644 --- a/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/PathImplTest.java +++ b/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/PathImplTest.java @@ -40,6 +40,7 @@ /** * @author Hardy Ferentschik * @author Gunnar Morling + * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public class PathImplTest { @@ -76,6 +77,35 @@ public void testParsing() { assertEquals( path.toString(), property ); } + @Test + public void testParsingPropertyWithCurrencySymbol() { + PathImpl path = PathImpl.createPathFromString( "€Amount" ); + Iterator it = path.iterator(); + + assertEquals( it.next().getName(), "€Amount" ); + } + + @Test + public void testParsingPropertyWithGermanCharacter() { + PathImpl path = PathImpl.createPathFromString( "höchstBetrag" ); + Iterator it = path.iterator(); + + assertEquals( it.next().getName(), "höchstBetrag" ); + } + + @Test + public void testParsingPropertyWithUnicodeCharacter() { + PathImpl path = PathImpl.createPathFromString( "höchst\u00f6Betrag" ); + Iterator it = path.iterator(); + + assertEquals( it.next().getName(), "höchst\u00f6Betrag" ); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testParsingInvalidJavaProperty() { + PathImpl.createPathFromString( "1invalid" ); + } + @Test public void testParseMapBasedProperty() { String property = "order[foo].deliveryAddress"; From bc71d8656048871ea9687cd78c538ba063c01b4d Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Thu, 3 Feb 2011 10:46:12 +0100 Subject: [PATCH 3/6] HV-376: Add test for ValidateValue and ValidateProperty methods. To use currency symbol in source code, the source encoding has to be set to UTF-8. --- .../validator/test/engine/ValidatorTest.java | 30 ++++++++++++++++++- pom.xml | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/ValidatorTest.java b/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/ValidatorTest.java index e6a01f3825..520721f683 100644 --- a/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/ValidatorTest.java +++ b/hibernate-validator/src/test/java/org/hibernate/validator/test/engine/ValidatorTest.java @@ -23,18 +23,41 @@ import javax.validation.constraints.NotNull; import javax.validation.metadata.BeanDescriptor; -import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.hibernate.validator.test.util.TestUtil; + import static org.hibernate.validator.test.util.TestUtil.assertCorrectPropertyPaths; import static org.hibernate.validator.test.util.TestUtil.assertNumberOfViolations; +import static org.testng.Assert.assertTrue; /** * @author Hardy Ferentschik + * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public class ValidatorTest { + /** + * HV-376 + */ + @Test + public void testValidatePropertyWithCurrencySymbol() { + Validator validator = TestUtil.getValidator(); + Ticket testInstance = new Ticket(); + Set> constraintViolations = validator.validateProperty( testInstance, "€price" ); + assertNumberOfViolations( constraintViolations, 1 ); + } + + @Test + public void testValidateValueWithCurrencySymbol() { + Validator validator = TestUtil.getValidator(); + Ticket testInstance = new Ticket(); + Set> constraintViolations = validator.validateValue( + Ticket.class, "€price", testInstance.€price + ); + assertNumberOfViolations( constraintViolations, 1 ); + } + /** * HV-208 */ @@ -70,4 +93,9 @@ public boolean hasB() { return b; } } + + class Ticket { + @NotNull + Float €price; + } } diff --git a/pom.xml b/pom.xml index 65a00765b6..f00b5eb36b 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 1.6.1 + UTF-8 From 5af0d1df18077c416910629a22370913d8a2b50a Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 7 Feb 2011 13:40:34 +0100 Subject: [PATCH 4/6] HV-376: Use Character class methods instead of regex categories. --- .../hibernate/validator/engine/PathImpl.java | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java index a74a7fae9e..8148f18121 100644 --- a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java +++ b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java @@ -44,7 +44,7 @@ public final class PathImpl implements Path, Serializable { * * @see Regular expression tester */ - private static final Pattern PATH_PATTERN = Pattern.compile( "(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)(\\[(\\w*)\\])?(\\.(.*))*" ); + private static final Pattern PATH_PATTERN = Pattern.compile( "([^\\[\\.]+)(\\[(\\w*)\\])?(\\.(.*))*" ); private static final int PROPERTY_NAME_GROUP = 1; private static final int INDEXED_GROUP = 2; private static final int INDEX_GROUP = 3; @@ -285,8 +285,12 @@ private static PathImpl parseProperty(String property) { Matcher matcher = PATH_PATTERN.matcher( tmp ); if ( matcher.matches() ) { - // create the node String value = matcher.group( PROPERTY_NAME_GROUP ); + if ( !isValidJavaIdentifier( value ) ) { + throw new IllegalArgumentException( value + " is not a valid Java Identifier" ); + } + + // create the node path.addNode( value ); // is the node indexable @@ -320,4 +324,32 @@ private static PathImpl parseProperty(String property) { return path; } + + /** + * Validate that the given identifier is a valid Java identifier according to the Java Language Specification, + * chapter 3.8 + * + * @param identifier the identifier string + * @return true if the given identifier is a valid Java Identifier + * + * @throws IllegalArgumentException if the identifier is null + */ + private static boolean isValidJavaIdentifier(String identifier) { + Contracts.assertNotNull( identifier, "identifier param cannot be null" ); + + final char[] identifierChars = identifier.toCharArray(); + + if ( identifierChars.length == 0 || !Character.isJavaIdentifierStart( (int) identifierChars[0] ) ) { + return false; + } + + for ( int i = 1; i < identifierChars.length; i++ ) { + if ( !Character.isJavaIdentifierPart( (int) identifierChars[i] ) ) { + return false; + } + } + + return true; + } + } From 1a08d183bc42320eaf8b4caf415fa70d52c9ce05 Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 7 Feb 2011 16:17:39 +0100 Subject: [PATCH 5/6] HV-376: Make the regexp more readable. --- .../main/java/org/hibernate/validator/engine/PathImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java index 8148f18121..b5ef601a8b 100644 --- a/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java +++ b/hibernate-validator/src/main/java/org/hibernate/validator/engine/PathImpl.java @@ -44,7 +44,11 @@ public final class PathImpl implements Path, Serializable { * * @see Regular expression tester */ - private static final Pattern PATH_PATTERN = Pattern.compile( "([^\\[\\.]+)(\\[(\\w*)\\])?(\\.(.*))*" ); + private static final String LEADING_PROPERTY_GROUP = "[^\\[\\.]+"; // everything up to a [ or . + private static final String OPTIONAL_INDEX_GROUP = "\\[(\\w*)\\]"; + private static final String REMAINING_PROPERTY_STRING = "\\.(.*)"; // processed recursively + + private static final Pattern PATH_PATTERN = Pattern.compile( "(" + LEADING_PROPERTY_GROUP + ")(" + OPTIONAL_INDEX_GROUP + ")?(" + REMAINING_PROPERTY_STRING + ")*" ); private static final int PROPERTY_NAME_GROUP = 1; private static final int INDEXED_GROUP = 2; private static final int INDEX_GROUP = 3; From 2cecbc5d7284373cbe41c197cf48acf70081de01 Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Mon, 7 Feb 2011 16:26:10 +0100 Subject: [PATCH 6/6] HV-376: Add a comment for the UTF-8 source encoding property. --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index f00b5eb36b..3c48788dcc 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,8 @@ 1.6.1 + + UTF-8