From 127d1fd9e75d33f1a6a4cd4d30c259b00686c4ff Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Fri, 13 Mar 2009 19:05:54 +0100 Subject: [PATCH] ExecWrapper tweaks We now handle params for scripts sanely, plus we refuse to execute ../ in script names to avoid breaking out of our scripts jail. --- src/client/clientuserinputhandler.cpp | 13 ++------- src/client/execwrapper.cpp | 40 +++++++++++++++++++-------- src/client/execwrapper.h | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/client/clientuserinputhandler.cpp b/src/client/clientuserinputhandler.cpp index a02bc189..610a7021 100644 --- a/src/client/clientuserinputhandler.cpp +++ b/src/client/clientuserinputhandler.cpp @@ -67,15 +67,6 @@ void ClientUserInputHandler::handleUserInput(const BufferInfo &bufferInfo, const } void ClientUserInputHandler::handleExec(const BufferInfo &bufferInfo, const QString &execString) { - QString script; - QStringList params; - if(execString.contains(' ')) { - script = execString.section(' ', 0, 0); - params = execString.section(' ', 1).trimmed().split(' '); // FIXME handle args properly, including quoted strings etc - } else - script = execString; - - ExecWrapper *exec = new ExecWrapper(this); - exec->start(bufferInfo, script, params); - + ExecWrapper *exec = new ExecWrapper(this); // gets suicidal when it's done + exec->start(bufferInfo, execString); } diff --git a/src/client/execwrapper.cpp b/src/client/execwrapper.cpp index b6dfc98d..24b5c842 100644 --- a/src/client/execwrapper.cpp +++ b/src/client/execwrapper.cpp @@ -36,18 +36,34 @@ ExecWrapper::ExecWrapper(QObject* parent) : QObject(parent) { connect(this, SIGNAL(stderr(QString)), SLOT(postStderr(QString))); } -void ExecWrapper::start(const BufferInfo &info, const QString &scriptName, const QStringList& params) { +void ExecWrapper::start(const BufferInfo &info, const QString &command) { _bufferInfo = info; - _scriptName = scriptName; - foreach(QString scriptDir, Quassel::scriptDirPaths()) { - QString fileName = scriptDir + '/' + scriptName; - if(!QFile::exists(fileName)) - continue; - _process.start(fileName, params); - return; + QString params; + + QRegExp rx("^\\s*(\\S+)(\\s+(.*))?$"); + if(!rx.exactMatch(command)) { + emit stderr(tr("Invalid command string for /exec: %1").arg(command)); + } else { + _scriptName = rx.cap(1); + params = rx.cap(3); } - emit stderr(tr("Could not find script \"%1\"").arg(scriptName)); - deleteLater(); + + // Make sure we don't execute something outside a script dir + if(_scriptName.startsWith('/') || _scriptName.contains("../")) + emit stderr(tr("Name \"%1\" is invalid: / or ../ are not allowed!").arg(_scriptName)); + + else { + foreach(QString scriptDir, Quassel::scriptDirPaths()) { + QString fileName = scriptDir + _scriptName; + if(!QFile::exists(fileName)) + continue; + _process.start(fileName + ' ' + params); + return; + } + emit stderr(tr("Could not find script \"%1\"").arg(_scriptName)); + } + + deleteLater(); // self-destruct } void ExecWrapper::postStdout(const QString &msg) { @@ -78,6 +94,8 @@ void ExecWrapper::processFinished(int exitCode, QProcess::ExitStatus status) { void ExecWrapper::processError(QProcess::ProcessError error) { emit stderr(tr("Script \"%1\" caused error %2.").arg(_scriptName).arg(error)); + if(_process.state() != QProcess::Running) + deleteLater(); } void ExecWrapper::processReadStdout() { @@ -93,7 +111,7 @@ void ExecWrapper::processReadStderr() { _stderrBuffer.append(_process.readAllStandardError()); int idx; while((idx = _stderrBuffer.indexOf('\n')) >= 0) { - emit stdout(_stderrBuffer.left(idx)); + emit stderr(_stderrBuffer.left(idx)); _stderrBuffer = _stderrBuffer.mid(idx + 1); } } diff --git a/src/client/execwrapper.h b/src/client/execwrapper.h index b0c52bef..b8a73b74 100644 --- a/src/client/execwrapper.h +++ b/src/client/execwrapper.h @@ -32,7 +32,7 @@ public: ExecWrapper(QObject *parent = 0); public slots: - void start(const BufferInfo &info, const QString &scriptName, const QStringList ¶ms = QStringList()); + void start(const BufferInfo &info, const QString &command); signals: void stderr(const QString &errorMsg); -- 2.20.1