History

* rework _requireResolve error throws (to avoid using lambda w/default args -- which vc++ didn't care for) * add ExceptionEmitters to require/resolve so errors get logged even if invoked indpendently from a script

humbletim committed 9 years ago

Commit 32e450e1 parent efc61c21 file · +24 −24Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 1 file). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+24−24
@@ -1361,28 +1361,22 @@ void ScriptEngine::print(const QString& message) { · 1360 unmodified lines
1361QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& relativeTo) {1361QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& relativeTo) {
1362 QUrl defaultScriptsLoc = defaultScriptsLocation();1362 QUrl defaultScriptsLoc = defaultScriptsLocation();
1363 QUrl url(moduleId);1363 QUrl url(moduleId);
1364 ExceptionEmitter tryCatcher(this, __FUNCTION__);
1364 1365
1365 // helper to generate an exception and return a null string1366 auto displayId = moduleId;
1366 auto resolverException = [=](const QString& detail, const QString& type = "Error") -> QString {1367 if (displayId.length() > MAX_DEBUG_VALUE_LENGTH) {
1367 auto displayId = moduleId;1368 displayId = displayId.mid(0, MAX_DEBUG_VALUE_LENGTH) + "...";
1368 if (displayId.length() > MAX_DEBUG_VALUE_LENGTH) {1369 }
1369 displayId = displayId.mid(0, MAX_DEBUG_VALUE_LENGTH) + "...";1370 auto message = QString("Cannot find module '%1' (%2)").arg(displayId);
1370 }1371 auto ctx = currentContext();
1371 currentContext()->throwValue(makeError(
1372 QString("Cannot find module '%1' (%2)")
1373 .arg(displayId)
1374 .arg(detail), type));
1375 return QString();
1376 };
1377 1372
1378 // de-fuzz the input a little by restricting to rational sizes1373 // de-fuzz the input a little by restricting to rational sizes
1379 auto idLength = url.toString().length();1374 auto idLength = url.toString().length();
1380 if (idLength < 1 || idLength > MAX_MODULE_ID_LENTGH) {1375 if (idLength < 1 || idLength > MAX_MODULE_ID_LENTGH) {
1381 return resolverException(1376 auto details = QString("rejecting invalid module id size (%1 chars [1,%2])")
1382 QString("rejecting invalid module id size (%1 chars [1,%2])")1377 .arg(idLength).arg(MAX_MODULE_ID_LENTGH);
1383 .arg(idLength).arg(MAX_MODULE_ID_LENTGH),1378 ctx->throwValue(makeError(message.arg(details), "RangeError"));
1384 "RangeError"1379 return nullptr;
1385 );
1386 }1380 }
1387 1381
1388 // this regex matches: absolute, dotted or path-like URLs1382 // this regex matches: absolute, dotted or path-like URLs
@@ -1402,12 +1396,14 @@ QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& re · 13 unmodified lines
1402 url = defaultScriptsLoc;1396 url = defaultScriptsLoc;
1403 url.setPath(systemModulePath);1397 url.setPath(systemModulePath);
1404 if (!QFileInfo(url.toLocalFile()).isFile()) {1398 if (!QFileInfo(url.toLocalFile()).isFile()) {
1405 return resolverException("system module not found");1399 ctx->throwValue(makeError(message.arg("system module not found")));
1400 return nullptr;
1406 }1401 }
1407 }1402 }
1408 1403
1409 if (url.isRelative()) {1404 if (url.isRelative()) {
1410 return resolverException("could not resolve module id");1405 ctx->throwValue(makeError(message.arg("could not resolve module id")));
1406 return nullptr;
1411 }1407 }
1412 1408
1413 // if it looks like a local file, verify that it's an allowed path and really a file1409 // if it looks like a local file, verify that it's an allowed path and really a file
@@ -1420,18 +1416,21 @@ QString ScriptEngine::_requireResolve(const QString& moduleId, const QString& re · 6 unmodified lines
1420 1416
1421 bool disallowOutsideFiles = !defaultScriptsLocation().isParentOf(canonical) && !currentSandboxURL.isLocalFile();1417 bool disallowOutsideFiles = !defaultScriptsLocation().isParentOf(canonical) && !currentSandboxURL.isLocalFile();
1422 if (disallowOutsideFiles && !PathUtils::isDescendantOf(canonical, currentSandboxURL)) {1418 if (disallowOutsideFiles && !PathUtils::isDescendantOf(canonical, currentSandboxURL)) {
1423 return resolverException(1419 ctx->throwValue(makeError(message.arg(
1424 QString("path '%1' outside of origin script '%2' '%3'")1420 QString("path '%1' outside of origin script '%2' '%3'")
1425 .arg(PathUtils::stripFilename(url))1421 .arg(PathUtils::stripFilename(url))
1426 .arg(PathUtils::stripFilename(currentSandboxURL))1422 .arg(PathUtils::stripFilename(currentSandboxURL))
1427 .arg(canonical.toString())1423 .arg(canonical.toString())
1428 );1424 )));
1425 return nullptr;
1429 }1426 }
1430 if (!file.exists()) {1427 if (!file.exists()) {
1431 return resolverException("path does not exist: " + url.toLocalFile());1428 ctx->throwValue(makeError(message.arg("path does not exist: " + url.toLocalFile())));
1429 return nullptr;
1432 }1430 }
1433 if (!file.isFile()) {1431 if (!file.isFile()) {
1434 return resolverException("path is not a file: " + url.toLocalFile());1432 ctx->throwValue(makeError(message.arg("path is not a file: " + url.toLocalFile())));
1433 return nullptr;
1435 }1434 }
1436 }1435 }
1437 1436
@@ -1611,6 +1610,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId) { · 173 unmodified lines
1611 // serialize require calls so the ordering/caching works correctly across multiple Entities1610 // serialize require calls so the ordering/caching works correctly across multiple Entities
1612 // note: this is a Recursive mutex so nested require's should not affected1611 // note: this is a Recursive mutex so nested require's should not affected
1613 QMutexLocker locker(&_requireLock);1612 QMutexLocker locker(&_requireLock);
1613 ExceptionEmitter tryCatcher(this, __FUNCTION__);
1614 // _requireDepth++;1614 // _requireDepth++;
1615 // QObject autoDecrement;connect(&autoDecrement, &QObject::destroyed, this, [this](){ _requireDepth--; });1615 // QObject autoDecrement;connect(&autoDecrement, &QObject::destroyed, this, [this](){ _requireDepth--; });
1616 1616
@@ -1632,7 +1632,7 @@ QScriptValue ScriptEngine::require(const QString& moduleId) { · 15 unmodified lines
1632 1632
1633 // start by resolving the moduleId into a fully-qualified path/URL1633 // start by resolving the moduleId into a fully-qualified path/URL
1634 QString modulePath = _requireResolve(moduleId);1634 QString modulePath = _requireResolve(moduleId);
1635 if (hasUncaughtException()) {1635 if (modulePath.isNull() || tryCatcher.hasPending()) {
1636 // the resolver already threw an exception -- bail early1636 // the resolver already threw an exception -- bail early
1637 return nullValue();1637 return nullValue();
1638 }1638 }