6#include "validatoremail_p.h"
13#include <QRegularExpression>
24 :
ValidatorRule(*new ValidatorEmailPrivate(
field, threshold, options, messages, defValKey))
66 ValidatorEmailDiagnoseStruct diag;
68 if (ValidatorEmailPrivate::checkEmail(v, d->options, d->threshold, &diag)) {
69 if (!diag.literal.isEmpty()) {
97bool ValidatorEmailPrivate::checkEmail(
const QString &address,
98 ValidatorEmail::Options options,
100 ValidatorEmailDiagnoseStruct *diagnoseStruct)
106 EmailPart context = ComponentLocalpart;
108 EmailPart contextPrior = ComponentLocalpart;
113 QString parseLocalPart;
115 QString parseLiteral;
116 QMap<int, QString> atomListLocalPart;
117 QMap<int, QString> atomListDomain;
118 int elementCount = 0;
120 bool hypenFlag =
false;
121 bool endOrDie =
false;
126 const QString stringSpecials = QStringLiteral(
"()<>[]:;@\\,.\"");
133 const int atPos = address.
lastIndexOf(QLatin1Char(
'@'));
136 const QString local = address.
left(atPos);
137 const QString domain = address.
mid(atPos + 1);
138 bool asciiDomain =
true;
139 for (
const QChar &ch : domain) {
140 const ushort &uc = ch.unicode();
159 const int rawLength = email.
length();
161 for (
int i = 0; i < rawLength; i++) {
168 case ComponentLocalpart:
187 if (token == QLatin1Char(
'(')) {
188 if (elementLen == 0) {
199 context = ContextComment;
200 }
else if (token == QLatin1Char(
'.')) {
201 if (elementLen == 0) {
203 returnStatus.
push_back((elementCount == 0)
218 parseLocalPart += token;
219 atomListLocalPart[elementCount] = QString();
220 }
else if (token == QLatin1Char(
'"')) {
221 if (elementLen == 0) {
224 returnStatus.
push_back((elementCount == 0)
228 parseLocalPart += token;
229 atomListLocalPart[elementCount] += token;
233 context = ContextQuotedString;
245 if (elementLen == 0) {
254 context = ContextFWS;
256 }
else if (token == QLatin1Char(
'@')) {
258 if (contextStack.
size() != 1) {
260 qCCritical(C_VALIDATOR,
"ValidatorEmail: Unexpected item on context stack");
264 if (parseLocalPart.
isEmpty()) {
266 }
else if (elementLen == 0) {
268 }
else if (parseLocalPart.
size() > 64) {
273 }
else if ((contextPrior == ContextComment) || (contextPrior == ContextFWS)) {
287 context = ComponentDomain;
288 contextStack.
clear();
308 switch (contextPrior) {
313 case ContextQuotedString:
318 qCCritical(C_VALIDATOR,
319 "ValidatorEmail: More atext found where none is allowed, but "
320 "unrecognised prior context.");
324 contextPrior = context;
325 const ushort uni = token.
unicode();
327 if (!allowUtf8Local) {
328 if ((uni < 33) || (uni > 126) || stringSpecials.
contains(token)) {
334 if ((uni < 33) || (uni > 126) || stringSpecials.
contains(token)) {
341 parseLocalPart += token;
342 atomListLocalPart[elementCount] += token;
350 case ComponentDomain:
390 if (token == QLatin1Char(
'(')) {
391 if (elementLen == 0) {
395 returnStatus.
push_back((elementCount == 0)
405 context = ContextComment;
406 }
else if (token == QLatin1Char(
'.')) {
407 if (elementLen == 0) {
409 returnStatus.
push_back((elementCount == 0)
412 }
else if (hypenFlag) {
428 if (elementLen > 63) {
437 atomListDomain[elementCount] = QString();
438 parseDomain += token;
440 }
else if (token == QLatin1Char(
'[')) {
445 context = ComponentLiteral;
446 parseDomain += token;
447 atomListDomain[elementCount] += token;
448 parseLiteral = QString();
460 if (elementLen == 0) {
461 returnStatus.
push_back((elementCount == 0)
471 context = ContextFWS;
499 switch (contextPrior) {
504 case ComponentLiteral:
509 qCCritical(C_VALIDATOR,
510 "ValidatorEmail: More atext found where none is allowed, but "
511 "unrecognised prior context.");
516 const ushort uni = token.
unicode();
519 if ((uni < 33) || (uni > 126) || stringSpecials.
contains(token)) {
521 }
else if (token == QLatin1Char(
'-')) {
522 if (elementLen == 0) {
528 }
else if (!(((uni > 47) && (uni < 58)) || ((uni > 64) && (uni < 91)) ||
529 ((uni > 96) && (uni < 123)))) {
534 parseDomain += token;
535 atomListDomain[elementCount] += token;
542 case ComponentLiteral:
552 if (token == QLatin1Char(
']')) {
553 if (
static_cast<int>(
611 QString addressLiteral = parseLiteral;
613 QRegularExpression ipv4Regex(
614 QStringLiteral(
"\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25["
615 "0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"));
616 QRegularExpressionMatch ipv4Match = ipv4Regex.match(addressLiteral);
621 addressLiteral.
mid(0, index) +
634 QString ipv6 = addressLiteral.
mid(5);
635 const QStringList matchesIP = ipv6.
split(QLatin1Char(
':'));
636 int groupCount = matchesIP.
size();
637 index = ipv6.
indexOf(QLatin1String(
"::"));
641 if (groupCount != maxGroups) {
645 if (index != ipv6.
lastIndexOf(QLatin1String(
"::"))) {
648 if ((index == 0) || (index == (ipv6.
length() - 2))) {
652 if (groupCount > maxGroups) {
654 }
else if (groupCount == maxGroups) {
662 if ((ipv6.
size() == 1 && ipv6[0] == QLatin1Char(
':')) ||
663 (ipv6[0] == QLatin1Char(
':') && ipv6[1] != QLatin1Char(
':'))) {
667 }
else if (ipv6.
right(2).
at(1) == QLatin1Char(
':') &&
668 ipv6.
right(2).
at(0) != QLatin1Char(
':')) {
673 int unmatchedChars = 0;
674 for (
const QString &ip : matchesIP) {
676 QRegularExpression(QStringLiteral(
"^[0-9A-Fa-f]{0,4}$")))) {
680 if (unmatchedChars != 0) {
692 parseDomain += token;
693 atomListDomain[elementCount] += token;
695 contextPrior = context;
697 }
else if (token == QLatin1Char(
'\\')) {
700 context = ContextQuotedPair;
711 context = ContextFWS;
727 const ushort uni = token.
unicode();
730 if ((uni > 127) || (uni == 0) || (uni == QLatin1Char(
'['))) {
733 }
else if ((uni < 33) || (uni == 127)) {
737 parseLiteral += token;
738 parseDomain += token;
739 atomListDomain[elementCount] += token;
746 case ContextQuotedString:
754 if (token == QLatin1Char(
'\\')) {
756 context = ContextQuotedPair;
782 context = ContextFWS;
784 }
else if (token == QLatin1Char(
'"')) {
785 parseLocalPart += token;
786 atomListLocalPart[elementCount] += token;
788 contextPrior = context;
804 const ushort uni = token.
unicode();
806 if (!allowUtf8Local) {
807 if ((uni > 127) || (uni == 0) || (uni == 10)) {
809 }
else if ((uni < 32) || (uni == 127)) {
814 if ((uni > 127) || (uni == 0) || (uni == 10)) {
817 }
else if ((uni < 32) || (uni == 127)) {
823 parseLocalPart += token;
824 atomListLocalPart[elementCount] += token;
839 case ContextQuotedPair:
857 const ushort uni = token.
unicode();
861 }
else if (((uni < 31) && (uni != 9)) || (uni == 127)) {
872 contextPrior = context;
878 case ContextQuotedString:
879 parseLocalPart += QLatin1Char(
'\\');
880 parseLocalPart += token;
881 atomListLocalPart[elementCount] += QLatin1Char(
'\\');
882 atomListLocalPart[elementCount] += token;
886 case ComponentLiteral:
887 parseDomain += QLatin1Char(
'\\');
888 parseDomain += token;
889 atomListDomain[elementCount] += QLatin1Char(
'\\');
890 atomListDomain[elementCount] += token;
896 qCCritical(C_VALIDATOR,
897 "ValidatorEmail: Quoted pair logic invoked in an invalid context.");
910 if (token == QLatin1Char(
'(')) {
913 context = ContextComment;
914 }
else if (token == QLatin1Char(
')')) {
915 contextPrior = context;
934 }
else if (token == QLatin1Char(
'\\')) {
936 context = ContextQuotedPair;
947 context = ContextFWS;
964 const ushort uni = token.
unicode();
966 if ((uni > 127) || (uni == 0) || (uni == 10)) {
969 }
else if ((uni < 32) || (uni == 127)) {
997 if (crlf_count > 0) {
998 if (++crlf_count > 1) {
1018 if (crlf_count > 0) {
1022 contextPrior = context;
1049 qCCritical(C_VALIDATOR,
"ValidatorEmail: Unknown context");
1053 if (
static_cast<int>(
1061 if (
static_cast<int>(*std::max_element(returnStatus.
constBegin(), returnStatus.
constEnd())) <
1063 if (context == ContextQuotedString) {
1065 }
else if (context == ContextQuotedPair) {
1067 }
else if (context == ContextComment) {
1069 }
else if (context == ComponentLiteral) {
1073 }
else if (parseDomain.
isEmpty()) {
1075 }
else if (elementLen == 0) {
1077 }
else if (hypenFlag) {
1079 }
else if (parseDomain.
size() > 255) {
1083 }
else if ((parseLocalPart.
size() + 1 + parseDomain.
size()) > 254) {
1103 }
else if (elementLen > 63) {
1109 bool dnsChecked =
false;
1112 (
static_cast<int>(*std::max_element(returnStatus.
constBegin(), returnStatus.
constEnd())) <
1113 static_cast<int>(threshold))) {
1127 if (elementCount == 0) {
1128 parseDomain += QLatin1Char(
'.');
1138 if ((mxLookup.error() ==
QDnsLookup::NoError) && !mxLookup.mailExchangeRecords().empty()) {
1190 (
static_cast<int>(*std::max_element(returnStatus.
constBegin(), returnStatus.
constEnd())) <
1192 if (elementCount == 0) {
1196 if (QStringLiteral(
"0123456789").contains(atomListDomain[elementCount][0])) {
1201 if (returnStatus.
size() != 1) {
1202 QList<ValidatorEmail::Diagnose> _rs;
1203 for (
int j = 0; j < returnStatus.
size(); ++j) {
1212 returnStatus.
begin(), returnStatus.
end(), std::greater<ValidatorEmail::Diagnose>());
1217 if (diagnoseStruct) {
1218 diagnoseStruct->finalStatus = finalStatus;
1219 diagnoseStruct->returnStatus = returnStatus;
1220 diagnoseStruct->localpart = parseLocalPart;
1221 diagnoseStruct->domain = parseDomain;
1222 diagnoseStruct->literal = parseLiteral;
1225 ret = (
static_cast<int>(finalStatus) <
static_cast<int>(threshold));
1234 if (
label.isEmpty()) {
1238 c->
translate(
"Cutelyst::ValidatorEmail",
1239 "Address is valid. Please note that this does not mean that both the "
1240 "address and the domain actually exist. This address could be issued "
1241 "by the domain owner without breaking the rules of any RFCs.");
1245 "Cutelyst::ValidatorEmail",
1246 "Could not find an MX record for this address’ domain but an A record does exist.");
1250 "Cutelyst::ValidatorEmail",
1251 "Could neither find an MX record nor an A record for this address’ domain.");
1254 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1255 "Address is valid but at a Top Level Domain.");
1258 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1259 "Address is valid but the Top Level Domain begins with a number.");
1262 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1263 "Address is valid but contains a quoted string.");
1266 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1267 "Address is valid but uses an IP address instead of a domain name.");
1270 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1271 "Address is valid but uses an IP address that contains a :: only "
1272 "eliding one zero group. All implementations must accept and be "
1273 "able to handle any legitimate RFC 4291 format.");
1276 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address contains comments.");
1279 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1280 "Address contains folding white spaces like line breaks.");
1284 c->
translate(
"Cutelyst::ValidatorEmail",
"The local part is in a deprecated form.");
1287 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1288 "Address contains an obsolete form of folding white spaces.");
1291 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1292 "A quoted string contains a deprecated character.");
1295 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1296 "A quoted pair contains a deprecated character.");
1299 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1300 "Address contains a comment in a position that is deprecated.");
1303 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1304 "A comment contains a deprecated character.");
1308 "Cutelyst::ValidatorEmail",
1309 "Address contains a comment or folding white space around the @ sign.");
1312 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1313 "Address is RFC 5322 compliant but contains domain characters that "
1314 "are not allowed by DNS.");
1317 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address is too long.");
1320 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1321 "The local part of the address is too long.");
1324 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"The domain part is too long.");
1327 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1328 "The domain part contains an element that is too long.");
1331 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1332 "The domain literal is not a valid RFC 5321 address literal.");
1335 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1336 "The domain literal is not a valid RFC 5321 domain literal and it "
1337 "contains obsolete characters.");
1340 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1341 "The IPv6 literal address contains the wrong number of groups.");
1344 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1345 "The IPv6 literal address contains too many :: sequences.");
1348 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1349 "The IPv6 address contains an illegal group of characters.");
1352 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"The IPv6 address has too many groups.");
1355 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1356 "The IPv6 address starts with a single colon.");
1359 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1360 "The IPv6 address ends with a single colon.");
1363 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1364 "A domain literal contains a character that is not allowed.");
1367 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address has no local part.");
1370 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address has no domain part.");
1373 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1374 "The address must not contain consecutive dots.");
1377 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1378 "Address contains text after a comment or folding white space.");
1381 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1382 "Address contains text after a quoted string.");
1385 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1386 "Extra characters were found after the end of the domain literal.");
1390 "Cutelyst::ValidatorEmail",
1391 "The Address contains a character that is not allowed in a quoted pair.");
1394 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1395 "Address contains a character that is not allowed.");
1398 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1399 "A quoted string contains a character that is not allowed.");
1402 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1403 "A comment contains a character that is not allowed.");
1406 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1407 "The address can not end with a backslash.");
1410 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1411 "Neither part of the address may begin with a dot.");
1414 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1415 "Neither part of the address may end with a dot.");
1418 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1419 "A domain or subdomain can not begin with a hyphen.");
1422 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1423 "A domain or subdomain can not end with a hyphen.");
1426 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1427 "Unclosed quoted string. (Missing double quotation mark)");
1430 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1431 "Unclosed comment. (Missing closing parentheses)");
1434 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1435 "Domain literal is missing its closing bracket.");
1439 "Cutelyst::ValidatorEmail",
1440 "Folding white space contains consecutive line break sequences (CRLF).");
1443 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1444 "Folding white space ends with a line break sequence (CRLF).");
1447 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1448 "Address contains a carriage return (CR) that is not followed by a "
1452 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1453 "A fatal error occurred while parsing the address.");
1465 "Cutelyst::ValidatorEmail",
1466 "The address in the “%1” field is valid. Please note that this does not mean "
1467 "that both the address and the domain actually exist. This address could be "
1468 "issued by the domain owner without breaking the rules of any RFCs.")
1472 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1473 "Could not find an MX record for the address’ domain in the “%1” "
1474 "field but an A record does exist.")
1478 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1479 "Could neither find an MX record nor an A record for address’ "
1480 "domain in the “%1” field.")
1484 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1485 "The address in the “%1” field is valid but at a Top Level Domain.")
1489 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1490 "The address in the “%1” field is valid but the Top Level Domain "
1491 "begins with a number.")
1496 c->
translate(
"Cutelyst::ValidatorEmail",
1497 "The address in the “%1” field is valid but contains a quoted string.")
1501 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1502 "The address in the “%1” field is valid but uses an IP address "
1503 "instead of a domain name.")
1507 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1508 "The address in the “%1” field is valid but uses an IP address that "
1509 "contains a :: only eliding one zero group. All implementations "
1510 "must accept and be able to handle any legitimate RFC 4291 format.")
1514 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1515 "The address in the “%1” field contains comments.")
1519 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1520 "The address in the “%1” field contains folding white spaces like "
1526 "Cutelyst::ValidatorEmail",
1527 "The local part of the address in the “%1” field is in a deprecated form.")
1531 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1532 "The address in the “%1” field contains an obsolete form of folding "
1537 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1538 "A quoted string in the address in the “%1” field contains a "
1539 "deprecated character.")
1543 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1544 "A quoted pair in the address in the “%1” field contains a "
1545 "deprecate character.")
1549 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1550 "The address in the “%1” field contains a comment in a position "
1551 "that is deprecated.")
1557 "Cutelyst::ValidatorEmail",
1558 "A comment in the address in the “%1” field contains a deprecated character.")
1562 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1563 "The address in the “%1” field contains a comment or folding white "
1564 "space around the @ sign.")
1568 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1569 "The address in the “%1” field is RFC 5322 compliant but contains "
1570 "domain characters that are not allowed by DNS.")
1574 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1575 "The address in the “%1” field is too long.")
1579 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1580 "The local part of the address in the “%1” field is too long.")
1584 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1585 "The domain part of the address in the “%1” field is too long.")
1589 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1590 "The domain part of the address in the “%1” field contains an "
1591 "element that is too long.")
1595 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1596 "The domain literal of the address in the “%1” field is not a valid "
1597 "RFC 5321 address literal.")
1601 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1602 "The domain literal of the address in the “%1” field is not a valid "
1603 "RFC 5321 domain literal and it contains obsolete characters.")
1607 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1608 "The IPv6 literal of the address in the “%1” field contains the "
1609 "wrong number of groups.")
1613 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1614 "The IPv6 literal of the address in the “%1” field contains too "
1615 "many :: sequences.")
1619 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1620 "The IPv6 address of the email address in the “%1” field contains "
1621 "an illegal group of characters.")
1627 "Cutelyst::ValidatorEmail",
1628 "The IPv6 address of the email address in the “%1” field has too many groups.")
1632 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1633 "The IPv6 address of the email address in the “%1” field starts "
1634 "with a single colon.")
1638 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1639 "The IPv6 address of the email address in the “%1” field ends with "
1644 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1645 "A domain literal of the address in the “%1” field contains a "
1646 "character that is not allowed.")
1650 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1651 "The address in the “%1” field has no local part.")
1655 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1656 "The address in the “%1” field has no domain part.")
1660 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1661 "The address in the “%1” field must not contain consecutive dots.")
1665 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1666 "The address in the “%1” field contains text after a comment or "
1667 "folding white space.")
1671 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1672 "The address in the “%1” field contains text after a quoted string.")
1676 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1677 "Extra characters were found after the end of the domain literal of "
1678 "the address in the “%1” field.")
1682 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1683 "The address in the “%1” field contains a character that is not "
1684 "allowed in a quoted pair.")
1689 "Cutelyst::ValidatorEmail",
1690 "The address in the “%1” field contains a character that is not allowed.")
1694 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1695 "A quoted string in the address in the “%1” field contains a "
1696 "character that is not allowed.")
1700 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1701 "A comment in the address in the “%1” field contains a character "
1702 "that is not allowed.")
1706 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1707 "The address in the “%1” field can't end with a backslash.")
1712 c->
translate(
"Cutelyst::ValidatorEmail",
1713 "Neither part of the address in the “%1” field may begin with a dot.")
1717 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1718 "Neither part of the address in the “%1” field may end with a dot.")
1722 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1723 "A domain or subdomain of the address in the “%1” field can not "
1724 "begin with a hyphen.")
1728 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1729 "A domain or subdomain of the address in the “%1” field can not end "
1734 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1735 "Unclosed quoted string in the address in the “%1” field. (Missing "
1736 "double quotation mark)")
1740 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1741 "Unclosed comment in the address in the “%1” field. (Missing "
1742 "closing parentheses)")
1746 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1747 "Domain literal of the address in the “%1” field is missing its "
1752 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1753 "Folding white space in the address in the “%1” field contains "
1754 "consecutive line break sequences (CRLF).")
1758 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1759 "Folding white space in the address in the “%1” field ends with a "
1760 "line break sequence (CRLF).")
1764 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1765 "The address in the “%1” field contains a carriage return (CR) that "
1766 "is not followed by a line feed (LF).")
1771 c->
translate(
"Cutelyst::ValidatorEmail",
1772 "A fatal error occurred while parsing the address in the “%1” field.")
1786 if (
label.isEmpty()) {
1789 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address is valid.");
1792 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1793 "Address is valid but a DNS check was not successful.");
1796 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1797 "Address is valid for SMTP but has unusual elements.");
1800 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1801 "Address is valid within the message but can not be used unmodified "
1802 "for the envelope.");
1805 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1806 "Address contains deprecated elements but my still be valid in "
1807 "restricted contexts.");
1810 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1811 "The address is only valid according to the broad definition of RFC "
1812 "5322. It is otherwise invalid.");
1815 ret = c->
translate(
"Cutelyst::ValidatorEmail",
"Address is invalid for any purpose.");
1822 c->
translate(
"Cutelyst::ValidatorEmail",
"The address in the “%1” field is valid.")
1827 "Cutelyst::ValidatorEmail",
1828 "The address in the “%1” field is valid but a DNS check was not successful.")
1833 "Cutelyst::ValidatorEmail",
1834 "The address in the “%1” field is valid for SMTP but has unusual elements.")
1838 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1839 "The address in the “%1” field is valid within the message but can "
1840 "not be used unmodified for the envelope.")
1844 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1845 "The address in the “%1” field contains deprecated elements but my "
1846 "still be valid in restricted contexts.")
1850 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1851 "The address in the “%1” field is only valid according to the broad "
1852 "definition of RFC 5322. It is otherwise invalid.")
1856 ret = c->
translate(
"Cutelyst::ValidatorEmail",
1857 "The address in the “%1” field is invalid for any purpose.")
1869 const quint8 diag =
static_cast<quint8
>(diagnose);
1871 if (diag <
static_cast<quint8
>(
Valid)) {
1873 }
else if (diag <
static_cast<quint8
>(
DNSWarn)) {
1875 }
else if (diag <
static_cast<quint8
>(
RFC5321)) {
1877 }
else if (diag <
static_cast<quint8
>(
CFWS)) {
1879 }
else if (diag <
static_cast<quint8
>(
Deprecated)) {
1881 }
else if (diag <
static_cast<quint8
>(
RFC5322)) {
1903 ValidatorEmailDiagnoseStruct diag;
1904 ret = ValidatorEmailPrivate::checkEmail(email, options, threshold, &diag);
1907 *diagnoses = diag.returnStatus;
1913#include "moc_validatoremail.cpp"
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
static QString categoryString(Context *c, Category category, const QString &label=QString())
Returns a descriptive and translated string for the category.
static QString diagnoseString(Context *c, Diagnose diagnose, const QString &label=QString())
Returns a descriptive and translated string for the diagnose.
static Category category(Diagnose diagnose)
Returns the category the diagnose belongs to.
~ValidatorEmail() override
Deconstructs the email validator.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error if validation failed.
Diagnose
Single diagnose values that show why an address is not valid.
@ ErrorUnclosedDomLiteral
ValidatorEmail(const QString &field, Category threshold=RFC5321, Options options=NoOption, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new email validator.
Category
Validation category, used as threshold to define valid addresses.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
QString field() const
Returns the name of the field to validate.
void defaultValue(Context *c, ValidatorReturnType *result, const char *validatorName) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...
ValidatorRule(const QString &field, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new ValidatorRule with the given parameters.
QString value(const ParamsMultiMap ¶ms) const
Returns the value of the field from the input params.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
static bool validate(const QString &email, Category threshold=RFC5321, Options options=NoOption, QList< Diagnose > *diagnoses=nullptr)
Returns true if email is a valid address according to the Category given in the threshold.
The Cutelyst namespace holds all public Cutelyst API.
QMultiMap< QString, QString > ParamsMultiMap
bool isLetterOrNumber() const const
ushort unicode() const const
int exec(ProcessEventsFlags flags)
void append(const T &value)
const T & at(int i) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
bool contains(const T &value) const const
void push_back(const T &value)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString captured(int nth) const const
bool hasMatch() const const
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
const QChar at(int position) const const
int compare(const QString &other, Qt::CaseSensitivity cs) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromLatin1(const char *str, int size)
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
QString left(int n) const const
QString mid(int position, int n) const const
QString right(int n) const const
QByteArray toAce(const QString &domain)
QVariant fromValue(const T &value)
void setValue(const T &value)
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.