Obsolete command-string parsing QProcess::start/execute overloads
The command string parsing covers only simple quoting patterns, while users tend to expect something that is in line with their shell. The overloads that take a QStringList are the recommended APIs to use anyway, so exposing the splitting method as a static function for which we document the exact behavior allows callers to post-process the QStringList, before calling the preferred overloads. [ChangeLog][QtCore][QProcess] Overloads of start/execute/startDatached that parse a single command string into program and arguments have been marked as deprecated. A static helper splitCommand has been added to construct a QStringList from a command string. Change-Id: Ie91fcfb5eae6a52e5065efc60d2d9e068d20869d Fixes: QTBUG-80640 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
This commit is contained in:
parent
adfd0914e3
commit
92eea63349
@ -2246,8 +2246,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
|
|||||||
startProcess();
|
startProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.15
|
||||||
|
|
||||||
static QStringList parseCombinedArgString(const QString &program)
|
Splits the string \a command into a list of tokens, and returns
|
||||||
|
the list.
|
||||||
|
|
||||||
|
Tokens with spaces can be surrounded by double quotes; three
|
||||||
|
consecutive double quotes represent the quote character itself.
|
||||||
|
*/
|
||||||
|
QStringList QProcess::splitCommand(const QString &command)
|
||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
QString tmp;
|
QString tmp;
|
||||||
@ -2257,13 +2265,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
|||||||
// handle quoting. tokens can be surrounded by double quotes
|
// handle quoting. tokens can be surrounded by double quotes
|
||||||
// "hello world". three consecutive double quotes represent
|
// "hello world". three consecutive double quotes represent
|
||||||
// the quote character itself.
|
// the quote character itself.
|
||||||
for (int i = 0; i < program.size(); ++i) {
|
for (int i = 0; i < command.size(); ++i) {
|
||||||
if (program.at(i) == QLatin1Char('"')) {
|
if (command.at(i) == QLatin1Char('"')) {
|
||||||
++quoteCount;
|
++quoteCount;
|
||||||
if (quoteCount == 3) {
|
if (quoteCount == 3) {
|
||||||
// third consecutive quote
|
// third consecutive quote
|
||||||
quoteCount = 0;
|
quoteCount = 0;
|
||||||
tmp += program.at(i);
|
tmp += command.at(i);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2272,13 +2280,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
|||||||
inQuote = !inQuote;
|
inQuote = !inQuote;
|
||||||
quoteCount = 0;
|
quoteCount = 0;
|
||||||
}
|
}
|
||||||
if (!inQuote && program.at(i).isSpace()) {
|
if (!inQuote && command.at(i).isSpace()) {
|
||||||
if (!tmp.isEmpty()) {
|
if (!tmp.isEmpty()) {
|
||||||
args += tmp;
|
args += tmp;
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp += program.at(i);
|
tmp += command.at(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!tmp.isEmpty())
|
if (!tmp.isEmpty())
|
||||||
@ -2288,6 +2296,7 @@ static QStringList parseCombinedArgString(const QString &program)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
\obsolete
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
Starts the command \a command in a new process.
|
Starts the command \a command in a new process.
|
||||||
@ -2324,11 +2333,13 @@ static QStringList parseCombinedArgString(const QString &program)
|
|||||||
list-based API. In these rare cases you need to use setProgram() and
|
list-based API. In these rare cases you need to use setProgram() and
|
||||||
setNativeArguments() instead of this function.
|
setNativeArguments() instead of this function.
|
||||||
|
|
||||||
|
\sa splitCommand()
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
||||||
void QProcess::start(const QString &command, OpenMode mode)
|
void QProcess::start(const QString &command, OpenMode mode)
|
||||||
{
|
{
|
||||||
QStringList args = parseCombinedArgString(command);
|
QStringList args = splitCommand(command);
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
Q_D(QProcess);
|
Q_D(QProcess);
|
||||||
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
|
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
|
||||||
@ -2493,6 +2504,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
\obsolete
|
||||||
\overload
|
\overload
|
||||||
|
|
||||||
Starts the program \a command in a new process, waits for it to finish,
|
Starts the program \a command in a new process, waits for it to finish,
|
||||||
@ -2503,7 +2515,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
|
|||||||
After the \a command string has been split and unquoted, this function
|
After the \a command string has been split and unquoted, this function
|
||||||
behaves like the overload which takes the arguments as a string list.
|
behaves like the overload which takes the arguments as a string list.
|
||||||
|
|
||||||
\sa start()
|
\sa start(), splitCommand()
|
||||||
*/
|
*/
|
||||||
int QProcess::execute(const QString &command)
|
int QProcess::execute(const QString &command)
|
||||||
{
|
{
|
||||||
@ -2559,6 +2571,7 @@ bool QProcess::startDetached(const QString &program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
\obsolete
|
||||||
\overload startDetached()
|
\overload startDetached()
|
||||||
|
|
||||||
Starts the command \a command in a new process, and detaches from it.
|
Starts the command \a command in a new process, and detaches from it.
|
||||||
@ -2569,11 +2582,11 @@ bool QProcess::startDetached(const QString &program,
|
|||||||
After the \a command string has been split and unquoted, this function
|
After the \a command string has been split and unquoted, this function
|
||||||
behaves like the overload which takes the arguments as a string list.
|
behaves like the overload which takes the arguments as a string list.
|
||||||
|
|
||||||
\sa start(const QString &command, QIODevice::OpenMode mode)
|
\sa start(const QString &command, QIODevice::OpenMode mode), splitCommand()
|
||||||
*/
|
*/
|
||||||
bool QProcess::startDetached(const QString &command)
|
bool QProcess::startDetached(const QString &command)
|
||||||
{
|
{
|
||||||
QStringList args = parseCombinedArgString(command);
|
QStringList args = splitCommand(command);
|
||||||
if (args.isEmpty())
|
if (args.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -160,7 +160,13 @@ public:
|
|||||||
|
|
||||||
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
|
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
|
||||||
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 15)
|
||||||
|
QT_DEPRECATED_X(
|
||||||
|
"Use QProcess::start(const QString &program, const QStringList &arguments,"
|
||||||
|
"OpenMode mode = ReadWrite) instead"
|
||||||
|
)
|
||||||
void start(const QString &command, OpenMode mode = ReadWrite);
|
void start(const QString &command, OpenMode mode = ReadWrite);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void start(OpenMode mode = ReadWrite);
|
void start(OpenMode mode = ReadWrite);
|
||||||
bool startDetached(qint64 *pid = nullptr);
|
bool startDetached(qint64 *pid = nullptr);
|
||||||
@ -250,8 +256,12 @@ public:
|
|||||||
bool atEnd() const override; // ### Qt6: remove trivial override
|
bool atEnd() const override; // ### Qt6: remove trivial override
|
||||||
|
|
||||||
static int execute(const QString &program, const QStringList &arguments);
|
static int execute(const QString &program, const QStringList &arguments);
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 15)
|
||||||
|
QT_DEPRECATED_X(
|
||||||
|
"Use QProcess::execute(const QString &program, const QStringList &arguments) instead"
|
||||||
|
)
|
||||||
static int execute(const QString &command);
|
static int execute(const QString &command);
|
||||||
|
#endif
|
||||||
static bool startDetached(const QString &program, const QStringList &arguments,
|
static bool startDetached(const QString &program, const QStringList &arguments,
|
||||||
const QString &workingDirectory
|
const QString &workingDirectory
|
||||||
#if defined(Q_QDOC)
|
#if defined(Q_QDOC)
|
||||||
@ -261,12 +271,19 @@ public:
|
|||||||
#if !defined(Q_QDOC)
|
#if !defined(Q_QDOC)
|
||||||
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
|
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
|
||||||
#endif
|
#endif
|
||||||
|
#if QT_DEPRECATED_SINCE(5, 15)
|
||||||
|
QT_DEPRECATED_X(
|
||||||
|
"Use QProcess::startDetached(const QString &program, const QStringList &arguments) instead"
|
||||||
|
)
|
||||||
static bool startDetached(const QString &command);
|
static bool startDetached(const QString &command);
|
||||||
|
#endif
|
||||||
|
|
||||||
static QStringList systemEnvironment();
|
static QStringList systemEnvironment();
|
||||||
|
|
||||||
static QString nullDevice();
|
static QString nullDevice();
|
||||||
|
|
||||||
|
static QStringList splitCommand(const QString &command);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void terminate();
|
void terminate();
|
||||||
void kill();
|
void kill();
|
||||||
|
Loading…
Reference in New Issue
Block a user