7#include <QtCore/qstringlist.h>
8#include <QtCore/private/qnumeric_p.h>
9#include <QtCore/private/qoffsetstringarray_p.h>
10#include <QtCore/private/qstringiterator_p.h>
11#include <QtCore/private/qunicodetables_p.h>
32 return digit + 22 + 75 * (digit < 26);
37 delta /= (firsttime ?
damp : 2);
38 delta += (delta / numpoints);
44 return k + (((
base -
tmin + 1) * delta) / (delta +
skew));
54 for (qq = delta, k =
base;; k +=
base) {
61 qq = (qq -
t) / (
base -
t);
79 int outLen =
output->size();
86 if (
c.unicode() < 0x80)
98 int copied =
output->size() - outLen;
109 uint inputLength = 0;
113 if (
iter.next(
char32_t(-1)) == char32_t(-1)) {
121 while (
h < inputLength) {
123 uint m = std::numeric_limits<uint>::max();
125 auto c =
iter.nextUnchecked();
126 static_assert(std::numeric_limits<
decltype(
m)>::max()
127 >= std::numeric_limits<
decltype(
c)>::max(),
128 "Punycode uint should be able to cover all codepoints");
135 if (qMulOverflow<uint>(
m -
n,
h + 1, &tmp) || qAddOverflow<uint>(delta, tmp, &delta)) {
142 auto c =
iter.nextUnchecked();
147 if (qAddOverflow<uint>(delta, 1, &delta)) {
167 output->insert(outLen,
"xn--"_L1);
191 auto output = delimiterPos < 4 ? std::u32string()
197 uint cnt = delimiterPos + 1;
211 if (digit - 48 < 10) digit -= 22;
212 else if (digit - 65 < 26) digit -= 65;
213 else if (digit - 97 < 26) digit -= 97;
222 if (qMulOverflow<uint>(digit,
w, &tmp) || qAddOverflow<uint>(
i, tmp, &
i))
231 if (digit <
t)
break;
234 if (qMulOverflow<uint>(
w,
base -
t, &
w))
241 bias =
adapt(
i - oldi, outputLength + 1, oldi == 0);
244 if (qAddOverflow<uint>(
n,
i / (outputLength + 1), &
n))
248 i %= (outputLength + 1);
254 qWarning(
"Attempt to insert a basic codepoint. Unhandled overflow?");
273 output.insert(
i, 1,
static_cast<char32_t>(
n));
281 "ac",
"ar",
"asia",
"at",
283 "cat",
"ch",
"cl",
"cn",
"com",
289 "il",
"info",
"io",
"is",
"ir",
292 "li",
"lt",
"lu",
"lv",
294 "name",
"net",
"no",
"nu",
"nz",
298 "tel",
"th",
"tm",
"tw",
323 const auto *uc =
reinterpret_cast<const char16_t *
>(
a);
324 const char16_t *
e = uc + l;
330 if (uc ==
e || *uc !=
static_cast<unsigned char>(*
c))
335 return uc ==
e ? *
c : (*uc < static_cast<unsigned char>(*
c));
340 while (l &&
a->unicode() && *
b) {
356 auto tldString = aceDomain.
mid(idx + 1);
357 const auto len = tldString.
size();
359 const QChar *tld = tldString.constData();
366 int i = (l +
r + 1) / 2;
381 return c == u
'-' ||
c == u
'_' || (
c >= u
'0' &&
c <= u
'9') || (
c >= u
'a' &&
c <= u
'z');
400 *resultIsAscii =
true;
416 bool allAscii =
true;
419 char32_t uc =
iter.next();
423 if (uc >= U
'A' && uc <= U
'Z')
429 result.append(
static_cast<char16_t>(uc));
458 *resultIsAscii = allAscii;
474 if (
label.first() == u
'-' ||
label.last() == u
'-')
477 return std::all_of(
label.begin(),
label.end(), isValidInNormalizedAsciiLabel<QChar>);
482class DomainValidityChecker
484 bool domainNameIsBidi =
false;
485 bool hadBidiErrors =
false;
487 static constexpr char32_t ZWNJ = U
'\u200C';
488 static constexpr char32_t ZWJ = U
'\u200D';
491 DomainValidityChecker() { }
492 bool checkLabel(
const QString &
label, QUrl::AceProcessingOptions options);
523 constexpr unsigned char CombiningClassVirama = 9;
530 State regexpState = State::Initial;
531 bool previousIsVirama =
false;
537 if (!previousIsVirama)
539 regexpState = State::Initial;
540 }
else if (
ch == ZWNJ) {
541 if (!previousIsVirama && regexpState != State::LD_T)
543 regexpState = previousIsVirama ? State::Initial : State::ZWNJ_T;
547 if (regexpState == State::ZWNJ_T)
549 regexpState = State::LD_T;
552 regexpState = State::Initial;
555 regexpState = State::LD_T;
560 regexpState = State::Initial;
568 return regexpState != State::ZWNJ_T;
603 char32_t ch =
iter.next();
604 bool labelIsRTL =
false;
618 bool labelHasEN =
false;
619 bool labelHasAN =
false;
621 while (
iter.hasNext()) {
704bool DomainValidityChecker::checkLabel(
const QString &
label, QUrl::AceProcessingOptions options)
712 if (
label.size() >= 4) {
720 if (
label.startsWith(u
'-') ||
label.endsWith(u
'-'))
723 if (
label.contains(u
'.'))
727 auto c =
iter.next();
734 bool hasJoiners =
false;
737 hasJoiners = hasJoiners ||
c == ZWNJ ||
c == ZWJ;
739 if (!domainNameIsBidi) {
744 domainNameIsBidi =
true;
769 if (hasJoiners && !checkContextJRules(
label))
772 hadBidiErrors = hadBidiErrors || !checkBidiRules(
label);
774 if (domainNameIsBidi && hadBidiErrors)
787 auto idx = normalizedDomain.
indexOf(u
'.', lastIdx);
789 idx = normalizedDomain.
size();
791 const auto labelLength = idx - lastIdx;
792 if (labelLength == 0) {
793 if (idx == normalizedDomain.
size())
804 aceResult.
append(aceForm);
807 if (idx == normalizedDomain.
size())
821 bool hasPunycode =
false;
822 *usesPunycode =
false;
824 while (lastIdx < normalizedDomain.
size()) {
825 auto idx = normalizedDomain.
indexOf(u
'.', lastIdx);
827 idx = normalizedDomain.
size();
829 const auto labelLength = idx - lastIdx;
830 if (labelLength == 0) {
831 if (idx == normalizedDomain.
size())
846 *usesPunycode = hasPunycode;
856 DomainValidityChecker checker;
859 auto idx = asciiDomain.
indexOf(u
'.', lastIdx);
861 idx = asciiDomain.
size();
863 const auto labelLength = idx - lastIdx;
864 if (labelLength == 0) {
865 if (idx == asciiDomain.
size())
868 const auto label = asciiDomain.
sliced(lastIdx, labelLength);
871 if (unicodeLabel.isEmpty())
874 if (!checker.checkLabel(unicodeLabel, options))
880 if (idx == asciiDomain.
size())
890 QUrl::AceProcessingOptions options)
903 bool needsCoversionToUnicode;
908 if (op ==
ToAceOnly || !needsCoversionToUnicode
Direction direction() const noexcept
Returns the character's direction.
static constexpr auto fromUcs4(char32_t c) noexcept
constexpr bool isSurrogate() const noexcept
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
unsigned char combiningClass() const noexcept
Returns the combining class for the character as defined in the Unicode standard.
JoiningType joiningType() const noexcept
bool isMark() const noexcept
Returns true if the character is a mark (Mark_* categories); otherwise returns false.
void reserve(qsizetype size)
bool startsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr qsizetype size() const noexcept
Returns the size of this string view, in UTF-16 code units (that is, surrogate pairs count as two for...
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
constexpr QStringView sliced(qsizetype pos) const noexcept
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
std::u32string toStdU32String() const
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
void clear()
Clears the contents of the string and makes it null.
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString fromStdU32String(const std::u32string &s)
QString sliced(qsizetype pos) const
QString & append(QChar c)
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
@ AceTransitionalProcessing
static QStringList idnWhitelist()
static void setIdnWhitelist(const QStringList &)
Combined button and popup list for selecting options.
Q_CORE_EXPORT IdnaStatus QT_FASTCALL idnaStatus(char32_t ucs4) noexcept
Q_CORE_EXPORT QStringView QT_FASTCALL idnaMapping(char32_t ucs4) noexcept
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
constexpr auto qOffsetStringArray(const char(&...strings)[Nx]) noexcept
GLboolean GLboolean GLboolean b
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLsizei const GLchar * label
[43]
GLfloat GLfloat GLfloat GLfloat h
GLint GLenum GLboolean normalized
static qreal dot(const QPointF &a, const QPointF &b)
#define Q_AUTOTEST_EXPORT
static bool checkAsciiDomainName(const QString &normalizedDomain, AceLeadingDot dot, bool *usesPunycode)
static const uint initial_bias
QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot, QUrl::AceProcessingOptions options)
static bool isValidInNormalizedAsciiName(C c)
static bool qt_is_idn_enabled(QStringView aceDomain)
static constexpr auto idn_whitelist
static constexpr qsizetype MaxDomainLabelLength
static bool validateAsciiLabel(QStringView label)
static bool isValidInNormalizedAsciiLabel(C c)
static void appendEncode(QString *output, uint delta, uint bias)
static Q_CONSTINIT QStringList * user_idn_whitelist
static bool lessThan(const QChar *a, int l, const char *c)
static QString mapDomainName(const QString &in, QUrl::AceProcessingOptions options, bool *resultIsAscii)
static QString convertToUnicode(const QString &asciiDomain, QUrl::AceProcessingOptions options)
static QString convertToAscii(const QString &normalizedDomain, AceLeadingDot dot)
Q_AUTOTEST_EXPORT QString qt_punycodeDecoder(const QString &pc)
static const uint initial_n
Q_AUTOTEST_EXPORT void qt_punycodeEncoder(QStringView in, QString *output)
static bool equal(const QChar *a, int l, const char *b)
static uint encodeDigit(uint digit)
static uint adapt(uint delta, uint numpoints, bool firsttime)
QT_BEGIN_NAMESPACE typedef uchar * output
\inmodule QtCore \reentrant