| 389 | } |
| 390 | |
| 391 | void handle_info_response(struct RedisModuleCtx *ctx, const char *szReply, size_t len, const char *command) { |
| 392 | |
| 393 | #define SAFETY_CHECK_POINTER(_p) ((_p) < (szReply + len)) |
| 394 | |
| 395 | // Parse the INFO reply string line by line |
| 396 | const char *pchLineStart = szReply; |
| 397 | |
| 398 | while (SAFETY_CHECK_POINTER(pchLineStart) && *pchLineStart != '\0') { |
| 399 | // Loop Each Line |
| 400 | const char *pchColon = pchLineStart; |
| 401 | while (SAFETY_CHECK_POINTER(pchColon) && *pchColon != ':' && *pchColon != '\r') { |
| 402 | ++pchColon; |
| 403 | } |
| 404 | if (!SAFETY_CHECK_POINTER(pchColon)) { |
| 405 | RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_WARNING, "Unexpected line termination when parsing response from %s command: \"%s\"", command, pchLineStart); |
| 406 | break; // BUG |
| 407 | } |
| 408 | const char *pchLineEnd = pchColon; |
| 409 | while (SAFETY_CHECK_POINTER(pchLineEnd) && *pchLineEnd != '\n') |
| 410 | ++pchLineEnd; |
| 411 | |
| 412 | std::string strCheck(pchLineStart, pchColon - pchLineStart); |
| 413 | if (strCheck.find("errorstat_") != std::string::npos) { |
| 414 | std::string remainder(pchColon + 1, pchLineEnd - (pchColon + 1)); |
| 415 | handleErrorStatItem(ctx, strCheck, remainder); |
| 416 | } else if (std::regex_match(strCheck, g_replica_or_db_info_regex)) { |
| 417 | std::string remainder(pchColon + 1, pchLineEnd - (pchColon + 1)); |
| 418 | handleReplicaOrDbInfoItem(ctx, strCheck, remainder); |
| 419 | } else { |
| 420 | auto itr = g_mapInfoFields.find(strCheck); |
| 421 | if (itr != g_mapInfoFields.end()) { |
| 422 | // This is an info field we care about |
| 423 | if (itr->second.szAlternate != nullptr) |
| 424 | strCheck = itr->second.szAlternate; |
| 425 | handleStatItem(ctx, strCheck, itr->second, pchColon+1); |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | RedisModule_Log(ctx, REDISMODULE_LOGLEVEL_DEBUG, "INFO response line: \"%s\"", std::string(pchLineStart, pchLineEnd - pchLineStart).c_str()); |
| 430 | pchLineStart = pchLineEnd + 1; // start of next line, if we're over the loop will catch it |
| 431 | } |
| 432 | |
| 433 | #undef SAFETY_CHECK_POINTER |
| 434 | } |
| 435 | |
| 436 | void handle_cluster_nodes_response(struct RedisModuleCtx *ctx, const char *szReply, size_t len) { |
| 437 | #define SAFETY_CHECK_POINTER(_p) ((_p) < (szReply + len)) |
no test coverage detected