aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyan Ofsky <ryan@ofsky.org>2022-12-02 17:53:16 -0500
committerRyan Ofsky <ryan@ofsky.org>2022-12-02 17:53:16 -0500
commit6bd1d20b8cf27aa72ec2907342787e6fc9f94c50 (patch)
treeae6a0867a99e33740aef9450cfdda75912c051cb /src
parente2c3b18e671e347e422d696d1cbdd9f82b2ce468 (diff)
rpc: Make it an error server-side to specify same named parameter multiple times
Specifying same named parameter multiple times is still allowed by bitcoin-cli. The client implementation overwrites earlier option values with later ones before sending to server. This is tested by interface_bitcoin_cli.py Rationale for allowing client parameters to be specified multiple times in bitcoin-cli is that this behavior has been supported for a long time, and that when using the command line interactively, it can be convenient to override earlier option values with new values without having to go back and remove the old value. But for the RPC server, there isn't really a good use-case for earlier values to be discarded if multiple values are specified. JSON keys are generally supposed to be unique and if they aren't it's probably an indication of some problem generating the RPC request.
Diffstat (limited to 'src')
-rw-r--r--src/rpc/server.cpp5
-rw-r--r--src/test/rpc_tests.cpp5
2 files changed, 7 insertions, 3 deletions
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index f57133f75b..232e2119f1 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -399,7 +399,10 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
const std::vector<UniValue>& values = in.params.getValues();
std::unordered_map<std::string, const UniValue*> argsIn;
for (size_t i=0; i<keys.size(); ++i) {
- argsIn[keys[i]] = &values[i];
+ auto [_, inserted] = argsIn.emplace(keys[i], &values[i]);
+ if (!inserted) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + keys[i] + " specified multiple times");
+ }
}
// Process expected parameters. If any parameters were left unspecified in
// the request before a parameter that was specified, null values need to be
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 23e666bc45..a4d5a4b12c 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -89,8 +89,9 @@ BOOST_AUTO_TEST_CASE(rpc_namedparams)
// Make sure named arguments are transformed into positional arguments in correct places separated by nulls
BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg2": 2, "arg4": 4})"), arg_names).write(), "[null,2,null,4]");
- // Make sure later named argument value silently overwrites earlier values
- BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg2": 2, "arg2": 4})"), arg_names).write(), "[null,4]");
+ // Make sure named argument specified multiple times raises an exception
+ BOOST_CHECK_EXCEPTION(TransformParams(JSON(R"({"arg2": 2, "arg2": 4})"), arg_names), UniValue,
+ HasJSON(R"({"code":-8,"message":"Parameter arg2 specified multiple times"})"));
// Make sure named and positional arguments can be combined.
BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg5": 5, "args": [1, 2], "arg4": 4})"), arg_names).write(), "[1,2,null,4,5]");