Skip to content

Commit

Permalink
De-quote fully quoted arguments when it's unnecessary
Browse files Browse the repository at this point in the history
Some Flashpoint service arguments are fully quoted even though they
don't need to be (which works for the regular launcher since it uses the
shell to start most child processes, unlike CLIFp), which creates issues
when starting such a process via the OS directly and not a shell, as the
quotes will be escaped and included as part of the argument, when the FP
configure clearly just intended the argument to be quoted.
  • Loading branch information
oblivioncth committed Nov 18, 2023
1 parent 8c8de04 commit ac4c5ad
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
41 changes: 41 additions & 0 deletions app/src/task/t-exec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,46 @@ QString TExec::createEscapedShellArguments()
return escapedArgs;
}

void TExec::removeRedundantFullQuotes(QProcess& process)
{
/* Sometimes service arguments have been observed to be "pre-prepped" for shell use by being fully quoted even
* when not needed. This is an issue since QProcess will quote non-native arguments automatically when not using
* the shell, which we don't for most things other than scripts, so we have to remove such quotes here. Note this
* affects all execution tasks though, not just services.
*/
QStringList args = process.arguments();
for(QString& a : args)
{
// Determine if arg is simply fully quoted
if(a.size() < 3 || (a.front() != '"' && a.back() != '"')) // min 3 maintains " and "" which theoretically could be significant
continue;

QStringView inner(a.cbegin() + 1, a.cend() - 1);
bool redundant = true;
bool escaped = false;
for(const QChar& c : inner)
{
if(c == '\\')
escaped = true;
else if(c == '"' && !escaped)
{
redundant = false;
break;
}
else
escaped = false;
}

if(redundant)
{
emit eventOccurred(NAME, LOG_EVENT_REMOVED_REDUNDANT_QUOTES.arg(a));
a = inner.toString();
}
}

process.setArguments(args);
}

TExecError TExec::cleanStartProcess(QProcess* process)
{
// Note directories
Expand Down Expand Up @@ -185,6 +225,7 @@ void TExec::perform()

// Prepare process object
QProcess* taskProcess = prepareProcess(QFileInfo(execPath));
removeRedundantFullQuotes(*taskProcess);
logPreparedProcess(taskProcess);

// Set common process properties
Expand Down
2 changes: 2 additions & 0 deletions app/src/task/t-exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class TExec : public Task

// Logging - Process Prep
static inline const QString LOG_EVENT_PREPARING_PROCESS = u"Preparing %1 process '%2' (%3)..."_s;
static inline const QString LOG_EVENT_REMOVED_REDUNDANT_QUOTES = u"Removed unnecessary outer quotes on argument (%1)."_s;
static inline const QString LOG_EVENT_FINAL_EXECUTABLE = u"Final Executable: %1"_s;
static inline const QString LOG_EVENT_FINAL_PARAMETERS = u"Final Parameters: %1"_s;

Expand Down Expand Up @@ -133,6 +134,7 @@ class TExec : public Task
QString escapeForShell(const QString& argStr);
QString createEscapedShellArguments();
QProcess* prepareProcess(const QFileInfo& execInfo);
void removeRedundantFullQuotes(QProcess& process);
TExecError cleanStartProcess(QProcess* process);

// Logging
Expand Down

0 comments on commit ac4c5ad

Please sign in to comment.