QUrl: restore empty-but-not-null for components that are present
This got lost during the QStringView port that happend in Qt 6.0
(commit 548dcef089
) because
QString::operator+=(QStringView) does not copy the nullness of the right
side, whereas QString::operator+=(const QString &) does.
Pick-to: 6.2 6.4 6.5
Fixes: QTBUG-84315
Change-Id: Ide4dbd0777a44ed0870efffd17399b772d34fd55
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
a26d25be7b
commit
a14a3a5487
@ -818,14 +818,16 @@ recodeFromUser(const QString &input, const ushort *actions, qsizetype from, qsiz
|
||||
static inline void appendToUser(QString &appendTo, QStringView value, QUrl::FormattingOptions options,
|
||||
const ushort *actions)
|
||||
{
|
||||
// Test ComponentFormattingOptions, ignore FormattingOptions.
|
||||
if ((options & 0xFFFF0000) == QUrl::PrettyDecoded) {
|
||||
// The stored value is already QUrl::PrettyDecoded, so there's nothing to
|
||||
// do if that's what the user asked for (test only
|
||||
// ComponentFormattingOptions, ignore FormattingOptions).
|
||||
if ((options & 0xFFFF0000) == QUrl::PrettyDecoded ||
|
||||
!qt_urlRecode(appendTo, value, options, actions))
|
||||
appendTo += value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qt_urlRecode(appendTo, value, options, actions))
|
||||
appendTo += value;
|
||||
// copy nullness, if necessary, because QString::operator+=(QStringView) doesn't
|
||||
if (appendTo.isNull() && !value.isNull())
|
||||
appendTo.detach();
|
||||
}
|
||||
|
||||
inline void QUrlPrivate::appendAuthority(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
|
||||
|
@ -3801,106 +3801,106 @@ void tst_QUrl::setComponents_data()
|
||||
|
||||
QTest::newRow("invalid-username-1") << QUrl("http://example.com")
|
||||
<< int(UserName) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-username-2") << QUrl("http://example.com")
|
||||
<< int(UserName) << "foo/bar" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-username-3") << QUrl("http://example.com")
|
||||
<< int(UserName) << "foo:bar" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-password-1") << QUrl("http://example.com")
|
||||
<< int(Password) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-password-2") << QUrl("http://example.com")
|
||||
<< int(Password) << "foo/bar" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-password-3") << QUrl("http://example.com")
|
||||
<< int(Password) << "foo:bar" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-userinfo-1") << QUrl("http://example.com")
|
||||
<< int(UserInfo) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-userinfo-2") << QUrl("http://example.com")
|
||||
<< int(UserInfo) << "foo/bar" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
|
||||
QTest::newRow("invalid-host-1") << QUrl("http://example.com")
|
||||
<< int(Host) << "-not-valid-" << Tolerant << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-host-2") << QUrl("http://example.com")
|
||||
<< int(Host) << "%31%30.%30.%30.%31" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-authority-1") << QUrl("http://example.com")
|
||||
<< int(Authority) << "-not-valid-" << Tolerant << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-authority-2") << QUrl("http://example.com")
|
||||
<< int(Authority) << "%31%30.%30.%30.%31" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
|
||||
QTest::newRow("invalid-path-0") << QUrl("http://example.com")
|
||||
<< int(Path) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-query-1") << QUrl("http://example.com")
|
||||
<< int(Query) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("invalid-fragment-1") << QUrl("http://example.com")
|
||||
<< int(Fragment) << "{}" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
|
||||
// these test cases are "compound invalid":
|
||||
// they produces isValid == false, but the original is still available
|
||||
QTest::newRow("invalid-path-1") << QUrl("/relative")
|
||||
<< int(Path) << "c:/" << Strict << false
|
||||
<< PrettyDecoded << "c:/" << "";
|
||||
<< PrettyDecoded << "c:/" << QString();
|
||||
QTest::newRow("invalid-path-2") << QUrl("http://example.com")
|
||||
<< int(Path) << "relative" << Strict << false
|
||||
<< PrettyDecoded << "relative" << "";
|
||||
<< PrettyDecoded << "relative" << QString();
|
||||
QTest::newRow("invalid-path-3") << QUrl("trash:/")
|
||||
<< int(Path) << "//path" << Tolerant << false
|
||||
<< PrettyDecoded << "//path" << "";
|
||||
<< PrettyDecoded << "//path" << QString();
|
||||
|
||||
// -- test bad percent encoding --
|
||||
// unnecessary to test the scheme, since percent-decoding is not performed in it;
|
||||
// see tests above
|
||||
QTest::newRow("bad-percent-username") << QUrl("http://example.com")
|
||||
<< int(UserName) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-password") << QUrl("http://user@example.com")
|
||||
<< int(Password) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-userinfo-1") << QUrl("http://example.com")
|
||||
<< int(UserInfo) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-userinfo-2") << QUrl("http://example.com")
|
||||
<< int(UserInfo) << "bar%:foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-userinfo-3") << QUrl("http://example.com")
|
||||
<< int(UserInfo) << "bar:%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-authority-1") << QUrl("http://example.com")
|
||||
<< int(Authority) << "bar%foo@example.org" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-authority-2") << QUrl("http://example.com")
|
||||
<< int(Authority) << "bar%:foo@example.org" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-authority-3") << QUrl("http://example.com")
|
||||
<< int(Authority) << "bar:%foo@example.org" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-authority-4") << QUrl("http://example.com")
|
||||
<< int(Authority) << "bar:foo@bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-host") << QUrl("http://example.com")
|
||||
<< int(Host) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-path") << QUrl("http://example.com")
|
||||
<< int(Path) << "/bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-query") << QUrl("http://example.com")
|
||||
<< int(Query) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("bad-percent-fragment") << QUrl("http://example.com")
|
||||
<< int(Fragment) << "bar%foo" << Strict << false
|
||||
<< PrettyDecoded << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
|
||||
// -- test decoded behaviour --
|
||||
// '%' characters are not permitted in the scheme, this tests that it fails to set anything
|
||||
@ -3916,7 +3916,7 @@ void tst_QUrl::setComponents_data()
|
||||
// '%' 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 << "" << "";
|
||||
<< PrettyDecoded << QString() << QString();
|
||||
QTest::newRow("path-encode") << QUrl("http://example.com/foo")
|
||||
<< int(Path) << "/bar%23" << Decoded << true
|
||||
<< PrettyDecoded << "/bar%2523" << "http://example.com/bar%2523";
|
||||
@ -3955,41 +3955,44 @@ void tst_QUrl::setComponents()
|
||||
QFETCH(int, encoding);
|
||||
QFETCH(QString, output);
|
||||
|
||||
#define QNULLCOMPARE(a, b) \
|
||||
do { QCOMPARE(a, b); QCOMPARE(a.isNull(), b.isNull()); } while (false)
|
||||
|
||||
switch (component) {
|
||||
case Scheme:
|
||||
// scheme is only parsed in strict mode
|
||||
copy.setScheme(newValue);
|
||||
QCOMPARE(copy.scheme(), output);
|
||||
QCOMPARE(copy.scheme(), output); // schemes don't become null
|
||||
break;
|
||||
|
||||
case Path:
|
||||
copy.setPath(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.path(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.path(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case UserInfo:
|
||||
copy.setUserInfo(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.userInfo(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.userInfo(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case UserName:
|
||||
copy.setUserName(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.userName(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.userName(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Password:
|
||||
copy.setPassword(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.password(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.password(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Host:
|
||||
copy.setHost(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Authority:
|
||||
copy.setAuthority(newValue, QUrl::ParsingMode(parsingMode));
|
||||
QCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
QNULLCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
|
||||
case Query:
|
||||
@ -4004,6 +4007,7 @@ void tst_QUrl::setComponents()
|
||||
QCOMPARE(copy.fragment(QUrl::ComponentFormattingOptions(encoding)), output);
|
||||
break;
|
||||
}
|
||||
#undef QNULLCOMPARE
|
||||
|
||||
QFETCH(bool, isValid);
|
||||
QCOMPARE(copy.isValid(), isValid);
|
||||
|
Loading…
Reference in New Issue
Block a user