From caa598c843eb27fd0c645e62723fd2d4e3e12f60 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 27 Sep 2018 11:56:07 -0700 Subject: [PATCH] Fix QUrl::matches for when removing authority parts (other than host) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QUrl::RemoveAuthority is RemoveUserInfo | RemovePort | 0x10, so the condition if (options & QUrl::RemoveAuthority) would match if any of the other bits for the username, password or port were set, which meant we would skip the host comparison. Ditto for username and RemovePassword. [ChangeLog][QtCore][QUrl] Fixed a bug that caused QUrl::matches to incorrectly compare two URLs with different hostnames or different usernames as equal, if certain QUrl::RemoveXxx options were passed. Change-Id: I015970a03b874898bba7fffd155856ab9d6cb1be Fixes: QTBUG-70774 Reviewed-by: MÃ¥rten Nordheim --- src/corelib/io/qurl.cpp | 16 ++++++++-------- tests/auto/corelib/io/qurl/tst_qurl.cpp | 12 ++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 438924bd80..e7ad13d28f 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3722,37 +3722,37 @@ bool QUrl::matches(const QUrl &url, FormattingOptions options) const if (isLocalFile()) mask &= ~QUrlPrivate::Host; - if (options & QUrl::RemoveScheme) + if (options.testFlag(QUrl::RemoveScheme)) mask &= ~QUrlPrivate::Scheme; else if (d->scheme != url.d->scheme) return false; - if (options & QUrl::RemovePassword) + if (options.testFlag(QUrl::RemovePassword)) mask &= ~QUrlPrivate::Password; else if (d->password != url.d->password) return false; - if (options & QUrl::RemoveUserInfo) + if (options.testFlag(QUrl::RemoveUserInfo)) mask &= ~QUrlPrivate::UserName; else if (d->userName != url.d->userName) return false; - if (options & QUrl::RemovePort) + if (options.testFlag(QUrl::RemovePort)) mask &= ~QUrlPrivate::Port; else if (d->port != url.d->port) return false; - if (options & QUrl::RemoveAuthority) + if (options.testFlag(QUrl::RemoveAuthority)) mask &= ~QUrlPrivate::Host; else if (d->host != url.d->host) return false; - if (options & QUrl::RemoveQuery) + if (options.testFlag(QUrl::RemoveQuery)) mask &= ~QUrlPrivate::Query; else if (d->query != url.d->query) return false; - if (options & QUrl::RemoveFragment) + if (options.testFlag(QUrl::RemoveFragment)) mask &= ~QUrlPrivate::Fragment; else if (d->fragment != url.d->fragment) return false; @@ -3760,7 +3760,7 @@ bool QUrl::matches(const QUrl &url, FormattingOptions options) const if ((d->sectionIsPresent & mask) != (url.d->sectionIsPresent & mask)) return false; - if (options & QUrl::RemovePath) + if (options.testFlag(QUrl::RemovePath)) return true; // Compare paths, after applying path-related options diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 09aefcee91..62af907037 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -4123,6 +4123,18 @@ void tst_QUrl::matches_data() << "http://user:pass@www.website.com/directory" << "http://otheruser:otherpass@www.website.com/directory" << uint(QUrl::RemovePath | QUrl::RemoveAuthority) << true; + QTest::newRow("matchingHost-removePort") << "http://example.com" << "http://example.com" + << uint(QUrl::RemovePort) << true; + QTest::newRow("nonMatchingHost-removePort") << "http://example.com" << "http://example.net" + << uint(QUrl::RemovePort) << false; + QTest::newRow("matchingHost-removePassword") << "http://example.com" << "http://example.com" + << uint(QUrl::RemovePassword) << true; + QTest::newRow("nonMatchingHost-removePassword") << "http://example.com" << "http://example.net" + << uint(QUrl::RemovePassword) << false; + QTest::newRow("matchingUserName-removePassword") << "http://user@example.com" << "http://user@example.com" + << uint(QUrl::RemovePassword) << true; + QTest::newRow("nonMatchingUserName-removePassword") << "http://user@example.com" << "http://user2@example.com" + << uint(QUrl::RemovePassword) << false; } void tst_QUrl::matches()