Bug 884332 - Limit domain labels to 63 chars in HTMLInputElement::IsValidEmailAddress. r=mounir

This commit is contained in:
Birunthan Mohanathas 2013-08-14 08:51:55 -04:00
parent c690916d16
commit b9d171dfa6
2 changed files with 50 additions and 18 deletions

View File

@ -5743,30 +5743,50 @@ HTMLInputElement::IsValidEmailAddress(const nsAString& aValue)
uint32_t i = 0;
uint32_t length = value.Length();
// Email addresses can't be empty and can't end with a '.' or '-'.
if (length == 0 || value[length - 1] == '.' || value[length - 1] == '-') {
return false;
}
uint32_t atPos = (uint32_t)value.FindChar('@');
// Email addresses must contain a '@', but can't begin or end with it.
if (atPos == (uint32_t)kNotFound || atPos == 0 || atPos == length - 1) {
return false;
}
// Puny-encode the string if needed before running the validation algorithm.
nsCOMPtr<nsIIDNService> idnSrv = do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv) {
// ConvertUTF8toACE() treats 'username@domain' as a single label so we need
// to puny-encode the username and domain parts separately.
const nsDependentCSubstring username = Substring(value, 0, atPos);
bool ace;
if (NS_SUCCEEDED(idnSrv->IsACE(value, &ace)) && !ace) {
nsAutoCString punyCodedValue;
if (NS_SUCCEEDED(idnSrv->ConvertUTF8toACE(value, punyCodedValue))) {
value = punyCodedValue;
length = value.Length();
if (NS_SUCCEEDED(idnSrv->IsACE(username, &ace)) && !ace) {
nsAutoCString usernameACE;
// TODO: Bug 901347: Usernames longer than 63 chars are not converted by
// ConvertUTF8toACE(). For now, continue on even if the conversion fails.
if (NS_SUCCEEDED(idnSrv->ConvertUTF8toACE(username, usernameACE))) {
value.Replace(0, atPos, usernameACE);
atPos = usernameACE.Length();
}
}
const nsDependentCSubstring domain = Substring(value, atPos + 1);
if (NS_SUCCEEDED(idnSrv->IsACE(domain, &ace)) && !ace) {
nsAutoCString domainACE;
if (NS_FAILED(idnSrv->ConvertUTF8toACE(domain, domainACE))) {
return false;
}
value.Replace(atPos + 1, domain.Length(), domainACE);
}
length = value.Length();
} else {
NS_ERROR("nsIIDNService isn't present!");
}
// If the email address is empty, begins with an '@'
// or ends with a '.' or '-', we know it's invalid.
if (length == 0 || value[0] == '@' || value[length-1] == '.' ||
value[length-1] == '-') {
return false;
}
// Parsing the username.
for (; i < length && value[i] != '@'; ++i) {
for (; i < atPos; ++i) {
PRUnichar c = value[i];
// The username characters have to be in this list to be valid.
@ -5779,10 +5799,8 @@ HTMLInputElement::IsValidEmailAddress(const nsAString& aValue)
}
}
// If there is no domain name, that's not a valid email address.
if (++i >= length) {
return false;
}
// Skip the '@'.
++i;
// The domain name can't begin with a dot or a dash.
if (value[i] == '.' || value[i] == '-') {

View File

@ -112,6 +112,20 @@ var values = [
// Long strings with UTF-8.
[ 'this.is.email.should.be.longer.than.sixty.four.characters.föö@mözillä.tld', true ],
[ 'this-is-email-should-be-longer-than-sixty-four-characters-föö@mözillä.tld', true, true ],
// Long labels.
[ 'foo@thislabelisexactly63characterssssssssssssssssssssssssssssssssss', true ],
[ 'foo@thislabelisexactly63characterssssssssssssssssssssssssssssssssss.com', true ],
[ 'foo@foo.thislabelisexactly63characterssssssssssssssssssssssssssssssssss.com', true ],
[ 'foo@foo.thislabelisexactly63characterssssssssssssssssssssssssssssssssss', true ],
[ 'foo@thislabelisexactly64charactersssssssssssssssssssssssssssssssssss', false ],
[ 'foo@thislabelisexactly64charactersssssssssssssssssssssssssssssssssss.com', false ],
[ 'foo@foo.thislabelisexactly64charactersssssssssssssssssssssssssssssssssss.com', false ],
[ 'foo@foo.thislabelisexactly64charactersssssssssssssssssssssssssssssssssss', false ],
// Long labels with UTF-8.
[ 'foo@thisläbelisexäctly63charäcterssssssssssssssssssssssssssssssssss', false ],
[ 'foo@thisläbelisexäctly63charäcterssssssssssssssssssssssssssssssssss.com', false ],
[ 'foo@foo.thisläbelisexäctly63charäcterssssssssssssssssssssssssssssssssss.com', false ],
[ 'foo@foo.thisläbelisexäctly63charäcterssssssssssssssssssssssssssssssssss', false ],
// The domains labels (sub-domains or tld) can't start or finish with a '-'
[ 'foo@foo-bar', true ],
[ 'foo@-foo', false ],
@ -179,7 +193,7 @@ for (c of legalCharacters) {
values.push(["foo@foo.bar" + c, true]);
}
// Add the concatenation of all legal characters too.
values.push(["foo@bar.com" + legalCharacters, true]);
values.push(["foo@bar." + legalCharacters, true]);
// Add domain illegal characters.
illegalCharacters = "()<>[]:;@\\,!#$%&'*+/=?^_`{|}~ \t";