aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier De Cannière <olivier.decanniere@qt.io>2023-02-08 11:17:58 +0100
committerOlivier De Cannière <olivier.decanniere@qt.io>2023-02-09 13:02:01 +0100
commit6cca731f3e1304ce98f1ec18af42e3bd06001eea (patch)
tree89eb1a5a9f6bc4c8183602632a7e7e2a08d0902d
parentd2c8fe712a87a247864decd9d13167f847035aab (diff)
UrlObject: Properly encode the url search components
The href() and search() functions now return properly encoded search components. Tests were added to tst_urlobject.cpp to verify this. Pick-to: 6.5 Fixes: QTBUG-110454 Change-Id: I3d6485eeeedbd5ba5423cdd42d9c17669ca4bd62 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp13
-rw-r--r--src/qml/jsruntime/qv4urlobject_p.h2
-rw-r--r--tests/auto/qml/qv4urlobject/tst_qv4urlobject.cpp86
3 files changed, 98 insertions, 3 deletions
diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp
index e5d8ddb9e8..4417d327c6 100644
--- a/src/qml/jsruntime/qv4urlobject.cpp
+++ b/src/qml/jsruntime/qv4urlobject.cpp
@@ -124,14 +124,14 @@ void UrlObject::setUrl(const QUrl &url)
{
d()->hash.set(engine(), engine()->newString(url.fragment()));
d()->hostname.set(engine(), engine()->newString(url.host()));
- d()->href.set(engine(), engine()->newString(url.toString()));
+ d()->href.set(engine(), engine()->newString(url.toString(QUrl::ComponentFormattingOptions(QUrl::ComponentFormattingOption::FullyEncoded))));
d()->password.set(engine(), engine()->newString(url.password()));
d()->pathname.set(engine(), engine()->newString(url.path()));
d()->port.set(engine(),
engine()->newString(url.port() == -1 ? QLatin1String("")
: QString::number(url.port())));
d()->protocol.set(engine(), engine()->newString(url.scheme() + QLatin1Char(':')));
- d()->search.set(engine(), engine()->newString(url.query()));
+ d()->search.set(engine(), engine()->newString(url.query(QUrl::ComponentFormattingOptions(QUrl::ComponentFormattingOption::FullyEncoded))));
d()->username.set(engine(), engine()->newString(url.userName()));
updateOrigin();
@@ -242,6 +242,15 @@ bool UrlObject::setUsername(QString username)
return true;
}
+QString UrlObject::search() const
+{
+ auto url = QUrl(href());
+ if (auto url = QUrl(href()); !url.hasQuery() || url.query().isEmpty())
+ return QLatin1String("");
+
+ return QLatin1Char('?') + url.query(QUrl::ComponentFormattingOptions(QUrl::ComponentFormattingOption::FullyEncoded));
+}
+
QUrl UrlObject::toQUrl() const
{
return QUrl(href());
diff --git a/src/qml/jsruntime/qv4urlobject_p.h b/src/qml/jsruntime/qv4urlobject_p.h
index 4e4a03a923..d45b74fcaa 100644
--- a/src/qml/jsruntime/qv4urlobject_p.h
+++ b/src/qml/jsruntime/qv4urlobject_p.h
@@ -102,7 +102,7 @@ struct UrlObject : Object
QString protocol() const { return toQString(d()->protocol); }
bool setProtocol(QString protocol);
- QString search() const { return QLatin1String("?") + toQString(d()->search); }
+ Q_QML_AUTOTEST_EXPORT QString search() const;
bool setSearch(QString search);
QString username() const { return toQString(d()->username); }
diff --git a/tests/auto/qml/qv4urlobject/tst_qv4urlobject.cpp b/tests/auto/qml/qv4urlobject/tst_qv4urlobject.cpp
index 99a5803586..886bfda018 100644
--- a/tests/auto/qml/qv4urlobject/tst_qv4urlobject.cpp
+++ b/tests/auto/qml/qv4urlobject/tst_qv4urlobject.cpp
@@ -11,6 +11,10 @@ class tst_urlobject : public QObject
private slots:
void searchParams_set();
void searchParams_nullUrlPointer();
+ void urlObject_search();
+ void urlObject_search_data();
+ void urlObject_href();
+ void urlObject_href_data();
};
void tst_urlobject::searchParams_set()
@@ -53,6 +57,88 @@ void tst_urlobject::searchParams_nullUrlPointer()
QVERIFY(!result.isError());
}
+void tst_urlobject::urlObject_search()
+{
+ QFETCH(QString, test);
+ QFETCH(QString, expected);
+
+ QJSEngine engine;
+
+ QCOMPARE(engine.evaluate(test).toString(), expected);
+}
+
+void tst_urlobject::urlObject_search_data()
+{
+ QTest::addColumn<QString>("test");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("base case")
+ << "var url = new URL(\"http://www.google.com/search?q=123\");"
+ "url.search"
+ << "?q=123";
+ QTest::newRow("space")
+ << "var url = new URL(\"http://www.google.com/search?a=b ~\");"
+ "url.search"
+ << "?a=b%20~";
+ QTest::newRow("empty search")
+ << "var url = new URL(\"http://www.google.com/search?\");"
+ "url.search"
+ << "";
+ QTest::newRow("no search")
+ << "var url = new URL(\"http://www.google.com/search\");"
+ "url.search"
+ << "";
+ QTest::newRow("Question mark")
+ << "var url = new URL(\"http://www.google.com/search??=?\");"
+ "url.search"
+ << "??=?";
+ QTest::newRow("equal sign")
+ << "var url = new URL(\"http://www.google.com/search?a==&b=!\");"
+ "url.search"
+ << "?a==&b=!";
+ QTest::newRow("percent sign")
+ << "var url = new URL(\"http://www.google.com/search?a=%20\");"
+ "url.search"
+ << "?a=%20";
+ QTest::newRow("multiple key-value pairs")
+ << "var url = new URL(\"http://www.google.com/search?a=b&c=d\");"
+ "url.search"
+ << "?a=b&c=d";
+ QTest::newRow("unreserved")
+ << "var url = new URL(\"http://www.google.com/search?a=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~\");"
+ "url.search"
+ << "?a=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~";
+ QTest::newRow("reserved + illegal")
+ << "var url = new URL(\"http://google.com/search/?a=!*();:@&=+$,/?#[]\");"
+ "url.search"
+ << "?a=!*();:@&=+$,/?";
+ QTest::newRow("unicode (U+327D)")
+ << "var url = new URL(\"http://google.com/search/?a=㉽\");"
+ "url.search"
+ << "?a=%E3%89%BD";
+}
+
+void tst_urlobject::urlObject_href()
+{
+ QFETCH(QString, test);
+ QFETCH(QString, expected);
+
+ QJSEngine engine;
+
+ QCOMPARE(engine.evaluate(test).toString(), expected);
+}
+
+void tst_urlobject::urlObject_href_data()
+{
+ QTest::addColumn<QString>("test");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("QTBUG-110454")
+ << "var url = new URL(\"https://example.com/?a=b ~\");"
+ "url.href"
+ << "https://example.com/?a=b%20~";
+}
+
QTEST_MAIN(tst_urlobject)
#include "tst_qv4urlobject.moc"