QUrlIdna: port containsProhibitedOutput() to QStringIterator

Also Extract Method isProhibitedOutput(), which, in order to preserve
history, is placed in the unnamed namespace and violates the
indentation rules. But this code is delicate enough to be left
undisturbed. At least for now.

By said Extract Method, we can static_assert on the invalidity of the
QStringIterator::next() argument, which we assume will be rejected, so
that we continue to reject malformed surrogate pairs.

Also fix a comment that suggested the function would actively remove
("strip") malformed content, when in fact it only detects it.

Change-Id: I4185cbac71fb147e2f2036dbaf052af20bd1003f
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2020-05-12 10:46:21 +02:00
parent c59665b0ec
commit f437c8c5f9

View File

@ -41,6 +41,8 @@
#include "qurl_p.h"
#include <QtCore/qstringlist.h>
#include <QtCore/private/qstringiterator_p.h>
#include <algorithm>
QT_BEGIN_NAMESPACE
@ -1499,23 +1501,9 @@ static bool isMappedToNothing(uint uc)
}
}
static bool containsProhibitedOuptut(const QString *str, int from)
{
const ushort *in = reinterpret_cast<const ushort *>(str->begin() + from);
const ushort *end = (const ushort *)str->data() + str->size();
for ( ; in < end; ++in) {
uint uc = *in;
if (QChar(uc).isHighSurrogate() && in < end - 1) {
ushort low = *(in + 1);
if (QChar(low).isLowSurrogate()) {
++in;
uc = QChar::surrogateToUcs4(uc, low);
} else {
// unpaired surrogates are prohibited
return true;
}
}
namespace {
static constexpr bool isProhibitedOutputChar(char32_t uc)
{
if (uc <= 0xFFFF) {
if (uc < 0x80 ||
!(uc <= 0x009F
@ -1538,7 +1526,7 @@ static bool containsProhibitedOuptut(const QString *str, int from)
|| (uc >= 0xFDD0 && uc <= 0xFDEF)
|| uc == 0xFEFF
|| (uc >= 0xFFF9 && uc <= 0xFFFF))) {
continue;
return false;
}
} else {
if (!((uc >= 0x1D173 && uc <= 0x1D17A)
@ -1562,11 +1550,24 @@ static bool containsProhibitedOuptut(const QString *str, int from)
|| (uc >= 0xFFFFE && uc <= 0xFFFFF)
|| (uc >= 0x100000 && uc <= 0x10FFFD)
|| (uc >= 0x10FFFE && uc <= 0x10FFFF))) {
continue;
return false;
}
}
return true;
}
} // unnamed namespace
static bool containsProhibitedOuptut(QStringView str, qsizetype from)
{
constexpr char32_t invalid = 0xDEAD;
static_assert(isProhibitedOutputChar(invalid));
QStringIterator it{str, from};
while (it.hasNext()) {
if (isProhibitedOutputChar(it.next(invalid)))
return true;
}
return false;
}
@ -2081,8 +2082,8 @@ Q_AUTOTEST_EXPORT bool qt_nameprep(QString *source, int from)
qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2,
firstNonAscii > from ? firstNonAscii - 1 : from);
// Strip prohibited output
if (containsProhibitedOuptut(source, firstNonAscii)) {
// Check for prohibited output
if (containsProhibitedOuptut(*source, firstNonAscii)) {
source->resize(from);
return false;
}