Merge pull request #13497 from hyperlogic/bug-fix/script-engine-batchloader-memory-corruption-fix

Fix memory corruption when running scripts using Script.require().
This commit is contained in:
Anthony Thibault 2018-06-28 14:18:56 -07:00 committed by GitHub
commit a5919ee3fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1639,22 +1639,24 @@ QVariantMap ScriptEngine::fetchModuleSource(const QString& modulePath, const boo
loader->start(MAX_RETRIES); loader->start(MAX_RETRIES);
if (!loader->isFinished()) { if (!loader->isFinished()) {
QTimer monitor; // This lambda can get called AFTER this local scope has completed.
QEventLoop loop; // This is why we pass smart ptrs to the lambda instead of references to local variables.
QObject::connect(loader, &BatchLoader::finished, this, [&monitor, &loop]{ auto monitor = std::make_shared<QTimer>();
monitor.stop(); auto loop = std::make_shared<QEventLoop>();
loop.quit(); QObject::connect(loader, &BatchLoader::finished, this, [monitor, loop] {
monitor->stop();
loop->quit();
}); });
// this helps detect the case where stop() is invoked during the download // this helps detect the case where stop() is invoked during the download
// but not seen in time to abort processing in onload()... // but not seen in time to abort processing in onload()...
connect(&monitor, &QTimer::timeout, this, [this, &loop]{ connect(monitor.get(), &QTimer::timeout, this, [this, loop] {
if (isStopping()) { if (isStopping()) {
loop.exit(-1); loop->exit(-1);
} }
}); });
monitor.start(500); monitor->start(500);
loop.exec(); loop->exec();
} }
loader->deleteLater(); loader->deleteLater();
return req; return req;