Skip to content

Commit 6bd1d20

Browse files
committed
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.
1 parent e2c3b18 commit 6bd1d20

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

doc/release-notes-26628.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
JSON-RPC
2+
---
3+
4+
The JSON-RPC server now rejects requests where a parameter is specified multiple times with the same name, instead of silently overwriting earlier parameter values with later ones. (#26628)

src/rpc/server.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,10 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
399399
const std::vector<UniValue>& values = in.params.getValues();
400400
std::unordered_map<std::string, const UniValue*> argsIn;
401401
for (size_t i=0; i<keys.size(); ++i) {
402-
argsIn[keys[i]] = &values[i];
402+
auto [_, inserted] = argsIn.emplace(keys[i], &values[i]);
403+
if (!inserted) {
404+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + keys[i] + " specified multiple times");
405+
}
403406
}
404407
// Process expected parameters. If any parameters were left unspecified in
405408
// the request before a parameter that was specified, null values need to be

src/test/rpc_tests.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ BOOST_AUTO_TEST_CASE(rpc_namedparams)
8989
// Make sure named arguments are transformed into positional arguments in correct places separated by nulls
9090
BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg2": 2, "arg4": 4})"), arg_names).write(), "[null,2,null,4]");
9191

92-
// Make sure later named argument value silently overwrites earlier values
93-
BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg2": 2, "arg2": 4})"), arg_names).write(), "[null,4]");
92+
// Make sure named argument specified multiple times raises an exception
93+
BOOST_CHECK_EXCEPTION(TransformParams(JSON(R"({"arg2": 2, "arg2": 4})"), arg_names), UniValue,
94+
HasJSON(R"({"code":-8,"message":"Parameter arg2 specified multiple times"})"));
9495

9596
// Make sure named and positional arguments can be combined.
9697
BOOST_CHECK_EQUAL(TransformParams(JSON(R"({"arg5": 5, "args": [1, 2], "arg4": 4})"), arg_names).write(), "[1,2,null,4,5]");

0 commit comments

Comments
 (0)