Remove relative directory elements in import paths
Avoid unnecessary conversions to/from QUrl. Change-Id: If52e78cfdaf4fe344f34d961e300b21dd4a11fb2 Reviewed-by: Michael Brasser <michael.brasser@nokia.com> Reviewed-by: Chris Adams <christopher.adams@nokia.com>
This commit is contained in:
parent
1d0368335d
commit
f29c5732f6
|
@ -63,9 +63,6 @@ static bool greaterThan(const QString &s1, const QString &s2)
|
||||||
|
|
||||||
QString resolveLocalUrl(const QString &url, const QString &relative)
|
QString resolveLocalUrl(const QString &url, const QString &relative)
|
||||||
{
|
{
|
||||||
return QUrl(url).resolved(QUrl(relative)).toString();
|
|
||||||
|
|
||||||
//XXX Find out why this broke with new QUrl.
|
|
||||||
if (relative.contains(QLatin1Char(':'))) {
|
if (relative.contains(QLatin1Char(':'))) {
|
||||||
// contains a host name
|
// contains a host name
|
||||||
return QUrl(url).resolved(QUrl(relative)).toString();
|
return QUrl(url).resolved(QUrl(relative)).toString();
|
||||||
|
@ -74,11 +71,41 @@ QString resolveLocalUrl(const QString &url, const QString &relative)
|
||||||
} else if (relative.at(0) == QLatin1Char('/') || !url.contains(QLatin1Char('/'))) {
|
} else if (relative.at(0) == QLatin1Char('/') || !url.contains(QLatin1Char('/'))) {
|
||||||
return relative;
|
return relative;
|
||||||
} else {
|
} else {
|
||||||
|
QString base(url.left(url.lastIndexOf(QLatin1Char('/')) + 1));
|
||||||
|
|
||||||
if (relative == QLatin1String("."))
|
if (relative == QLatin1String("."))
|
||||||
return url.left(url.lastIndexOf(QLatin1Char('/')) + 1);
|
return base;
|
||||||
else if (relative.startsWith(QLatin1String("./")))
|
|
||||||
return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative.mid(2);
|
base.append(relative);
|
||||||
return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative;
|
|
||||||
|
// Remove any relative directory elements in the path
|
||||||
|
const QLatin1Char dot('.');
|
||||||
|
const QLatin1Char slash('/');
|
||||||
|
|
||||||
|
int length = base.length();
|
||||||
|
int index = 0;
|
||||||
|
while ((index = base.indexOf(QLatin1String("/."), index)) != -1) {
|
||||||
|
if ((length > (index + 2)) && (base.at(index + 2) == dot) &&
|
||||||
|
(length == (index + 3) || (base.at(index + 3) == slash))) {
|
||||||
|
// Either "/../" or "/..<END>"
|
||||||
|
int previous = base.lastIndexOf(slash, index - 1);
|
||||||
|
if (previous == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int removeLength = (index - previous) + 3;
|
||||||
|
base.remove(previous + 1, removeLength);
|
||||||
|
length -= removeLength;
|
||||||
|
index = previous;
|
||||||
|
} else if ((length == (index + 2)) || (base.at(index + 2) == slash)) {
|
||||||
|
// Either "/./" or "/.<END>"
|
||||||
|
base.remove(index, 2);
|
||||||
|
length -= 2;
|
||||||
|
} else {
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "SpecificComponent"
|
||||||
|
import "./SpecificComponent"
|
||||||
|
import "././SpecificComponent"
|
||||||
|
import "./././SpecificComponent"
|
||||||
|
import "SpecificComponent/."
|
||||||
|
import "SpecificComponent/./"
|
||||||
|
import "SpecificComponent/./."
|
||||||
|
import "SpecificComponent/././"
|
||||||
|
import "SpecificComponent/././."
|
||||||
|
import "SpecificComponent/./././"
|
||||||
|
import "../data/SpecificComponent"
|
||||||
|
import "./../data/SpecificComponent"
|
||||||
|
import ".././data/SpecificComponent"
|
||||||
|
import "SpecificComponent/nonexistent/../."
|
||||||
|
import "SpecificComponent/nonexistent/.././"
|
||||||
|
import "SpecificComponent/nonexistent/./.."
|
||||||
|
import "SpecificComponent/nonexistent/./../"
|
||||||
|
import "SpecificComponent/nonexistent/nonexistent/../.."
|
||||||
|
import "SpecificComponent/nonexistent/nonexistent/../../"
|
||||||
|
import "SpecificComponent/nonexistent/nonexistent/nonexistent/../../.."
|
||||||
|
import "SpecificComponent/nonexistent/nonexistent/nonexistent/../../../"
|
||||||
|
import "SpecificComponent/.././SpecificComponent"
|
||||||
|
import "SpecificComponent/./../SpecificComponent"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property bool success : true
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import "../../../../../../Invalid"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
}
|
|
@ -323,10 +323,9 @@ void tst_qqmlcomponent::componentUrlCanonicalization()
|
||||||
// load components via import
|
// load components via import
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.qml"));
|
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.qml"));
|
||||||
QObject *object = component.create();
|
QScopedPointer<QObject> object(component.create());
|
||||||
QVERIFY(object != 0);
|
QVERIFY(object != 0);
|
||||||
QVERIFY(object->property("success").toBool());
|
QVERIFY(object->property("success").toBool());
|
||||||
delete object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -334,20 +333,36 @@ void tst_qqmlcomponent::componentUrlCanonicalization()
|
||||||
// import of the other if it were not already loaded.
|
// import of the other if it were not already loaded.
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.2.qml"));
|
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.2.qml"));
|
||||||
QObject *object = component.create();
|
QScopedPointer<QObject> object(component.create());
|
||||||
QVERIFY(object != 0);
|
QVERIFY(object != 0);
|
||||||
QVERIFY(object->property("success").toBool());
|
QVERIFY(object->property("success").toBool());
|
||||||
delete object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// load components with more deeply nested imports
|
// load components with more deeply nested imports
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.3.qml"));
|
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.3.qml"));
|
||||||
QObject *object = component.create();
|
QScopedPointer<QObject> object(component.create());
|
||||||
QVERIFY(object != 0);
|
QVERIFY(object != 0);
|
||||||
QVERIFY(object->property("success").toBool());
|
QVERIFY(object->property("success").toBool());
|
||||||
delete object;
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// load components with unusually specified import paths
|
||||||
|
QQmlEngine engine;
|
||||||
|
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.4.qml"));
|
||||||
|
QScopedPointer<QObject> object(component.create());
|
||||||
|
QVERIFY(object != 0);
|
||||||
|
QVERIFY(object->property("success").toBool());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Do not crash with various nonsense import paths
|
||||||
|
QQmlEngine engine;
|
||||||
|
QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.5.qml"));
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, QLatin1String("QQmlComponent: Component is not ready").data());
|
||||||
|
QScopedPointer<QObject> object(component.create());
|
||||||
|
QVERIFY(object == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue