diff --git a/build.gradle b/build.gradle index df3966c..6bb38d6 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' testCompile group: 'com.tngtech.java', name: 'junit-dataprovider', version: '1.9.2' testCompile "org.mockito:mockito-core:1.+" + testCompile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' } def siteUrl = 'https://github.com/egulias/EmailValidator4J' diff --git a/src/main/java/emailvalidator4j/lexer/EmailLexer.java b/src/main/java/emailvalidator4j/lexer/EmailLexer.java index 7d56eb3..f743628 100644 --- a/src/main/java/emailvalidator4j/lexer/EmailLexer.java +++ b/src/main/java/emailvalidator4j/lexer/EmailLexer.java @@ -16,8 +16,10 @@ public class EmailLexer { public void lex(String input) { Pattern pattern = Pattern.compile( - "(([a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|[^\\u0000-\\u007F])+[46]?)|([0-9]+)|(\r\n)|(::)|(\\s+?)|(.)|(\\p{Cc}+)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE + "(([a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|[^\\u0000-\\u007F])+[46]?)|([0-9]+)|(\r\n)|(::)|(\\s+?)|(.)|(\\p{Cc}+)", + Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE ); + Matcher matcher = pattern.matcher(input); this.reset(); diff --git a/src/main/java/emailvalidator4j/parser/DomainPart.java b/src/main/java/emailvalidator4j/parser/DomainPart.java index 72e2f3e..ae8a09c 100755 --- a/src/main/java/emailvalidator4j/parser/DomainPart.java +++ b/src/main/java/emailvalidator4j/parser/DomainPart.java @@ -13,8 +13,8 @@ final class DomainPart extends Parser { private static final Pattern subDomainIllegalCharacters = Pattern.compile("[^a-zA-Z0-9\\-\\x00007F-\\u10FFFF]"); - private static final int DOMAINPART_MAX_LENGTH = 255; private static final int LABEL_MAX_LENGTH = 63; + public static final int DOMAINPART_MAX_LENGTH = 255; private final HashSet notAllowedTokens = new HashSet(2) {{ add(Tokens.BACKSLASH); add(Tokens.SLASH); diff --git a/src/main/java/emailvalidator4j/parser/Email.java b/src/main/java/emailvalidator4j/parser/Email.java index 4f70c30..5054458 100644 --- a/src/main/java/emailvalidator4j/parser/Email.java +++ b/src/main/java/emailvalidator4j/parser/Email.java @@ -24,9 +24,12 @@ public Email(EmailLexer lexer) { } public void parse(String email) throws InvalidEmail { - this.lexer.lex(Optional.ofNullable(email).orElseThrow(() -> - new InvalidEmail("Empty email") - )); + + String nonEmptyEmail = Optional.ofNullable(email).orElseThrow(() -> + new InvalidEmail("Empty email")); + this.validateLength(nonEmptyEmail); + + this.lexer.lex(nonEmptyEmail); if (!this.lexer.find(Tokens.AT)) { throw new NoLocalPart("No local part found"); @@ -40,6 +43,14 @@ public void parse(String email) throws InvalidEmail { this.domainPartParser.parse(this.lexer.toString()); } + private void validateLength(String email) throws InvalidEmail { + int maxLength = LocalPart.RFC5321_LOCALPART_MAX_LENGTH + DomainPart.DOMAINPART_MAX_LENGTH + 1; + + if (email.length() > maxLength) { + throw new InvalidEmail("email too long"); + } + } + public List getWarnings() { List warnings = this.localPartParser.getWarnings(); warnings.addAll(this.domainPartParser.getWarnings()); diff --git a/src/main/java/emailvalidator4j/parser/LocalPart.java b/src/main/java/emailvalidator4j/parser/LocalPart.java index 9e97e74..e42409f 100644 --- a/src/main/java/emailvalidator4j/parser/LocalPart.java +++ b/src/main/java/emailvalidator4j/parser/LocalPart.java @@ -13,7 +13,7 @@ final class LocalPart extends Parser { private boolean closingQuote = false; private boolean parseDQuote = true; - private static int RFC5321_LOCALPART_MAX_LENGTH = 64; + public static int RFC5321_LOCALPART_MAX_LENGTH = 64; LocalPart (EmailLexer lexer) { super(lexer); diff --git a/src/test/java/emailvalidator4j/EmailValidatorTest.java b/src/test/java/emailvalidator4j/EmailValidatorTest.java index 73480df..d101559 100644 --- a/src/test/java/emailvalidator4j/EmailValidatorTest.java +++ b/src/test/java/emailvalidator4j/EmailValidatorTest.java @@ -3,6 +3,7 @@ import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; +import org.apache.commons.lang3.StringUtils; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -134,4 +135,11 @@ public void warningsAreExposed() { validator.isValid("test@[127.0.0.0]"); Assert.assertFalse(validator.getWarnings().isEmpty()); } + + @Test + public void controlStringOverflow() { + String filled = StringUtils.repeat("a", 2000); + EmailValidator validator = new EmailValidator(); + Assert.assertFalse(validator.isValid(filled.concat("@example.com"))); + } }