Ai
1 Star 1 Fork 1

HuanZeng/texstudio

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
scriptobject.cpp 9.66 KB
一键复制 编辑 原始数据 按行查看 历史
#include "scriptobject.h"
#include "smallUsefulFunctions.h"
#include "qcryptographichash.h"
#include "configmanagerinterface.h"
#include "buildmanager.h"
#include "QtUiTools/QUiLoader"
#include "QBuffer"
QStringList privilegedReadScripts, privilegedWriteScripts;
int readSecurityMode, writeSecurityMode;
ScriptObject::ScriptObject(const QString &script, BuildManager *buildManager, Texstudio *app): backgroundScript(false), buildManager(buildManager), script(script), app(app)
{
ConfigManagerInterface::getInstance()->registerOption("Scripts/Privileged Read Scripts", &privilegedReadScripts);
ConfigManagerInterface::getInstance()->registerOption("Scripts/Read Security Mode", &readSecurityMode, 1);
ConfigManagerInterface::getInstance()->registerOption("Scripts/Privileged Write Scripts", &privilegedWriteScripts);
ConfigManagerInterface::getInstance()->registerOption("Scripts/Write Security Mode", &writeSecurityMode, 1);
this->subScriptObject.script = this;
}
void ScriptObject::alert(const QString &message)
{
UtilsUi::txsInformation(message);
}
void ScriptObject::information(const QString &message)
{
UtilsUi::txsInformation(message);
}
void ScriptObject::critical(const QString &message)
{
UtilsUi::txsCritical(message);
}
void ScriptObject::warning(const QString &message)
{
UtilsUi::txsWarning(message);
}
bool ScriptObject::confirm(const QString &message)
{
return UtilsUi::txsConfirm(message);
}
bool ScriptObject::confirmWarning(const QString &message)
{
return UtilsUi::txsConfirmWarning(message);
}
void ScriptObject::debug(const QString &message)
{
qDebug() << message;
}
#ifndef QT_NO_DEBUG
void ScriptObject::crash_assert()
{
Q_ASSERT(false);
}
#endif
void ScriptObject::crash_sigsegv()
{
if (!confirmWarning("Do you want to let txs crash with a SIGSEGV?")) return;
char *c = nullptr;
*c = 'A';
}
int global0 = 0;
void ScriptObject::crash_sigfpe()
{
if (!confirmWarning("Do you want to let txs crash with a SIGFPE?")) return;
int x = 1 / global0;
Q_UNUSED(x)
}
void ScriptObject::crash_stack()
{
if (!confirmWarning("Do you want to let txs crash with a stack overflow?")) return;
int temp = global0;
crash_stack();
Q_UNUSED(temp)
}
void ScriptObject::crash_loop()
{
if (!confirmWarning("Do you want to let txs freeze with an endless loop?")) return;
//#ifndef QT_NO_DEBUG // only used in the Q_ASSERT statements: prevent unused variable warning in release build
register int a = 1, b = 2, c = 3, d = 4;
//#endif
while (true) {
void *x = malloc(16);
free(x);
Q_ASSERT(a == 1);
Q_ASSERT(b == 2);
Q_ASSERT(c == 3);
Q_ASSERT(d == 4); //make sure, no register suddenly change
};
}
void ScriptObject::crash_throw()
{
if (!confirmWarning("Do you want to let txs crash with an exception?")) return;
throw "debug crash";
}
ProcessX *ScriptObject::system(const QString &commandline, const QString &workingDirectory)
{
if (!buildManager || !needWritePrivileges("system", commandline))
return nullptr;
ProcessX *p = nullptr;
if (commandline.contains(BuildManager::TXS_CMD_PREFIX) || !commandline.contains("|"))
p = buildManager->firstProcessOfDirectExpansion(commandline, QFileInfo());
else
p = buildManager->newProcessInternal(commandline, QFileInfo()); //use internal, so people can pass | to sh
if (!p) return nullptr;
connect(p, SIGNAL(finished(int, QProcess::ExitStatus)), p, SLOT(deleteLater()));
QMetaObject::invokeMethod(reinterpret_cast<QObject *>(app), "connectSubCommand", Q_ARG(ProcessX *, p), Q_ARG(bool, true));
if (!workingDirectory.isEmpty())
p->setWorkingDirectory(workingDirectory);
p->startCommand();
p->waitForStarted();
return p;
}
void ScriptObject::writeFile(const QString &filename, const QString &content)
{
if (!needWritePrivileges("writeFile", filename))
return;
QFile f(filename);
if (!f.open(QFile::WriteOnly))
return;
f.write(content.toUtf8());
f.close();
}
QVariant ScriptObject::readFile(const QString &filename)
{
if (!needReadPrivileges("readFile", filename))
return QVariant();
QFile f(filename);
if (!f.open(QFile::ReadOnly))
return QVariant();
QTextStream ts(&f);
ts.setAutoDetectUnicode(true);
ts.setCodec(QTextCodec::codecForName("UTF-8"));
return ts.readAll();
}
static QHash<QString, QVariant> globalGlobals;
bool ScriptObject::hasGlobal(const QString &name)
{
return globalGlobals.contains(name);
}
void ScriptObject::setGlobal(const QString &name, const QVariant &value)
{
globalGlobals.insert(name, value);
}
QVariant ScriptObject::getGlobal(const QString &name)
{
return globalGlobals.value(name);
}
bool ScriptObject::hasPersistent(const QString &name)
{
return ConfigManagerInterface::getInstance()->existsOption(name);
}
void ScriptObject::setPersistent(const QString &name, const QVariant &value)
{
if (!needWritePrivileges("setPersistent", name + "=" + value.toString())) return;
ConfigManagerInterface::getInstance()->setOption(name, value);
}
QVariant ScriptObject::getPersistent(const QString &name)
{
if (!needReadPrivileges("getPersistent", name)) return QVariant();
return ConfigManagerInterface::getInstance()->getOption(name);
}
void ScriptObject::registerAsBackgroundScript(const QString &name)
{
static QMap<QString, QPointer<ScriptObject> > backgroundScripts;
QString realName = name.isEmpty() ? getScriptHash() : name;
if (!backgroundScripts.value(realName, QPointer<ScriptObject>(nullptr)).isNull())
delete backgroundScripts.value(realName, QPointer<ScriptObject>(nullptr)).data();
backgroundScripts.insert(realName, this);
backgroundScript = true;
}
QWidget *ScriptObject::createUI(const QString &path, QWidget *parent)
{
QFile f(path);
if (!f.open(QFile::ReadOnly)) return nullptr;
return QUiLoader().load(&f, parent);
}
QWidget *ScriptObject::createUIFromString(const QString &str, QWidget *parent)
{
QByteArray ba(str.toLocal8Bit());
QBuffer buffer(&ba);
return QUiLoader().load(&buffer, parent);
}
QByteArray SubScriptObject::getScriptHash()
{
Q_ASSERT(script);
return script->getScriptHash();
}
static QHash<QString, QVariant> globals;
bool SubScriptObject::hasGlobal(const QString &name)
{
return globals.contains(getScriptHash() + "/" + name);
}
void SubScriptObject::setGlobal(const QString &name, const QVariant &value)
{
globals.insert(getScriptHash() + "/" + name, value);
}
QVariant SubScriptObject::getGlobal(const QString &name)
{
return globals.value(getScriptHash() + "/" + name, QVariant());
}
static QHash<QString, QVariant *> persistents;
bool SubScriptObject::hasPersistent(const QString &name)
{
QString id = getScriptHash() + "/" + name;
if (persistents.contains(id)) return true;
return ConfigManagerInterface::getInstance()->existsOption("Script Data/" + id);
}
void SubScriptObject::setPersistent(const QString &name, const QVariant &value)
{
QString id = getScriptHash() + "/" + name;
if (!persistents.contains(id)) {
QVariant *v = new QVariant;
persistents.insert(id, v);
ConfigManagerInterface::getInstance()->registerOption("Script Data/" + id, v);
}
*persistents.value(id) = value;
}
QVariant SubScriptObject::getPersistent(const QString &name)
{
if (!hasPersistent(name)) return QVariant();
QString id = getScriptHash() + "/" + name;
if (!persistents.contains(id)) {
QVariant *v = new QVariant;
persistents.insert(id, v);
ConfigManagerInterface::getInstance()->registerOption("Script Data/" + id, v);
}
return *persistents.value(id);
}
bool ScriptObject::hasReadPrivileges()
{
if (readSecurityMode == 0)
return false;
if (readSecurityMode == 2
|| privilegedReadScripts.contains(getScriptHash())
|| privilegedWriteScripts.contains(getScriptHash()))
return true;
return false;
}
bool ScriptObject::fileExists(const QString &fn)
{
QFileInfo fi(fn);
return fi.exists();
}
bool ScriptObject::hasWritePrivileges()
{
if (writeSecurityMode == 0)
return false;
if (writeSecurityMode == 2
|| privilegedWriteScripts.contains(getScriptHash()))
return true;
return false;
}
QByteArray ScriptObject::getScriptHash()
{
if (scriptHash.isEmpty())
scriptHash = QCryptographicHash::hash(script.toLatin1(), QCryptographicHash::Sha1).toHex();
return scriptHash;
}
void ScriptObject::registerAllowedWrite()
{
QByteArray hash = getScriptHash();
if (!privilegedWriteScripts.contains(hash))
privilegedWriteScripts.append(hash);
}
bool ScriptObject::needWritePrivileges(const QString &fn, const QString &param)
{
if (writeSecurityMode == 0) return false;
if (hasWritePrivileges()) return true;
int t = QMessageBox::question(nullptr, "TeXstudio script watcher",
tr("The current script has requested to enter privileged write mode and call following function:\n%1\n\nDo you trust this script?").arg(fn + "(\"" + param + "\")"), tr("Yes, allow this call"),
tr("Yes, allow all calls it will ever make"), tr("No, abort the call"), 0, 2);
if (t == 0) return true; //only now
if (t != 1) return false;
privilegedWriteScripts.append(getScriptHash());
return true;
}
bool ScriptObject::needReadPrivileges(const QString &fn, const QString &param)
{
if (readSecurityMode == 0) return false;
if (hasReadPrivileges()) return true;
int t = QMessageBox::question(nullptr, "TeXstudio script watcher",
tr("The current script has requested to enter privileged mode and read the following value:\n%1\n\nDo you trust this script?").arg(fn + "(\"" + param + "\")"), tr("Yes, allow this reading"),
tr("Yes, grant permanent read access to everything"), tr("No, abort the call"), 0, 2);
if (t == 0) return true; //only now
if (t != 1) return false;
privilegedReadScripts.append(getScriptHash());
return true;
}
SubScriptObject *ScriptObject::getScript()
{
return &subScriptObject;
}
Texstudio *ScriptObject::getApp()
{
return app;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xmrzh/texstudio.git
git@gitee.com:xmrzh/texstudio.git
xmrzh
texstudio
texstudio
master

搜索帮助