Skip to content

Commit 9048c58

Browse files
committed
Remove pointer cast in CRPCTable::dumpArgMap
CRPCTable::dumpArgMap currently works by casting RPC command unique_id integer field to a function pointer, and then calling the function. The unique_id field wasn't supposed to be used this way (it's meant to be used to detect RPC aliases), and this code segfaults in the rpc_help.py test in multiprocess PR bitcoin#10102 because wallet RPC functions aren't directly accessible from the node process. Fix this by adding a new GET_ARGS request mode to retrieve argument information similar to the way the GET_HELP mode retrieves help information.
1 parent 14f3d9b commit 9048c58

File tree

5 files changed

+20
-10
lines changed

5 files changed

+20
-10
lines changed

src/rpc/request.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class JSONRPCRequest
3434
UniValue id;
3535
std::string strMethod;
3636
UniValue params;
37-
enum Mode { EXECUTE, GET_HELP } mode = EXECUTE;
37+
enum Mode { EXECUTE, GET_HELP, GET_ARGS } mode = EXECUTE;
3838
std::string URI;
3939
std::string authUser;
4040
std::string peerAddr;

src/rpc/server.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static RPCHelpMan help()
149149
}
150150
if (strCommand == "dump_all_command_conversions") {
151151
// Used for testing only, undocumented
152-
return tableRPC.dumpArgMap();
152+
return tableRPC.dumpArgMap(jsonRequest);
153153
}
154154

155155
return tableRPC.help(strCommand, jsonRequest);
@@ -492,13 +492,18 @@ std::vector<std::string> CRPCTable::listCommands() const
492492
return commandList;
493493
}
494494

495-
UniValue CRPCTable::dumpArgMap() const
495+
UniValue CRPCTable::dumpArgMap(const JSONRPCRequest& args_request) const
496496
{
497+
JSONRPCRequest request(args_request);
498+
request.mode = JSONRPCRequest::GET_ARGS;
499+
497500
UniValue ret{UniValue::VARR};
498501
for (const auto& cmd : mapCommands) {
499-
for (const auto& c : cmd.second) {
500-
const auto help = RpcMethodFnType(c->unique_id)();
501-
help.AppendArgMap(ret);
502+
UniValue result;
503+
if (ExecuteCommands(cmd.second, request, result)) {
504+
for (const auto& values : result.getValues()) {
505+
ret.push_back(values);
506+
}
502507
}
503508
}
504509
return ret;

src/rpc/server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class CRPCTable
148148
/**
149149
* Return all named arguments that need to be converted by the client from string to another JSON type
150150
*/
151-
UniValue dumpArgMap() const;
151+
UniValue dumpArgMap(const JSONRPCRequest& request) const;
152152

153153
/**
154154
* Appends a CRPCCommand to the dispatch table.

src/rpc/util.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,9 @@ std::string RPCExamples::ToDescriptionString() const
478478

479479
UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request)
480480
{
481+
if (request.mode == JSONRPCRequest::GET_ARGS) {
482+
return GetArgMap();
483+
}
481484
/*
482485
* Check if the given request is valid according to this command or if
483486
* the user is asking for help information, and throw help when appropriate.
@@ -561,8 +564,9 @@ std::string RPCHelpMan::ToString() const
561564
return ret;
562565
}
563566

564-
void RPCHelpMan::AppendArgMap(UniValue& arr) const
567+
UniValue RPCHelpMan::GetArgMap() const
565568
{
569+
UniValue arr{UniValue::VARR};
566570
for (int i{0}; i < int(m_args.size()); ++i) {
567571
const auto& arg = m_args.at(i);
568572
std::vector<std::string> arg_names;
@@ -577,6 +581,7 @@ void RPCHelpMan::AppendArgMap(UniValue& arr) const
577581
arr.push_back(map);
578582
}
579583
}
584+
return arr;
580585
}
581586

582587
std::string RPCArg::GetFirstName() const

src/rpc/util.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,8 @@ class RPCHelpMan
337337

338338
UniValue HandleRequest(const JSONRPCRequest& request);
339339
std::string ToString() const;
340-
/** Append the named args that need to be converted from string to another JSON type */
341-
void AppendArgMap(UniValue& arr) const;
340+
/** Return the named args that need to be converted from string to another JSON type */
341+
UniValue GetArgMap() const;
342342
/** If the supplied number of args is neither too small nor too high */
343343
bool IsValidNumArgs(size_t num_args) const;
344344
std::vector<std::string> GetArgNames() const;

0 commit comments

Comments
 (0)