From 8c278563f5dbf5e09f18f56a5042f987da87adc5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 28 Apr 2016 13:40:55 -0700 Subject: [PATCH 1/7] allow scripts on the web to refer to interface-local javascript libraries --- libraries/script-engine/src/ScriptEngine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 15f3ebb985..19246dd355 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -912,7 +912,13 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac // Do NOT use PreferLocalFile as its behavior is unpredictable (e.g., on defaultScriptsLocation()) const auto strippingFlags = QUrl::RemoveFilename | QUrl::RemoveQuery | QUrl::RemoveFragment; for (QString file : includeFiles) { - QUrl thisURL { resolvePath(file) }; + QUrl thisURL; + if (file.startsWith("/~/")) { + thisURL = expandScriptUrl(QUrl::fromLocalFile(file)); + } else { + thisURL = resolvePath(file); + } + if (!_includedURLs.contains(thisURL)) { if (!currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") && ( From 648e6a74d7f159b588cce82de8590cf0b5421fe9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 28 Apr 2016 15:43:58 -0700 Subject: [PATCH 2/7] don't let people access scripts outside of /~/ --- libraries/script-engine/src/ScriptEngines.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index eeca49ff84..84f2de0e56 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -82,6 +82,15 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { QStringList splitPath = url.path().split("/"); QUrl defaultScriptsLoc = defaultScriptsLocation(); url.setPath(defaultScriptsLoc.path() + "/" + splitPath.mid(2).join("/")); // 2 to skip the slashes in /~/ + + // stop something like Script.include(["/~/../Users/james/Desktop/naughty.js"]); from working + QFileInfo fileInfo(url.path()); + url.setPath(fileInfo.absoluteFilePath()); + + if (!url.path().startsWith(defaultScriptsLoc.path())) { + qCWarning(scriptengine) << "Script.include() ignoring file path" << normalizedScriptURL + << "outside of standard libraries"; + } return url; } return normalizedScriptURL; From 8c2b89b910b0575c799ecf297f73c42ac8283238 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 28 Apr 2016 17:08:38 -0700 Subject: [PATCH 3/7] trying to get /~/ from web sorted out --- libraries/script-engine/src/ScriptEngines.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 84f2de0e56..14b0b83acc 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -84,12 +84,17 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { url.setPath(defaultScriptsLoc.path() + "/" + splitPath.mid(2).join("/")); // 2 to skip the slashes in /~/ // stop something like Script.include(["/~/../Users/james/Desktop/naughty.js"]); from working - QFileInfo fileInfo(url.path()); - url.setPath(fileInfo.absoluteFilePath()); + qDebug() << "url: " << url.path(); + qDebug() << "BEFORE: " << url.path(); + QFileInfo fileInfo(url.toLocalFile()); + url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + qDebug() << "AFTER: " << url.path(); + qDebug() << "default: " << defaultScriptsLoc.path(); - if (!url.path().startsWith(defaultScriptsLoc.path())) { + if (!defaultScriptsLoc.isParentOf(url)) { qCWarning(scriptengine) << "Script.include() ignoring file path" << normalizedScriptURL - << "outside of standard libraries"; + << "outside of standard libraries" << url.path() << defaultScriptsLoc.path(); + // return QUrl(""); } return url; } From ced18fe6be06f255f2ce7b11eba567ba7c3aa029 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 28 Apr 2016 18:29:08 -0700 Subject: [PATCH 4/7] trying some more to get /~/ to work right --- libraries/script-engine/src/ScriptEngines.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 14b0b83acc..80f2216e2b 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -83,18 +83,13 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { QUrl defaultScriptsLoc = defaultScriptsLocation(); url.setPath(defaultScriptsLoc.path() + "/" + splitPath.mid(2).join("/")); // 2 to skip the slashes in /~/ - // stop something like Script.include(["/~/../Users/james/Desktop/naughty.js"]); from working - qDebug() << "url: " << url.path(); - qDebug() << "BEFORE: " << url.path(); + // stop something like Script.include(["/~/../Desktop/naughty.js"]); from working QFileInfo fileInfo(url.toLocalFile()); - url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()); - qDebug() << "AFTER: " << url.path(); - qDebug() << "default: " << defaultScriptsLoc.path(); - + url = QUrl::fromLocalFile(fileInfo.canonicalFilePath()); if (!defaultScriptsLoc.isParentOf(url)) { - qCWarning(scriptengine) << "Script.include() ignoring file path" << normalizedScriptURL - << "outside of standard libraries" << url.path() << defaultScriptsLoc.path(); - // return QUrl(""); + qCWarning(scriptengine) << "Script.include() ignoring file path" << rawScriptURL + << "-- outside of standard libraries: " << url.path() << defaultScriptsLoc.path(); + return QUrl(""); } return url; } From f03130ff5ab857ae0e59e0d060b1b8693b9a7f11 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 29 Apr 2016 11:03:14 -0700 Subject: [PATCH 5/7] more work toward keeping /~/../.. from working --- libraries/script-engine/src/ScriptEngine.cpp | 7 +++++- libraries/script-engine/src/ScriptEngines.cpp | 24 +++++++++++++++---- libraries/script-engine/src/ScriptEngines.h | 1 + 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 19246dd355..78a0ad2d19 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -914,7 +914,12 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac for (QString file : includeFiles) { QUrl thisURL; if (file.startsWith("/~/")) { - thisURL = expandScriptUrl(QUrl::fromLocalFile(file)); + thisURL = expandScriptUrl(QUrl::fromLocalFile(expandScriptPath(file))); + QUrl defaultScriptsLoc = defaultScriptsLocation(); + if (!defaultScriptsLoc.isParentOf(thisURL)) { + qDebug() << "ScriptEngine::include -- skipping" << file << "-- outside of standard libraries"; + continue; + } } else { thisURL = resolvePath(file); } diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 80f2216e2b..aed2d15a1a 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -70,6 +70,12 @@ QUrl normalizeScriptURL(const QUrl& rawScriptURL) { } } +QString expandScriptPath(const QString& rawPath) { + QStringList splitPath = rawPath.split("/"); + QUrl defaultScriptsLoc = defaultScriptsLocation(); + return defaultScriptsLoc.path() + "/" + splitPath.mid(2).join("/"); // 2 to skip the slashes in /~/ +} + QUrl expandScriptUrl(const QUrl& rawScriptURL) { QUrl normalizedScriptURL = normalizeScriptURL(rawScriptURL); if (normalizedScriptURL.scheme() == "http" || @@ -79,17 +85,25 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { } else if (normalizedScriptURL.scheme() == "file") { if (normalizedScriptURL.path().startsWith("/~/")) { QUrl url = normalizedScriptURL; - QStringList splitPath = url.path().split("/"); - QUrl defaultScriptsLoc = defaultScriptsLocation(); - url.setPath(defaultScriptsLoc.path() + "/" + splitPath.mid(2).join("/")); // 2 to skip the slashes in /~/ + url.setPath(expandScriptPath(url.path())); // stop something like Script.include(["/~/../Desktop/naughty.js"]); from working QFileInfo fileInfo(url.toLocalFile()); + #if defined(Q_OS_WIN) + url = QUrl::fromLocalFile(fileInfo.canonicalFilePath().toLower()); + #elif defined(Q_OS_OSX) + url = QUrl::fromLocalFile(fileInfo.canonicalFilePath().toLower()); + #else url = QUrl::fromLocalFile(fileInfo.canonicalFilePath()); + #endif + + QUrl defaultScriptsLoc = defaultScriptsLocation(); if (!defaultScriptsLoc.isParentOf(url)) { qCWarning(scriptengine) << "Script.include() ignoring file path" << rawScriptURL - << "-- outside of standard libraries: " << url.path() << defaultScriptsLoc.path(); - return QUrl(""); + << "-- outside of standard libraries: " + << url.path() + << defaultScriptsLoc.path(); + return rawScriptURL; } return url; } diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 5de71663e9..0963b21600 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -101,6 +101,7 @@ protected: }; QUrl normalizeScriptURL(const QUrl& rawScriptURL); +QString expandScriptPath(const QString& rawPath); QUrl expandScriptUrl(const QUrl& rawScriptURL); #endif // hifi_ScriptEngine_h From b28cfd27ec1cfdab9df4d66e2b18aeeb51972933 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 29 Apr 2016 13:17:28 -0700 Subject: [PATCH 6/7] fix problem where canonicalFilePath will strip a trailing slash --- libraries/script-engine/src/ScriptEngine.cpp | 1 + libraries/script-engine/src/ScriptEngines.cpp | 9 +++------ libraries/shared/src/PathUtils.cpp | 15 +++++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 78a0ad2d19..960b3c6d90 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -874,6 +874,7 @@ QUrl ScriptEngine::resolvePath(const QString& include) const { } // at this point we should have a legitimate fully qualified URL for our parent + qDebug() << "ScriptEngine::resolvePath" << parentURL << url; url = expandScriptUrl(parentURL.resolved(url)); return url; } diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index aed2d15a1a..3f2e0aa908 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -89,13 +89,7 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { // stop something like Script.include(["/~/../Desktop/naughty.js"]); from working QFileInfo fileInfo(url.toLocalFile()); - #if defined(Q_OS_WIN) - url = QUrl::fromLocalFile(fileInfo.canonicalFilePath().toLower()); - #elif defined(Q_OS_OSX) - url = QUrl::fromLocalFile(fileInfo.canonicalFilePath().toLower()); - #else url = QUrl::fromLocalFile(fileInfo.canonicalFilePath()); - #endif QUrl defaultScriptsLoc = defaultScriptsLocation(); if (!defaultScriptsLoc.isParentOf(url)) { @@ -105,6 +99,9 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) { << defaultScriptsLoc.path(); return rawScriptURL; } + if (rawScriptURL.path().endsWith("/") && !url.path().endsWith("/")) { + url.setPath(url.path() + "/"); + } return url; } return normalizedScriptURL; diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index 025768908c..954ed2d75a 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -56,12 +56,15 @@ QString findMostRecentFileExtension(const QString& originalFileName, QVector Date: Fri, 29 Apr 2016 13:23:01 -0700 Subject: [PATCH 7/7] remove debug print --- libraries/script-engine/src/ScriptEngine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 960b3c6d90..78a0ad2d19 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -874,7 +874,6 @@ QUrl ScriptEngine::resolvePath(const QString& include) const { } // at this point we should have a legitimate fully qualified URL for our parent - qDebug() << "ScriptEngine::resolvePath" << parentURL << url; url = expandScriptUrl(parentURL.resolved(url)); return url; }