Make sure that the parsing mode reaches QUrlPrivate::setHost
Ensure that the parsing mode is cascaded down from setAuthority and setUrl so that the hostname parsing does not attempt to decode percent-encoded hostnames when it shouldn't. Take the opportunity to also remove the "Boolean Trap" from QUrlPrivate::setHost. Change-Id: Ia64754c4a4900182700b7af1382aea8410abc7e9 Reviewed-by: Lars Knoll <lars.knoll@nokia.com>bb10
parent
e1038794b1
commit
0838ac541d
|
|
@ -708,7 +708,7 @@ bool QUrlPrivate::setScheme(const QString &value, int len)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QUrlPrivate::setAuthority(const QString &auth, int from, int end)
|
||||
bool QUrlPrivate::setAuthority(const QString &auth, int from, int end, QUrl::ParsingMode mode)
|
||||
{
|
||||
sectionHasError &= ~Authority;
|
||||
sectionIsPresent &= ~Authority;
|
||||
|
|
@ -768,7 +768,7 @@ bool QUrlPrivate::setAuthority(const QString &auth, int from, int end)
|
|||
port = -1;
|
||||
}
|
||||
|
||||
return setHost(auth, from, qMin<uint>(end, colonIndex)) && !(sectionHasError & Port);
|
||||
return setHost(auth, from, qMin<uint>(end, colonIndex), mode) && !(sectionHasError & Port);
|
||||
}
|
||||
|
||||
void QUrlPrivate::setUserInfo(const QString &userInfo, int from, int end)
|
||||
|
|
@ -955,7 +955,7 @@ static bool parseIp6(QString &host, const QChar *begin, const QChar *end)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QUrlPrivate::setHost(const QString &value, int from, int iend, bool maybePercentEncoded)
|
||||
bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl::ParsingMode mode)
|
||||
{
|
||||
const QChar *begin = value.constData() + from;
|
||||
const QChar *end = value.constData() + iend;
|
||||
|
|
@ -1020,7 +1020,7 @@ bool QUrlPrivate::setHost(const QString &value, int from, int iend, bool maybePe
|
|||
|
||||
// check for percent-encoding first
|
||||
QString s;
|
||||
if (maybePercentEncoded && qt_urlRecode(s, begin, end, QUrl::DecodeReserved, 0)) {
|
||||
if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, QUrl::DecodeReserved, 0)) {
|
||||
// something was decoded
|
||||
// anything encoded left?
|
||||
if (s.contains(QChar(0x25))) { // '%'
|
||||
|
|
@ -1030,7 +1030,7 @@ bool QUrlPrivate::setHost(const QString &value, int from, int iend, bool maybePe
|
|||
}
|
||||
|
||||
// recurse
|
||||
return setHost(s, 0, s.length(), false);
|
||||
return setHost(s, 0, s.length(), QUrl::StrictMode);
|
||||
}
|
||||
|
||||
s = qt_ACE_do(QString::fromRawData(begin, len), NormalizeAce);
|
||||
|
|
@ -1111,7 +1111,7 @@ void QUrlPrivate::parse(const QString &url, QUrl::ParsingMode parsingMode)
|
|||
}
|
||||
}
|
||||
|
||||
setAuthority(url, hierStart + 2, authorityEnd);
|
||||
setAuthority(url, hierStart + 2, authorityEnd, parsingMode);
|
||||
|
||||
// even if we failed to set the authority properly, let's try to recover
|
||||
pathStart = authorityEnd;
|
||||
|
|
@ -1649,7 +1649,7 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
|
|||
mode = TolerantMode;
|
||||
}
|
||||
|
||||
d->setAuthority(data, 0, data.length());
|
||||
d->setAuthority(data, 0, data.length(), mode);
|
||||
if (authority.isNull()) {
|
||||
// QUrlPrivate::setAuthority cleared almost everything
|
||||
// but it leaves the Host bit set
|
||||
|
|
@ -1893,7 +1893,7 @@ void QUrl::setHost(const QString &host, ParsingMode mode)
|
|||
mode = TolerantMode;
|
||||
}
|
||||
|
||||
if (d->setHost(data, 0, data.length())) {
|
||||
if (d->setHost(data, 0, data.length(), mode)) {
|
||||
if (host.isNull())
|
||||
d->sectionIsPresent &= ~QUrlPrivate::Host;
|
||||
} else if (!data.startsWith(QLatin1Char('['))) {
|
||||
|
|
@ -1902,7 +1902,7 @@ void QUrl::setHost(const QString &host, ParsingMode mode)
|
|||
ushort oldSupplement = d->errorSupplement;
|
||||
data.prepend(QLatin1Char('['));
|
||||
data.append(QLatin1Char(']'));
|
||||
if (!d->setHost(data, 0, data.length())) {
|
||||
if (!d->setHost(data, 0, data.length(), mode)) {
|
||||
// failed again: choose if this was an IPv6 error or not
|
||||
if (!data.contains(QLatin1Char(':'))) {
|
||||
d->errorCode = oldCode;
|
||||
|
|
|
|||
|
|
@ -123,11 +123,11 @@ public:
|
|||
|
||||
// the "end" parameters are like STL iterators: they point to one past the last valid element
|
||||
bool setScheme(const QString &value, int len);
|
||||
bool setAuthority(const QString &auth, int from, int end);
|
||||
bool setAuthority(const QString &auth, int from, int end, QUrl::ParsingMode mode);
|
||||
void setUserInfo(const QString &userInfo, int from, int end);
|
||||
void setUserName(const QString &value, int from, int end);
|
||||
void setPassword(const QString &value, int from, int end);
|
||||
bool setHost(const QString &value, int from, int end, bool maybePercentEncoded = true);
|
||||
bool setHost(const QString &value, int from, int end, QUrl::ParsingMode mode);
|
||||
void setPath(const QString &value, int from, int end);
|
||||
void setQuery(const QString &value, int from, int end);
|
||||
void setFragment(const QString &value, int from, int end);
|
||||
|
|
|
|||
|
|
@ -1842,6 +1842,7 @@ void tst_QUrl::strictParser_data()
|
|||
QTest::newRow("invalid-password") << "http://user:pass\x7F@ok-hostname" << "Invalid password";
|
||||
|
||||
QTest::newRow("invalid-regname") << "http://bad<hostname>" << "Hostname contains invalid characters";
|
||||
QTest::newRow("invalid-regname-2") << "http://b%61d" << "Hostname contains invalid characters";
|
||||
QTest::newRow("invalid-ipv6") << "http://[:::]" << "Invalid IPv6 address";
|
||||
QTest::newRow("invalid-ipvfuture-1") << "http://[v7]" << "Invalid IPvFuture address";
|
||||
QTest::newRow("invalid-ipvfuture-2") << "http://[v7.]" << "Invalid IPvFuture address";
|
||||
|
|
@ -2007,6 +2008,13 @@ void tst_QUrl::tolerantParser()
|
|||
QVERIFY(url.isValid());
|
||||
QCOMPARE(QString(url.toEncoded()), QString("http://strange%3Cusername%3E@hostname/"));
|
||||
}
|
||||
|
||||
{
|
||||
QUrl url;
|
||||
url.setUrl("http://en%63o%64%65%64.hostname/", QUrl::TolerantMode);
|
||||
QVERIFY(url.isValid());
|
||||
QCOMPARE(url.toString(), QString("http://encoded.hostname/"));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QUrl::correctEncodedMistakes_data()
|
||||
|
|
@ -3045,6 +3053,15 @@ void tst_QUrl::setComponents_data()
|
|||
QTest::newRow("invalid-host-1") << QUrl("http://example.com")
|
||||
<< int(Host) << "-not-valid-" << Tolerant << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("invalid-host-2") << QUrl("http://example.com")
|
||||
<< int(Host) << "%31%30.%30.%30.%31" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("invalid-authority-1") << QUrl("http://example.com")
|
||||
<< int(Authority) << "-not-valid-" << Tolerant << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("invalid-authority-2") << QUrl("http://example.com")
|
||||
<< int(Authority) << "%31%30.%30.%30.%31" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("invalid-path-1") << QUrl("/relative")
|
||||
<< int(Path) << "c:/" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
|
|
@ -3063,10 +3080,13 @@ void tst_QUrl::setComponents_data()
|
|||
QTest::newRow("password-encode") << QUrl("http://example.com")
|
||||
<< int(Password) << "h%61llo:world@" << Decoded << true
|
||||
<< PrettyDecoded << "h%2561llo:world@" << "http://:h%2561llo:world%40@example.com";
|
||||
// '%' characters are not permitted in the hostname, this tests that it fails to set anything
|
||||
// '%' characters are not permitted in the hostname, these test that it fails to set anything
|
||||
QTest::newRow("invalid-host-encode") << QUrl("http://example.com")
|
||||
<< int(Host) << "ex%61mple.com" << Decoded << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("invalid-authority-encode") << QUrl("http://example.com")
|
||||
<< int(Authority) << "ex%61mple.com" << Decoded << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
QTest::newRow("path-encode") << QUrl("http://example.com/foo")
|
||||
<< int(Path) << "bar%23" << Decoded << true
|
||||
<< PrettyDecoded << "bar%2523" << "http://example.com/bar%2523";
|
||||
|
|
@ -3142,6 +3162,11 @@ void tst_QUrl::setComponents()
|
|||
QCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Authority:
|
||||
copy.setAuthority(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Query:
|
||||
copy.setQuery(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.hasQuery(), !newValue.isNull());
|
||||
|
|
|
|||
Loading…
Reference in New Issue