Skip to content

Commit 390bd14

Browse files
committed
[Qt] Console: don't allow empty arguments when using the comma-syntax
1 parent 6a32c0f commit 390bd14

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

src/qt/rpcconsole.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string
138138
{
139139
STATE_EATING_SPACES,
140140
STATE_EATING_SPACES_IN_ARG,
141+
STATE_EATING_SPACES_IN_BRACKETS,
141142
STATE_ARGUMENT,
142143
STATE_SINGLEQUOTED,
143144
STATE_DOUBLEQUOTED,
@@ -222,13 +223,16 @@ bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string
222223
}
223224
case STATE_ARGUMENT: // In or after argument
224225
case STATE_EATING_SPACES_IN_ARG:
226+
case STATE_EATING_SPACES_IN_BRACKETS:
225227
case STATE_EATING_SPACES: // Handle runs of whitespace
226228
switch(ch)
227229
{
228230
case '"': state = STATE_DOUBLEQUOTED; break;
229231
case '\'': state = STATE_SINGLEQUOTED; break;
230232
case '\\': state = STATE_ESCAPE_OUTER; break;
231233
case '(': case ')': case '\n':
234+
if (state == STATE_EATING_SPACES_IN_ARG)
235+
throw std::runtime_error("Invalid Syntax");
232236
if (state == STATE_ARGUMENT)
233237
{
234238
if (ch == '(' && stack.size() && stack.back().size() > 0)
@@ -240,7 +244,7 @@ bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string
240244

241245
stack.back().push_back(curarg);
242246
curarg.clear();
243-
state = STATE_EATING_SPACES;
247+
state = STATE_EATING_SPACES_IN_BRACKETS;
244248
}
245249
if ((ch == ')' || ch == '\n') && stack.size() > 0)
246250
{
@@ -257,12 +261,20 @@ bool RPCConsole::RPCExecuteCommandLine(std::string &strResult, const std::string
257261
}
258262
break;
259263
case ' ': case ',': case '\t':
260-
if(state == STATE_ARGUMENT || (state == STATE_EATING_SPACES_IN_ARG && ch == ',')) // Space ends argument
264+
if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch == ',')
265+
throw std::runtime_error("Invalid Syntax");
266+
267+
else if(state == STATE_ARGUMENT) // Space ends argument
261268
{
262269
stack.back().push_back(curarg);
263270
curarg.clear();
264271
}
265-
state = (ch == ',' ? STATE_EATING_SPACES_IN_ARG : STATE_EATING_SPACES);
272+
if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch == ',')
273+
{
274+
state = STATE_EATING_SPACES_IN_ARG;
275+
break;
276+
}
277+
state = STATE_EATING_SPACES;
266278
break;
267279
default: curarg += ch; state = STATE_ARGUMENT;
268280
}

src/qt/test/rpcnestedtests.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "util.h"
1616

1717
#include <QDir>
18+
#include <QtGlobal>
1819

1920
#include <boost/filesystem.hpp>
2021

@@ -77,16 +78,6 @@ void RPCNestedTests::rpcNestedTests()
7778
RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo "); //whitespace at the end will be tolerated
7879
QVERIFY(result.substr(0,1) == "{");
7980

80-
#if QT_VERSION >= 0x050300
81-
// do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
82-
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
83-
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
84-
(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
85-
(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()()()")); //tolerate non command brackts
86-
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(True)"), UniValue); //invalid argument
87-
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "a(getblockchaininfo(True))"), UniValue); //method not found
88-
#endif
89-
9081
(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()[\"chain\"]")); //Quote path identifier are allowed, but look after a child contaning the quotes in the key
9182
QVERIFY(result == "null");
9283

@@ -113,8 +104,25 @@ void RPCNestedTests::rpcNestedTests()
113104
QVERIFY(result == "[\"abc\",\"abc\"]");
114105
RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc\t\tabc");
115106
QVERIFY(result == "[\"abc\",\"abc\"]");
116-
RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc,,abc");
117-
QVERIFY(result == "[\"abc\",\"\",\"abc\"]");
107+
RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc )");
108+
QVERIFY(result == "[\"abc\"]");
109+
RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest( abc )");
110+
QVERIFY(result == "[\"abc\"]");
111+
RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest( abc , cba )");
112+
QVERIFY(result == "[\"abc\",\"cba\"]");
113+
114+
#if QT_VERSION >= 0x050300
115+
// do the QVERIFY_EXCEPTION_THROWN checks only with Qt5.3 and higher (QVERIFY_EXCEPTION_THROWN was introduced in Qt5.3)
116+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() .\n"), std::runtime_error); //invalid syntax
117+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo() getblockchaininfo()"), std::runtime_error); //invalid syntax
118+
(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(")); //tolerate non closing brackets if we have no arguments
119+
(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo()()()")); //tolerate non command brackts
120+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "getblockchaininfo(True)"), UniValue); //invalid argument
121+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "a(getblockchaininfo(True))"), UniValue); //method not found
122+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest abc,,abc"), std::runtime_error); //don't tollerate empty arguments when using ,
123+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,abc)"), std::runtime_error); //don't tollerate empty arguments when using ,
124+
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
125+
#endif
118126

119127
delete pcoinsTip;
120128
delete pcoinsdbview;

0 commit comments

Comments
 (0)