| 174 | */ |
| 175 | |
| 176 | bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const WalletModel* wallet_model) |
| 177 | { |
| 178 | std::vector< std::vector<std::string> > stack; |
| 179 | stack.push_back(std::vector<std::string>()); |
| 180 | |
| 181 | enum CmdParseState |
| 182 | { |
| 183 | STATE_EATING_SPACES, |
| 184 | STATE_EATING_SPACES_IN_ARG, |
| 185 | STATE_EATING_SPACES_IN_BRACKETS, |
| 186 | STATE_ARGUMENT, |
| 187 | STATE_SINGLEQUOTED, |
| 188 | STATE_DOUBLEQUOTED, |
| 189 | STATE_ESCAPE_OUTER, |
| 190 | STATE_ESCAPE_DOUBLEQUOTED, |
| 191 | STATE_COMMAND_EXECUTED, |
| 192 | STATE_COMMAND_EXECUTED_INNER |
| 193 | } state = STATE_EATING_SPACES; |
| 194 | std::string curarg; |
| 195 | UniValue lastResult; |
| 196 | unsigned nDepthInsideSensitive = 0; |
| 197 | size_t filter_begin_pos = 0, chpos; |
| 198 | std::vector<std::pair<size_t, size_t>> filter_ranges; |
| 199 | |
| 200 | auto add_to_current_stack = [&](const std::string& strArg) { |
| 201 | if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) { |
| 202 | nDepthInsideSensitive = 1; |
| 203 | filter_begin_pos = chpos; |
| 204 | } |
| 205 | // Make sure stack is not empty before adding something |
| 206 | if (stack.empty()) { |
| 207 | stack.push_back(std::vector<std::string>()); |
| 208 | } |
| 209 | stack.back().push_back(strArg); |
| 210 | }; |
| 211 | |
| 212 | auto close_out_params = [&]() { |
| 213 | if (nDepthInsideSensitive) { |
| 214 | if (!--nDepthInsideSensitive) { |
| 215 | assert(filter_begin_pos); |
| 216 | filter_ranges.push_back(std::make_pair(filter_begin_pos, chpos)); |
| 217 | filter_begin_pos = 0; |
| 218 | } |
| 219 | } |
| 220 | stack.pop_back(); |
| 221 | }; |
| 222 | |
| 223 | std::string strCommandTerminated = strCommand; |
| 224 | if (strCommandTerminated.back() != '\n') |
| 225 | strCommandTerminated += "\n"; |
| 226 | for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos) |
| 227 | { |
| 228 | char ch = strCommandTerminated[chpos]; |
| 229 | switch(state) |
| 230 | { |
| 231 | case STATE_COMMAND_EXECUTED_INNER: |
| 232 | case STATE_COMMAND_EXECUTED: |
| 233 | { |
nothing calls this directly
no test coverage detected