This is an automated email from the ASF dual-hosted git repository. sebb pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-validator.git
The following commit(s) were added to refs/heads/master by this push: new 44522d2 VALIDATOR-473 User specified DomainValidator 44522d2 is described below commit 44522d25d578e74175e0908dc6e75e387a631a38 Author: Sebb <s...@apache.org> AuthorDate: Tue Jul 28 21:07:58 2020 +0100 VALIDATOR-473 User specified DomainValidator --- src/changes/changes.xml | 3 ++ .../commons/validator/routines/EmailValidator.java | 34 +++++++++++++----- .../commons/validator/routines/UrlValidator.java | 40 ++++++++++++++++++++-- .../validator/routines/EmailValidatorTest.java | 27 +++++++++++++++ .../validator/routines/UrlValidatorTest.java | 20 +++++++++++ 5 files changed, 114 insertions(+), 10 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 4b413bb..7458a04 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -99,6 +99,9 @@ Apache Commons Validator. For the current list of dependencies, please see http://commons.apache.org/validator/dependencies.html "> + <action issue="VALIDATOR-473" type="add" dev="sebb"> + Allow Email- and UrlValidator to use specified DomainValidator + </action> <action issue="VALIDATOR-403" type="fix" dev="sebb" due-to="Tanya"> Accept Discover cards of 17 digits long that start with 6011 </action> diff --git a/src/main/java/org/apache/commons/validator/routines/EmailValidator.java b/src/main/java/org/apache/commons/validator/routines/EmailValidator.java index 51337d9..6279ae2 100644 --- a/src/main/java/org/apache/commons/validator/routines/EmailValidator.java +++ b/src/main/java/org/apache/commons/validator/routines/EmailValidator.java @@ -52,7 +52,6 @@ public class EmailValidator implements Serializable { private static final int MAX_USERNAME_LEN = 64; - private final boolean allowLocal; private final boolean allowTld; /** @@ -80,6 +79,8 @@ public class EmailValidator implements Serializable { */ private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL_WITH_TLD = new EmailValidator(true, true); + private final DomainValidator domainValidator; + /** * Returns the Singleton instance of this validator. * @@ -125,15 +126,36 @@ public class EmailValidator implements Serializable { } /** + * constructor for creating instances with the specified domainValidator + * + * @param allowLocal Should local addresses be considered valid? + * @param allowTld Should TLDs be allowed? + * @param domainValidator allow override of the DomainValidator. + * The instance must have the same allowLocal setting. + * @since 1.7 + */ + public EmailValidator(boolean allowLocal, boolean allowTld, DomainValidator domainValidator) { + super(); + this.allowTld = allowTld; + if (domainValidator == null) { + throw new IllegalArgumentException("DomainValidator cannot be null"); + } else { + if (domainValidator.isAllowLocal() != allowLocal) { + throw new IllegalArgumentException("DomainValidator must agree with allowLocal setting"); + } + this.domainValidator = domainValidator; + } + } + + /** * Protected constructor for subclasses to use. * * @param allowLocal Should local addresses be considered valid? * @param allowTld Should TLDs be allowed? */ protected EmailValidator(boolean allowLocal, boolean allowTld) { - super(); - this.allowLocal = allowLocal; this.allowTld = allowTld; + this.domainValidator = DomainValidator.getInstance(allowLocal); } /** @@ -142,9 +164,7 @@ public class EmailValidator implements Serializable { * @param allowLocal Should local addresses be considered valid? */ protected EmailValidator(boolean allowLocal) { - super(); - this.allowLocal = allowLocal; - this.allowTld = false; + this(allowLocal, false); } /** @@ -196,8 +216,6 @@ public class EmailValidator implements Serializable { return inetAddressValidator.isValid(ipDomainMatcher.group(1)); } // Domain is symbolic name - DomainValidator domainValidator = - DomainValidator.getInstance(allowLocal); if (allowTld) { return domainValidator.isValid(domain) || (!domain.startsWith(".") && domainValidator.isValidTld(domain)); } else { diff --git a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java index 11e69b9..74b0d30 100644 --- a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java +++ b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java @@ -182,6 +182,8 @@ public class UrlValidator implements Serializable { return DEFAULT_URL_VALIDATOR; } + private final DomainValidator domainValidator; + /** * Create a UrlValidator with default properties. */ @@ -245,7 +247,29 @@ public class UrlValidator implements Serializable { * enables both of those options. */ public UrlValidator(String[] schemes, RegexValidator authorityValidator, long options) { + this(schemes, authorityValidator, options, DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS, options))); + } + + /** + * Customizable constructor. Validation behavior is modifed by passing in options. + * @param schemes the set of valid schemes. Ignored if the ALLOW_ALL_SCHEMES option is set. + * @param authorityValidator Regular expression validator used to validate the authority part + * @param options Validation options. Set using the public constants of this class. + * To set multiple options, simply add them together: + * <p><code>ALLOW_2_SLASHES + NO_FRAGMENTS</code></p> + * enables both of those options. + * @param domainValidator the DomainValidator to use; must agree with ALLOW_LOCAL_URLS setting + * @since 1.7 + */ + public UrlValidator(String[] schemes, RegexValidator authorityValidator, long options, DomainValidator domainValidator) { this.options = options; + if (domainValidator == null) { + throw new IllegalArgumentException("DomainValidator must not be null"); + } + if (domainValidator.isAllowLocal() != ((options & ALLOW_LOCAL_URLS) > 0)){ + throw new IllegalArgumentException("DomainValidator disagrees with ALLOW_LOCAL_URLS setting"); + } + this.domainValidator = domainValidator; if (isOn(ALLOW_ALL_SCHEMES)) { allowedSchemes = Collections.emptySet(); @@ -380,8 +404,7 @@ public class UrlValidator implements Serializable { String hostLocation = authorityMatcher.group(PARSE_AUTHORITY_HOST_IP); // check if authority is hostname or IP address: // try a hostname first since that's much more likely - DomainValidator domainValidator = DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS)); - if (!domainValidator.isValid(hostLocation)) { + if (!this.domainValidator.isValid(hostLocation)) { // try an IPv4 address InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); if (!inetAddressValidator.isValidInet4Address(hostLocation)) { @@ -502,6 +525,19 @@ public class UrlValidator implements Serializable { } /** + * Tests whether the given flag is on. If the flag is not a power of 2 + * (e.g. 3) this tests whether the combination of flags is on. + * + * @param flag Flag value to check. + * @param options what to check + * + * @return whether the specified flag value is on. + */ + private static boolean isOn(long flag, long options) { + return (options & flag) > 0; + } + + /** * Tests whether the given flag is off. If the flag is not a power of 2 * (ie. 3) this tests whether the combination of flags is off. * diff --git a/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java b/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java index fe9ddff..4f0d28e 100644 --- a/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java +++ b/src/test/java/org/apache/commons/validator/routines/EmailValidatorTest.java @@ -565,4 +565,31 @@ public class EmailValidatorTest { public void testValidator374() { assertTrue(validator.isValid("abc@school.school")); } + + @Test(expected = IllegalArgumentException.class) + public void testValidator473_1() { // reject null DomainValidator + new EmailValidator(false, false, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testValidator473_2() { // reject null DomainValidator with mismatched allowLocal + List<DomainValidator.Item> items = new ArrayList<>(); + new EmailValidator(false, false, DomainValidator.getInstance(true, items)); + } + + @Test(expected = IllegalArgumentException.class) + public void testValidator473_3() { // reject null DomainValidator with mismatched allowLocal + List<DomainValidator.Item> items = new ArrayList<>(); + new EmailValidator(true, false, DomainValidator.getInstance(false, items)); + } + + @Test + public void testValidator473_4() { // Show that can override domain validation + assertFalse(validator.isValidDomain("test.local")); + List<DomainValidator.Item> items = new ArrayList<>(); + items.add(new DomainValidator.Item(DomainValidator.ArrayType.GENERIC_PLUS, new String[]{"local"})); + EmailValidator val = new EmailValidator(true, false, DomainValidator.getInstance(true, items)); + assertTrue(val.isValidDomain("test.local")); + } + } diff --git a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java index 3f9d4ef..a436698 100644 --- a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java +++ b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java @@ -18,6 +18,9 @@ package org.apache.commons.validator.routines; import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.List; + import org.apache.commons.validator.ResultPair; import org.junit.Before; import org.junit.Test; @@ -358,6 +361,23 @@ public class UrlValidatorTest { assertTrue(urlValidator.isValid("http://[::FFFF:129.144.52.38]:80/index.html")); } + @Test(expected = IllegalArgumentException.class) + public void testValidator473_1() { // reject null DomainValidator + new UrlValidator(new String[]{}, null, 0L, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testValidator473_2() { // reject null DomainValidator with mismatched allowLocal + List<DomainValidator.Item> items = new ArrayList<>(); + new UrlValidator(new String[]{}, null, 0L, DomainValidator.getInstance(true, items)); + } + + @Test(expected = IllegalArgumentException.class) + public void testValidator473_3() { // reject null DomainValidator with mismatched allowLocal + List<DomainValidator.Item> items = new ArrayList<>(); + new UrlValidator(new String[]{}, null, UrlValidator.ALLOW_LOCAL_URLS, DomainValidator.getInstance(false, items)); + } + static boolean incrementTestPartsIndex(int[] testPartsIndex, Object[] testParts) { boolean carry = true; //add 1 to lowest order part. boolean maxIndex = true;