@@ -113,11 +113,63 @@ std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
113113 return ParseHexV(find_value(o, strKey), strKey);
114114}
115115
116+ namespace {
117+
118+ /**
119+ * Quote an argument for shell.
120+ *
121+ * @note This is intended for help, not for security-sensitive purposes.
122+ */
123+ std::string ShellQuote(const std::string& s)
124+ {
125+ std::string result;
126+ result.reserve(s.size() * 2);
127+ for (const char ch: s) {
128+ if (ch == '\'') {
129+ result += "'\''";
130+ } else {
131+ result += ch;
132+ }
133+ }
134+ return "'" + result + "'";
135+ }
136+
137+ /**
138+ * Shell-quotes the argument if it needs quoting, else returns it literally, to save typing.
139+ *
140+ * @note This is intended for help, not for security-sensitive purposes.
141+ */
142+ std::string ShellQuoteIfNeeded(const std::string& s)
143+ {
144+ for (const char ch: s) {
145+ if (ch == ' ' || ch == '\'' || ch == '"') {
146+ return ShellQuote(s);
147+ }
148+ }
149+
150+ return s;
151+ }
152+
153+ }
154+
116155std::string HelpExampleCli(const std::string& methodname, const std::string& args)
117156{
118157 return "> bitcoin-cli " + methodname + " " + args + "\n";
119158}
120159
160+ std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args)
161+ {
162+ std::string result = "> bitcoin-cli -named " + methodname;
163+ for (const auto& argpair: args) {
164+ const auto& value = argpair.second.isStr()
165+ ? argpair.second.get_str()
166+ : argpair.second.write();
167+ result += " " + argpair.first + "=" + ShellQuoteIfNeeded(value);
168+ }
169+ result += "\n";
170+ return result;
171+ }
172+
121173std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
122174{
123175 return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", "
0 commit comments