aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2016-11-16 12:32:15 +0000
committerLuke Dashjr <luke-jr+git@utopios.org>2016-12-29 11:47:58 +0000
commitff77faf480cfaf8098cfa04af6cc17a75c19ba49 (patch)
tree7ea21627fa0385d5123a7b5d7144557f01e6d267
parenta79598ddf4bf35b934ed3513900f2a9fae0bff45 (diff)
Qt/RPCConsole: Use RPCParseCommandLine to perform command filtering
-rw-r--r--src/qt/rpcconsole.cpp77
1 files changed, 46 insertions, 31 deletions
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 63a23dc496..5cba588d0c 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -31,6 +31,7 @@
#include <QKeyEvent>
#include <QMenu>
+#include <QMessageBox>
#include <QScrollBar>
#include <QSettings>
#include <QSignalMapper>
@@ -74,16 +75,6 @@ const QStringList historyFilter = QStringList()
<< "walletpassphrasechange"
<< "encryptwallet";
-QString command_filter_sensitive_data(const QString cmd)
-{
- Q_FOREACH(QString unallowedCmd, historyFilter) {
- if (cmd.trimmed().startsWith(unallowedCmd)) {
- return unallowedCmd;
- }
- }
- return cmd;
-}
-
}
/* Object for executing console RPC commands in a separate thread.
@@ -175,13 +166,32 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
std::string curarg;
UniValue lastResult;
unsigned nDepthInsideSensitive = 0;
- size_t filter_begin_pos = 0;
+ size_t filter_begin_pos = 0, chpos;
std::vector<std::pair<size_t, size_t>> filter_ranges;
+ auto add_to_current_stack = [&](const std::string& curarg) {
+ if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(curarg), Qt::CaseInsensitive)) {
+ nDepthInsideSensitive = 1;
+ filter_begin_pos = chpos;
+ }
+ stack.back().push_back(curarg);
+ };
+
+ auto close_out_params = [&]() {
+ if (nDepthInsideSensitive) {
+ if (!--nDepthInsideSensitive) {
+ assert(filter_begin_pos);
+ filter_ranges.push_back(std::make_pair(filter_begin_pos, chpos));
+ filter_begin_pos = 0;
+ }
+ }
+ stack.pop_back();
+ };
+
std::string strCommandTerminated = strCommand;
if (strCommandTerminated.back() != '\n')
strCommandTerminated += "\n";
- for (size_t chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
+ for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
{
char ch = strCommandTerminated[chpos];
switch(state)
@@ -227,14 +237,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
breakParsing = false;
// pop the stack and return the result to the current command arguments
- if (nDepthInsideSensitive) {
- if (!--nDepthInsideSensitive) {
- assert(filter_begin_pos);
- filter_ranges.push_back(std::make_pair(filter_begin_pos, chpos));
- filter_begin_pos = 0;
- }
- }
- stack.pop_back();
+ close_out_params();
// don't stringify the json in case of a string to avoid doublequotes
if (lastResult.isStr())
@@ -246,7 +249,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
if (curarg.size())
{
if (stack.size())
- stack.back().push_back(curarg);
+ add_to_current_stack(curarg);
else
strResult = curarg;
}
@@ -283,7 +286,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
if (!stack.size())
throw std::runtime_error("Invalid Syntax");
- stack.back().push_back(curarg);
+ add_to_current_stack(curarg);
curarg.clear();
state = STATE_EATING_SPACES_IN_BRACKETS;
}
@@ -308,12 +311,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
else if(state == STATE_ARGUMENT) // Space ends argument
{
- // This is the only place where the method name should get pushed (as the first stack item)
- if ((!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(curarg), Qt::CaseInsensitive)) {
- nDepthInsideSensitive = 1;
- filter_begin_pos = chpos;
- }
- stack.back().push_back(curarg);
+ add_to_current_stack(curarg);
curarg.clear();
}
if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch == ',')
@@ -351,9 +349,13 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
}
}
if (pstrFilteredOut) {
+ if (STATE_COMMAND_EXECUTED == state) {
+ assert(!stack.empty());
+ close_out_params();
+ }
*pstrFilteredOut = strCommand;
for (auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
- pstrFilteredOut->replace(i->first, i->second - i->first, "...");
+ pstrFilteredOut->replace(i->first, i->second - i->first, "(…)");
}
}
switch(state) // final state
@@ -800,16 +802,29 @@ void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage)
void RPCConsole::on_lineEdit_returnPressed()
{
QString cmd = ui->lineEdit->text();
- ui->lineEdit->clear();
if(!cmd.isEmpty())
{
+ std::string strFilteredCmd;
+ try {
+ std::string dummy;
+ if (!RPCParseCommandLine(dummy, cmd.toStdString(), false, &strFilteredCmd)) {
+ // Failed to parse command, so we cannot even filter it for the history
+ throw std::runtime_error("Invalid command line");
+ }
+ } catch (const std::exception& e) {
+ QMessageBox::critical(this, "Error", QString("Error: ") + QString::fromStdString(e.what()));
+ return;
+ }
+
+ ui->lineEdit->clear();
+
cmdBeforeBrowsing = QString();
message(CMD_REQUEST, cmd);
Q_EMIT cmdRequest(cmd);
- cmd = command_filter_sensitive_data(cmd);
+ cmd = QString::fromStdString(strFilteredCmd);
// Remove command, if already in history
history.removeOne(cmd);