Skip to content

Commit

Permalink
Fix QUrl::toDisplayString(PreferLocalFile) returning an encoded path
Browse files Browse the repository at this point in the history
It's supposed to return the same as toLocalFile(), for local files,
which means passing QUrl::FullyDecoded just like QUrl::toLocalFile()
does.

But a few code paths were testing component formatting options without masking
other FormattingOptions like RemovePassword, so this had to be fixed.

Fixes: QTBUG-84594
Change-Id: I82f15148b6d93516200f9ad6258d474e7f10924a
Reviewed-by: Thiago Macieira <[email protected]>
  • Loading branch information
dfaure-kdab committed Jun 29, 2020
1 parent 76f45e6 commit eb54646
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
10 changes: 6 additions & 4 deletions src/corelib/io/qurl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,8 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to)
static inline void appendToUser(QString &appendTo, QStringView value, QUrl::FormattingOptions options,
const ushort *actions)
{
if (options == QUrl::PrettyDecoded) {
// Test ComponentFormattingOptions, ignore FormattingOptions.
if ((options & 0xFFFF0000) == QUrl::PrettyDecoded) {
appendTo += value;
return;
}
Expand Down Expand Up @@ -3276,9 +3277,10 @@ QString QUrl::toString(FormattingOptions options) const
// also catches isEmpty()
return url;
}
if (options == QUrl::FullyDecoded) {
if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded) {
qWarning("QUrl: QUrl::FullyDecoded is not permitted when reconstructing the full URL");
options = QUrl::PrettyDecoded;
options &= ~QUrl::FullyDecoded;
//options |= QUrl::PrettyDecoded; // no-op, value is 0
}

// return just the path if:
Expand All @@ -3291,7 +3293,7 @@ QString QUrl::toString(FormattingOptions options) const
&& (!d->hasQuery() || options.testFlag(QUrl::RemoveQuery))
&& (!d->hasFragment() || options.testFlag(QUrl::RemoveFragment))
&& isLocalFile()) {
url = d->toLocalFile(options);
url = d->toLocalFile(options | QUrl::FullyDecoded);
return url;
}

Expand Down
2 changes: 1 addition & 1 deletion src/corelib/io/qurlrecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ qt_urlRecode(QString &appendTo, QStringView in,
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications)
{
uchar actionTable[sizeof defaultActionTable];
if (encoding == QUrl::FullyDecoded) {
if ((encoding & QUrl::FullyDecoded) == QUrl::FullyDecoded) {
return int(decode(appendTo, in));
}

Expand Down
28 changes: 28 additions & 0 deletions tests/auto/corelib/io/qurl/tst_qurl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ private slots:
void toString_PreferLocalFile();
void toString_constructed_data();
void toString_constructed();
void toDisplayString_PreferLocalFile_data();
void toDisplayString_PreferLocalFile();
void toAndFromStringList_data();
void toAndFromStringList();
void isParentOf_data();
Expand Down Expand Up @@ -1207,6 +1209,32 @@ void tst_QUrl::toString_constructed()
QCOMPARE(url.toEncoded(formattingOptions), asEncoded);
}

void tst_QUrl::toDisplayString_PreferLocalFile_data()
{
QTest::addColumn<QUrl>("url");
QTest::addColumn<QString>("string");

QTest::newRow("basic") << QUrl::fromLocalFile("/home/charles/foomoo")
<< QString::fromLatin1("/home/charles/foomoo");
QTest::newRow("with%") << QUrl::fromLocalFile("/home/charles/foo%20moo")
<< QString::fromLatin1("/home/charles/foo%20moo");
QTest::newRow("non-local") << QUrl("file://host/foo")
<< QString::fromLatin1("//host/foo");
QTest::newRow("query-and-fragment") << QUrl("file://user:[email protected]/a?b=c%20d%23e#frag%23ment")
<< QString::fromLatin1("file://[email protected]/a?b=c d%23e#frag%23ment");
QTest::newRow("http") << QUrl("http://user:[email protected]/a?b=c%20d%23e#frag%23ment")
<< QString::fromLatin1("http://[email protected]/a?b=c d%23e#frag%23ment");
}

void tst_QUrl::toDisplayString_PreferLocalFile()
{
QFETCH(QUrl, url);
QFETCH(QString, string);

if (url.isLocalFile() && url.query().isEmpty() && url.fragment().isEmpty())
QCOMPARE(url.toLocalFile(), string);
QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), string);
}

void tst_QUrl::isParentOf()
{
Expand Down

0 comments on commit eb54646

Please sign in to comment.