summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp3
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp16
-rw-r--r--src/declarative/qml/qdeclarativecontext.h2
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml3
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml3
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml3
-rw-r--r--tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp41
7 files changed, 69 insertions, 2 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index 745734e..3cbafd6 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -185,6 +185,9 @@ void QDeclarativeLoader::setSource(const QUrl &url)
if (d->source == url)
return;
+ if (!qmlContext(this)->isSafeOrigin(url))
+ return;
+
d->clear();
d->source = url;
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 85896c4..ab3849a 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -361,6 +361,22 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
return value;
}
+bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const
+{
+ if (src.isRelative())
+ return true;
+ if (src.scheme()==QLatin1String("https"))
+ return true;
+
+ QUrl base = baseUrl();
+ if (src.host() == base.host() && src.port() == base.port()) // including files (with no host)
+ return true;
+
+ qWarning() << src << "is not a safe origin from" << base;
+
+ return false;
+}
+
/*!
Resolves the URL \a src relative to the URL of the
containing component.
diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h
index a349628..959af8b 100644
--- a/src/declarative/qml/qdeclarativecontext.h
+++ b/src/declarative/qml/qdeclarativecontext.h
@@ -85,6 +85,8 @@ public:
void setBaseUrl(const QUrl &);
QUrl baseUrl() const;
+ bool isSafeOrigin(const QUrl &src) const;
+
private:
friend class QDeclarativeVME;
friend class QDeclarativeEngine;
diff --git a/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml
new file mode 100644
index 0000000..e682d1c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml
@@ -0,0 +1,3 @@
+import Qt 4.6
+
+Loader { source: "http://evil.place/evil.qml" }
diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml
new file mode 100644
index 0000000..e281246
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml
@@ -0,0 +1,3 @@
+import Qt 4.6
+
+Item { }
diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml
new file mode 100644
index 0000000..e7f5a14
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml
@@ -0,0 +1,3 @@
+import Qt 4.6
+
+Loader { source: "sameorigin-load.qml" }
diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
index 2c20836..0deac3a 100644
--- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
+++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
@@ -86,6 +86,8 @@ private slots:
void noResizeGraphicsWidget();
void networkRequestUrl();
void failNetworkRequest();
+ void networkSafety();
+ void networkSafety_data();
// void networkComponent();
void deleteComponentCrash();
@@ -394,7 +396,7 @@ void tst_QDeclarativeLoader::networkRequestUrl()
server.serveDirectory(SRCDIR "/data");
QDeclarativeComponent component(&engine);
- component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), TEST_FILE(""));
+ component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml"));
QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create());
QVERIFY(loader != 0);
@@ -448,7 +450,7 @@ void tst_QDeclarativeLoader::failNetworkRequest()
QTest::ignoreMessage(QtWarningMsg, "(:-1: Network error for URL http://127.0.0.1:14445/IDontExist.qml) ");
QDeclarativeComponent component(&engine);
- component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), TEST_FILE(""));
+ component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml"));
QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create());
QVERIFY(loader != 0);
@@ -483,6 +485,41 @@ void tst_QDeclarativeLoader::deleteComponentCrash()
delete item;
}
+void tst_QDeclarativeLoader::networkSafety_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QString>("message");
+
+ QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString();
+ QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) ");
+}
+
+void tst_QDeclarativeLoader::networkSafety()
+{
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ server.serveDirectory(SRCDIR "/data");
+
+ QFETCH(QUrl, url);
+ QFETCH(QString, message);
+
+ if (!message.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
+
+ QDeclarativeComponent component(&engine, url);
+ TRY_WAIT(component.status() == QDeclarativeComponent::Ready);
+ QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create());
+ QVERIFY(loader != 0);
+
+ if (message.isEmpty()) {
+ TRY_WAIT(loader->status() == QDeclarativeLoader::Ready);
+ } else {
+ TRY_WAIT(loader->status() == QDeclarativeLoader::Null);
+ }
+
+ delete loader;
+}
+
QTEST_MAIN(tst_QDeclarativeLoader)
#include "tst_qdeclarativeloader.moc"