6#include "validatoremail_p.h"
20 u
"\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25["
21 "0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"_s};
23const QString ValidatorEmailPrivate::stringSpecials{u
"()<>[]:;@\\,.\""_s};
30 :
ValidatorRule(*new ValidatorEmailPrivate(field, threshold, options, messages, defValKey))
45 qCWarning(C_VALIDATOR) <<
"ValidatorEmail: using the CheckDNS option on validate() is"
46 <<
"not supported anymore. Use validateCb().";
51 ValidatorEmailDiagnoseStruct diag;
53 if (ValidatorEmailPrivate::checkEmail(v, d->options, d->threshold, &diag)) {
54 if (!diag.literal.isEmpty()) {
64 result.
extra = QVariant::fromValue<QList<Diagnose>>(diag.returnStatus);
83 [c, cb,
this, v](
bool isValid,
86 ValidatorReturnType rt;
87 rt.extra = QVariant::fromValue<QList<Diagnose>>(diagnoses);
89 rt.value.setValue(cleanedEmail);
91 qCDebug(C_VALIDATOR).noquote() << debugString(c) << diagnoses;
93 validationError(c, QVariant::fromValue<Diagnose>(diagnoses.at(0)));
111bool ValidatorEmailPrivate::checkEmail(
const QString &address,
112 ValidatorEmail::Options options,
114 ValidatorEmailDiagnoseStruct *diagnoseStruct)
118 EmailPart context = ComponentLocalpart;
120 EmailPart contextPrior = ComponentLocalpart;
130 int elementCount = 0;
132 bool hyphenFlag =
false;
133 bool endOrDie =
false;
145 const QString domain = address.
mid(atPos + 1);
146 bool asciiDomain =
true;
147 for (
const QChar &ch : domain) {
148 const ushort &uc = ch.
unicode();
149 if (uc > ValidatorEmailPrivate::asciiEnd) {
167 const qsizetype rawLength = email.
length();
169 for (
int i = 0; i < rawLength; i++) {
176 case ComponentLocalpart:
196 if (elementLen == 0) {
206 contextStack.push_back(context);
207 context = ContextComment;
209 if (elementLen == 0) {
211 returnStatus.push_back((elementCount == 0)
226 parseLocalPart += token;
227 atomListLocalPart[elementCount].
clear();
229 if (elementLen == 0) {
232 returnStatus.push_back((elementCount == 0)
236 parseLocalPart += token;
237 atomListLocalPart[elementCount] += token;
240 contextStack.push_back(context);
241 context = ContextQuotedString;
253 if (elementLen == 0) {
261 contextStack.push_back(context);
262 context = ContextFWS;
266 if (contextStack.size() != 1) {
268 qCCritical(C_VALIDATOR) <<
"ValidatorEmail: Unexpected item on context stack";
272 if (parseLocalPart.
isEmpty()) {
274 }
else if (elementLen == 0) {
276 }
else if (parseLocalPart.
size() > ValidatorEmailPrivate::maxLocalPartLength) {
281 }
else if ((contextPrior == ContextComment) || (contextPrior == ContextFWS)) {
295 context = ComponentDomain;
296 contextStack.clear();
297 contextStack.push_back(context);
316 switch (contextPrior) {
321 case ContextQuotedString:
326 qCCritical(C_VALIDATOR)
327 <<
"ValidatorEmail: More atext found where none is allowed, "
328 "but unrecognizes prior context";
332 contextPrior = context;
333 const char16_t uni = token.
unicode();
335 if (!allowUtf8Local) {
336 if ((uni < ValidatorEmailPrivate::asciiExclamationMark) ||
337 (uni > ValidatorEmailPrivate::asciiTilde) ||
338 ValidatorEmailPrivate::stringSpecials.contains(token)) {
339 returnStatus.push_back(
344 if ((uni < ValidatorEmailPrivate::asciiExclamationMark) ||
345 (uni > ValidatorEmailPrivate::asciiTilde) ||
346 ValidatorEmailPrivate::stringSpecials.contains(token)) {
347 returnStatus.push_back(
353 parseLocalPart += token;
354 atomListLocalPart[elementCount] += token;
362 case ComponentDomain:
403 if (elementLen == 0) {
407 returnStatus.push_back((elementCount == 0)
416 contextStack.push_back(context);
417 context = ContextComment;
419 if (elementLen == 0) {
421 returnStatus.push_back((elementCount == 0)
424 }
else if (hyphenFlag) {
440 if (elementLen > ValidatorEmailPrivate::maxDnsLabelLength) {
449 atomListDomain[elementCount].
clear();
450 parseDomain += token;
456 contextStack.push_back(context);
457 context = ComponentLiteral;
458 parseDomain += token;
459 atomListDomain[elementCount] += token;
460 parseLiteral.
clear();
472 if (elementLen == 0) {
473 returnStatus.push_back((elementCount == 0)
482 contextStack.push_back(context);
483 context = ContextFWS;
511 switch (contextPrior) {
516 case ComponentLiteral:
521 qCCritical(C_VALIDATOR)
522 <<
"ValidatorEmail: More atext found where none is allowed, but"
523 <<
"unrecognised prior context.";
528 const char16_t uni = token.
unicode();
531 if ((uni < ValidatorEmailPrivate::asciiExclamationMark) ||
532 (uni > ValidatorEmailPrivate::asciiTilde) ||
533 ValidatorEmailPrivate::stringSpecials.contains(token)) {
536 if (elementLen == 0) {
538 returnStatus.push_back(
542 }
else if (!(((uni >= ValidatorRulePrivate::ascii_0) &&
543 (uni <= ValidatorRulePrivate::ascii_9)) ||
544 ((uni >= ValidatorRulePrivate::ascii_A) &&
545 (uni <= ValidatorRulePrivate::ascii_Z)) ||
546 ((uni >= ValidatorRulePrivate::ascii_a) &&
547 (uni <= ValidatorRulePrivate::ascii_z)))) {
552 parseDomain += token;
553 atomListDomain[elementCount] += token;
560 case ComponentLiteral:
571 if (
static_cast<int>(
572 *std::max_element(returnStatus.constBegin(), returnStatus.constEnd())) <
628 qsizetype index = -1;
629 QString addressLiteral = parseLiteral;
632 ValidatorEmailPrivate::ipv4Regex.match(addressLiteral);
637 addressLiteral.
mid(0, index) +
647 addressLiteral.
left(5),
655 qsizetype groupCount = matchesIP.
size();
660 if (groupCount != maxGroups) {
667 if ((index == 0) || (index == (ipv6.
length() - 2))) {
671 if (groupCount > maxGroups) {
673 }
else if (groupCount == maxGroups) {
674 returnStatus.push_back(
683 returnStatus.push_back(
688 returnStatus.push_back(
692 int unmatchedChars = 0;
693 for (
const QString &ip : matchesIP) {
694 if (!ip.contains(ValidatorEmailPrivate::ipv6PartRegex)) {
698 if (unmatchedChars != 0) {
710 parseDomain += token;
711 atomListDomain[elementCount] += token;
713 contextPrior = context;
714 context = contextStack.takeLast();
717 contextStack.push_back(context);
718 context = ContextQuotedPair;
728 contextStack.push_back(context);
729 context = ContextFWS;
745 const char16_t uni = token.
unicode();
748 if ((uni > ValidatorEmailPrivate::asciiEnd) || (uni == 0) ||
752 }
else if ((uni < ValidatorEmailPrivate::asciiExclamationMark) ||
753 (uni == ValidatorEmailPrivate::asciiEnd)) {
757 parseLiteral += token;
758 parseDomain += token;
759 atomListDomain[elementCount] += token;
766 case ContextQuotedString:
775 contextStack.push_back(context);
776 context = ContextQuotedPair;
801 contextStack.push_back(context);
802 context = ContextFWS;
805 parseLocalPart += token;
806 atomListLocalPart[elementCount] += token;
808 contextPrior = context;
809 context = contextStack.takeLast();
824 const char16_t uni = token.
unicode();
826 if (!allowUtf8Local) {
827 if ((uni > ValidatorEmailPrivate::asciiEnd) || (uni == 0) ||
828 (uni == ValidatorEmailPrivate::asciiLF)) {
830 }
else if ((uni < ValidatorRulePrivate::asciiSpace) ||
831 (uni == ValidatorEmailPrivate::asciiEnd)) {
836 if ((uni > ValidatorEmailPrivate::asciiEnd) || (uni == 0) ||
837 (uni == ValidatorEmailPrivate::asciiLF)) {
838 returnStatus.push_back(
840 }
else if ((uni < ValidatorRulePrivate::asciiSpace) ||
841 (uni == ValidatorEmailPrivate::asciiEnd)) {
847 parseLocalPart += token;
848 atomListLocalPart[elementCount] += token;
863 case ContextQuotedPair:
881 const char16_t uni = token.
unicode();
883 if (uni > ValidatorEmailPrivate::asciiEnd) {
885 }
else if (((uni < ValidatorEmailPrivate::asciiUS) &&
886 (uni != ValidatorRulePrivate::asciiTab)) ||
887 (uni == ValidatorEmailPrivate::asciiEnd)) {
898 contextPrior = context;
899 context = contextStack.takeLast();
904 case ContextQuotedString:
906 parseLocalPart += token;
907 atomListLocalPart[elementCount] +=
QLatin1Char(
'\\');
908 atomListLocalPart[elementCount] += token;
912 case ComponentLiteral:
914 parseDomain += token;
916 atomListDomain[elementCount] += token;
922 qCCritical(C_VALIDATOR)
923 <<
"ValidatorEmail: Quoted pair logic invoked in an invalid context.";
938 contextStack.push_back(context);
939 context = ContextComment;
941 contextPrior = context;
942 context = contextStack.takeLast();
961 contextStack.push_back(context);
962 context = ContextQuotedPair;
972 contextStack.push_back(context);
973 context = ContextFWS;
990 const ushort uni = token.
unicode();
992 if ((uni > ValidatorEmailPrivate::asciiEnd) || (uni == 0) ||
993 (uni == ValidatorEmailPrivate::asciiLF)) {
996 }
else if ((uni < ValidatorRulePrivate::asciiSpace) ||
997 (uni == ValidatorEmailPrivate::asciiEnd)) {
1025 if (crlf_count > 0) {
1026 if (++crlf_count > 1) {
1027 returnStatus.push_back(
1046 crlf_count = std::min(crlf_count, 0);
1048 contextPrior = context;
1049 context = contextStack.takeLast();
1075 qCCritical(C_VALIDATOR) <<
"ValidatorEmail: Unknown context";
1079 if (
static_cast<int>(
1080 *std::max_element(returnStatus.constBegin(), returnStatus.constEnd())) >
1087 if (
static_cast<int>(*std::max_element(returnStatus.constBegin(), returnStatus.constEnd())) <
1089 if (context == ContextQuotedString) {
1091 }
else if (context == ContextQuotedPair) {
1093 }
else if (context == ContextComment) {
1095 }
else if (context == ComponentLiteral) {
1099 }
else if (parseDomain.
isEmpty()) {
1101 }
else if (elementLen == 0) {
1103 }
else if (hyphenFlag) {
1105 }
else if (parseDomain.
size() > ValidatorEmailPrivate::maxDomainLength) {
1109 }
else if ((parseLocalPart.
size() + 1 + parseDomain.
size()) >
1110 ValidatorEmailPrivate::maxMailboxLength) {
1130 }
else if (elementLen > ValidatorEmailPrivate::maxDnsLabelLength) {
1136 bool dnsChecked =
false;
1220 (
static_cast<int>(*std::max_element(returnStatus.constBegin(), returnStatus.constEnd())) <
1222 if (elementCount == 0) {
1226 if (QStringLiteral(
"0123456789").contains(atomListDomain[elementCount][0])) {
1231 if (returnStatus.size() != 1) {
1240 std::ranges::sort(returnStatus, std::greater<>());
1245 if (diagnoseStruct) {
1246 diagnoseStruct->finalStatus = finalStatus;
1247 diagnoseStruct->returnStatus = returnStatus;
1248 diagnoseStruct->localpart = parseLocalPart;
1249 diagnoseStruct->domain = parseDomain;
1250 diagnoseStruct->literal = parseLiteral;
1251 if (!parseLiteral.
isEmpty()) {
1252 diagnoseStruct->cleanedEmail = parseLocalPart +
QLatin1Char(
'@') + parseLiteral;
1254 diagnoseStruct->cleanedEmail = parseLocalPart +
QLatin1Char(
'@') + parseDomain;
1258 return static_cast<int>(finalStatus) <
static_cast<int>(threshold);
1269 return c->
qtTrId(
"cutelyst-valemail-diag-valid");
1272 return c->
qtTrId(
"cutelyst-valemail-diag-nomx");
1275 return c->
qtTrId(
"cutelyst-valemail-diag-mxdisabled");
1278 return c->
qtTrId(
"cutelyst-valemail-diag-noarec");
1281 return c->
qtTrId(
"cutelyst-valemail-diag-dnstimeout");
1284 return c->
qtTrId(
"cutelyst-valemail-diag-dnserror");
1287 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321tld");
1290 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321tldnumeric");
1293 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321quotedstring");
1296 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321addressliteral");
1301 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321ipv6deprecated");
1304 return c->
qtTrId(
"cutelyst-valemail-diag-cfwscomment");
1307 return c->
qtTrId(
"cutelyst-valemail-diag-cfwsfws");
1310 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedlocalpart");
1313 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedfws");
1316 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedqtext");
1319 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedqp");
1322 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedcomment");
1325 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedctext");
1328 return c->
qtTrId(
"cutelyst-valemail-diag-cfwsnearat");
1332 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domain");
1335 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322toolong")
1340 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322localtoolong")
1344 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domaintoolong")
1349 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322labeltoolong")
1353 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domainliteral");
1357 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domlitobsdtext");
1360 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6groupcount");
1363 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv62x2xcolon");
1366 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6badchar");
1369 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6maxgroups");
1372 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6colonstart");
1375 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6colonend");
1378 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingdtext");
1381 return c->
qtTrId(
"cutelyst-valemail-diag-errnolocalpart");
1384 return c->
qtTrId(
"cutelyst-valemail-diag-errnodomain");
1387 return c->
qtTrId(
"cutelyst-valemail-diag-errconsecutivedots");
1390 return c->
qtTrId(
"cutelyst-valemail-diag-erratextaftercfws");
1393 return c->
qtTrId(
"cutelyst-valemail-diag-erratextafterqs");
1396 return c->
qtTrId(
"cutelyst-valemail-diag-erratextafterdomlit");
1399 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingqpair");
1402 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingatext");
1405 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingqtext");
1408 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingctext");
1411 return c->
qtTrId(
"cutelyst-valemail-diag-errbackslashend");
1414 return c->
qtTrId(
"cutelyst-valemail-diag-errdotstart");
1417 return c->
qtTrId(
"cutelyst-valemail-diag-errdotend");
1420 return c->
qtTrId(
"cutelyst-valemail-diag-errdomainhyphenstart");
1423 return c->
qtTrId(
"cutelyst-valemail-diag-errdomainhyphenend");
1426 return c->
qtTrId(
"cutelyst-valemail-diag-errunclosedquotedstr");
1429 return c->
qtTrId(
"cutelyst-valemail-diag-errunclosedcomment");
1432 return c->
qtTrId(
"cutelyst-valemail-diag-erruncloseddomliteral");
1435 return c->
qtTrId(
"cutelyst-valemail-diag-errfwscrlfx2");
1438 return c->
qtTrId(
"cutelyst-valemail-diag-errfwscrlfend");
1442 return c->
qtTrId(
"cutelyst-valemail-diag-errcrnolf");
1445 return c->
qtTrId(
"cutelyst-valemail-diag-errfatal");
1457 return c->
qtTrId(
"cutelyst-valemail-diag-valid-label").
arg(
label);
1461 return c->
qtTrId(
"cutelyst-valemail-diag-nomx-label").
arg(
label);
1464 return c->
qtTrId(
"cutelyst-valemail-diag-mxdisabled-label").
arg(
label);
1468 return c->
qtTrId(
"cutelyst-valemail-diag-noarec-label").
arg(
label);
1471 return c->
qtTrId(
"cutelyst-valemail-diag-dnstimeout-label").
arg(
label);
1474 return c->
qtTrId(
"cutelyst-valemail-diag-dnserror-label").
arg(
label);
1477 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321tld-label").
arg(
label);
1481 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321tldnumeric-label").
arg(
label);
1484 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321quotedstring-label").
arg(
label);
1488 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321addressliteral-label").
arg(
label);
1493 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5321ipv6deprecated-label").
arg(
label);
1496 return c->
qtTrId(
"cutelyst-valemail-diag-cfwscomment-label").
arg(
label);
1500 return c->
qtTrId(
"cutelyst-valemail-diag-cfwsfws-label").
arg(
label);
1503 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedlocalpart-label").
arg(
label);
1507 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedfws-label").
arg(
label);
1511 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedqtext-label").
arg(
label);
1515 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedqp-label").
arg(
label);
1519 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedcomment-label").
arg(
label);
1522 return c->
qtTrId(
"cutelyst-valemail-diag-deprecatedctext-label").
arg(
label);
1526 return c->
qtTrId(
"cutelyst-valemail-diag-cfwsnearat-label").
arg(
label);
1530 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domain-label").
arg(
label);
1534 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322toolong-label")
1539 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322localtoolong-label")
1544 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domaintoolong-label")
1549 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322labeltoolong-label")
1554 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domainliteral-label").
arg(
label);
1558 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322domlitobsdtext-label").
arg(
label);
1562 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6groupcount-label").
arg(
label);
1566 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv62x2xcolon-label").
arg(
label);
1570 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6badchar-label").
arg(
label);
1573 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6maxgroups-label").
arg(
label);
1577 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6colonstart-label").
arg(
label);
1581 return c->
qtTrId(
"cutelyst-valemail-diag-rfc5322ipv6colonend-label").
arg(
label);
1585 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingdtext-label").
arg(
label);
1588 return c->
qtTrId(
"cutelyst-valemail-diag-errnolocalpart-label").
arg(
label);
1591 return c->
qtTrId(
"cutelyst-valemail-diag-errnodomain-label").
arg(
label);
1594 return c->
qtTrId(
"cutelyst-valemail-diag-errconsecutivedots-label").
arg(
label);
1598 return c->
qtTrId(
"cutelyst-valemail-diag-erratextaftercfws-label").
arg(
label);
1601 return c->
qtTrId(
"cutelyst-valemail-diag-erratextafterqs-label").
arg(
label);
1605 return c->
qtTrId(
"cutelyst-valemail-diag-erratextafterdomlit-label").
arg(
label);
1609 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingqpair-label").
arg(
label);
1612 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingatext-label").
arg(
label);
1616 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingqtext-label").
arg(
label);
1620 return c->
qtTrId(
"cutelyst-valemail-diag-errexpectingctext-label").
arg(
label);
1623 return c->
qtTrId(
"cutelyst-valemail-diag-errbackslashend-label").
arg(
label);
1626 return c->
qtTrId(
"cutelyst-valemail-diag-errdotstart-label").
arg(
label);
1629 return c->
qtTrId(
"cutelyst-valemail-diag-errdotend-label").
arg(
label);
1633 return c->
qtTrId(
"cutelyst-valemail-diag-errdomainhyphenstart-label").
arg(
label);
1637 return c->
qtTrId(
"cutelyst-valemail-diag-errdomainhyphenend-label").
arg(
label);
1641 return c->
qtTrId(
"cutelyst-valemail-diag-errunclosedquotedstr-label").
arg(
label);
1645 return c->
qtTrId(
"cutelyst-valemail-diag-errunclosedcomment-label").
arg(
label);
1649 return c->
qtTrId(
"cutelyst-valemail-diag-erruncloseddomliteral-label").
arg(
label);
1653 return c->
qtTrId(
"cutelyst-valemail-diag-errfwscrlfx2-label").
arg(
label);
1657 return c->
qtTrId(
"cutelyst-valemail-diag-errfwscrlfend-label").
arg(
label);
1661 return c->
qtTrId(
"cutelyst-valemail-diag-errcrnolf-label").
arg(
label);
1664 return c->
qtTrId(
"cutelyst-valemail-diag-errfatal-label").
arg(
label);
1677 return c->
qtTrId(
"cutelyst-valemail-cat-valid");
1680 return c->
qtTrId(
"cutelyst-valemail-cat-dnswarn");
1683 return c->
qtTrId(
"cutelyst-valemail-cat-dnsfailed");
1686 return c->
qtTrId(
"cutelyst-valemail-cat-rfc5321");
1690 return c->
qtTrId(
"cutelyst-valemail-cat-cfws");
1694 return c->
qtTrId(
"cutelyst-valemail-cat-deprecated");
1698 return c->
qtTrId(
"cutelyst-valemail-cat-rfc5322");
1701 return c->
qtTrId(
"cutelyst-valemail-cat-invalid");
1707 return c->
qtTrId(
"cutelyst-valemail-cat-valid-label").
arg(
label);
1710 return c->
qtTrId(
"cutelyst-valemail-cat-dnswarn-label").
arg(
label);
1713 return c->
qtTrId(
"cutelyst-valemail-cat-dnsfailed-label").
arg(
label);
1716 return c->
qtTrId(
"cutelyst-valemail-cat-rfc5321-label").
arg(
label);
1724 return c->
qtTrId(
"cutelyst-valemail-cat-deprecated-label").
arg(
label);
1728 return c->
qtTrId(
"cutelyst-valemail-cat-rfc5322-label").
arg(
label);
1731 return c->
qtTrId(
"cutelyst-valemail-cat-invalid-label").
arg(
label);
1740 const auto diag =
static_cast<int>(diagnose);
1742 if (diag <
static_cast<int>(
Valid)) {
1744 }
else if (diag <
static_cast<int>(
DNSWarn)) {
1746 }
else if (diag <
static_cast<int>(
DNSFailed)) {
1748 }
else if (diag <
static_cast<int>(
RFC5321)) {
1750 }
else if (diag <
static_cast<int>(
CFWS)) {
1752 }
else if (diag <
static_cast<int>(
Deprecated)) {
1754 }
else if (diag <
static_cast<int>(
RFC5322)) {
1772 qCWarning(C_VALIDATOR) <<
"ValidatorEmail: using the CheckDNS option on validate() is"
1773 <<
"not supported anymore. Use validateCb().";
1776 ValidatorEmailDiagnoseStruct diag;
1777 bool ret = ValidatorEmailPrivate::checkEmail(email, options, threshold, &diag);
1780 *diagnoses = diag.returnStatus;
1793 ValidatorEmailDiagnoseStruct diag;
1794 const bool ret = ValidatorEmailPrivate::checkEmail(email, options, threshold, &diag);
1798 if (diag.domain.isEmpty()) {
1800 diag.returnStatus.append(
DnsError);
1801 diag.sortReturnStatus();
1802 cb(diag.isBelowThreshold(threshold), diag.cleanedEmail, diag.returnStatus);
1810 !mxLookup->mailExchangeRecords().empty()) {
1811 const auto records = mxLookup->mailExchangeRecords();
1812 for (const auto &h : records) {
1813 if (h.preference() > 0 && !h.exchange().isEmpty()) {
1816 diag.returnStatus.removeAll(RFC5321TLD);
1817 diag.returnStatus.removeAll(RFC5321TLDNumeric);
1819 } else if (h.preference() == 0 &&
1820 (h.exchange().isEmpty() || h.exchange() ==
"."_L1)) {
1823 diag.returnStatus.append(DnsMxDisabled);
1827 diag.sortReturnStatus();
1828 cb(diag.isBelowThreshold(threshold), diag.cleanedEmail, diag.returnStatus);
1835 [aLookup, cb, diag, threshold]()
mutable {
1837 if (!aLookup->hostAddressRecords().empty()) {
1838 diag.returnStatus.append(DnsWarnNoMxRecord);
1840 diag.returnStatus.append(DnsNoRecordFound);
1842 diag.sortReturnStatus();
1843 cb(diag.isBelowThreshold(threshold),
1847 switch (aLookup->error()) {
1855 diag.returnStatus.append(
DnsError);
1858 diag.sortReturnStatus();
1859 cb(diag.isBelowThreshold(threshold),
1863 aLookup->deleteLater();
1870 switch (mxLookup->error()) {
1878 diag.returnStatus.append(
DnsError);
1881 diag.sortReturnStatus();
1882 cb(diag.isBelowThreshold(threshold), diag.cleanedEmail, diag.returnStatus);
1885 mxLookup->deleteLater();
1893 cb(ret, diag.cleanedEmail, diag.returnStatus);
1897void ValidatorEmailDiagnoseStruct::sortReturnStatus()
1899 std::ranges::sort(returnStatus, std::greater<>());
1900 finalStatus = returnStatus.at(0);
1905 return static_cast<int>(finalStatus) <
static_cast<int>(threshold);
1908#include "moc_validatoremail.cpp"
QLocale locale() const noexcept
QString qtTrId(const char *id, int n=-1) const
Checks if the value is a valid email address according to specific RFCs.
static Category category(Diagnose diagnose)
Category
Validation category, used as threshold to define valid addresses.
ValidatorEmail(const QString &field, Category threshold=RFC5321, Options options=NoOption, const ValidatorMessages &messages={}, const QString &defValKey={})
~ValidatorEmail() override
Diagnose
Single diagnose values that show why an address is not valid.
@ ErrorUnclosedDomLiteral
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
static QString categoryString(Context *c, Category category, const QString &label={})
static QString diagnoseString(Context *c, Diagnose diagnose, const QString &label={})
Base class for all validator rules.
QString validationError(Context *c, const QVariant &errorData={}) const
QString label(const Context *c) const
std::function< void(ValidatorReturnType &&result)> ValidatorRtFn
Void callback function for validator rules that processes the ValidatorReturnType.
void defaultValue(Context *c, ValidatorReturnType *result) const
QString value(const ParamsMultiMap ¶ms) const
static void validateCb(const QString &email, Category threshold, Options options, std::function< void(bool isValid, const QString &cleanedEmail, const QList< Diagnose > &diagnoses)> cb)
Checks if the email is a valid address according to the Category given in the threshold.
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.
bool isLetterOrNumber(char32_t ucs4)
void append(QList::parameter_type value)
bool contains(const AT &value) const const
qsizetype size() const const
QString toString(QDate date, QLocale::FormatType format) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString captured(QStringView name) const const
bool hasMatch() const const
QString arg(Args &&... args) const const
const QChar at(qsizetype position) const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
QString fromLatin1(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs) const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString right(qsizetype n) const const
qsizetype size() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
const QChar * unicode() const const
QByteArray toAce(const QString &domain, QUrl::AceProcessingOptions options)
void setValue(QVariant &&value)
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.