diff --git a/src/bin/pg_autoctl/ipaddr.c b/src/bin/pg_autoctl/ipaddr.c index 7f61d49f5..5c6dff480 100644 --- a/src/bin/pg_autoctl/ipaddr.c +++ b/src/bin/pg_autoctl/ipaddr.c @@ -537,9 +537,11 @@ findHostnameLocalAddress(const char *hostname, char *localIpAddress, int size) size) == NULL) { log_warn("Failed to determine local ip address: %m"); + freeifaddrs(ifaddrList); return false; } + freeifaddrs(ifaddrList); return true; } } @@ -565,15 +567,18 @@ findHostnameLocalAddress(const char *hostname, char *localIpAddress, int size) { /* check size >= INET6_ADDRSTRLEN */ log_warn("Failed to determine local ip address: %m"); + freeifaddrs(ifaddrList); return false; } + freeifaddrs(ifaddrList); return true; } } } } + freeifaddrs(ifaddrList); freeaddrinfo(dns_lookup_addr); return false; } diff --git a/src/bin/pg_autoctl/monitor.c b/src/bin/pg_autoctl/monitor.c index 04c6dc746..8e473ee9f 100644 --- a/src/bin/pg_autoctl/monitor.c +++ b/src/bin/pg_autoctl/monitor.c @@ -416,6 +416,10 @@ monitor_print_nodes_as_json(Monitor *monitor, char *formation, int groupId) log_error("Failed to get the nodes from the monitor while running " "\"%s\" with formation %s and group %d", sql, formation, groupId); + if (context.strVal) + { + free(context.strVal); + } return false; } @@ -429,10 +433,15 @@ monitor_print_nodes_as_json(Monitor *monitor, char *formation, int groupId) "it returned an unexpected result. " "See previous line for details.", sql, formation, groupId); + if (context.strVal) + { + free(context.strVal); + } return false; } fformat(stdout, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -559,6 +568,10 @@ monitor_print_other_nodes_as_json(Monitor *monitor, { log_error("Failed to get the other nodes from the monitor while running " "\"%s\" with node id %d", sql, myNodeId); + if (context.strVal) + { + free(context.strVal); + } return false; } @@ -571,10 +584,15 @@ monitor_print_other_nodes_as_json(Monitor *monitor, "\"%s\" with node id %d because it returned an " "unexpected result. See previous line for details.", sql, myNodeId); + if (context.strVal) + { + free(context.strVal); + } return false; } fformat(stdout, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -1977,10 +1995,15 @@ monitor_print_state_as_json(Monitor *monitor, char *formation, int group) { log_error("Failed to parse current state from the monitor"); log_error("%s", context.strVal); + if (context.strVal) + { + free(context.strVal); + } return false; } fformat(stdout, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -2142,10 +2165,15 @@ monitor_print_last_events_as_json(Monitor *monitor, { log_error("Failed to parse %d last events from the monitor", count); log_error("%s", context.strVal); + if (context.strVal) + { + free(context.strVal); + } return false; } fformat(stream, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -2379,6 +2407,10 @@ monitor_formation_uri(Monitor *monitor, if (!context.parsedOk) { /* errors have already been logged */ + if (context.strVal) + { + free(context.strVal); + } return false; } @@ -2386,10 +2418,15 @@ monitor_formation_uri(Monitor *monitor, { log_error("Formation \"%s\" currently has no nodes in group 0", formation); + if (context.strVal) + { + free(context.strVal); + } return false; } strlcpy(connectionString, context.strVal, size); + free(context.strVal); /* disconnect from PostgreSQL now */ pgsql_finish(&monitor->pgsql); @@ -2490,6 +2527,10 @@ monitor_print_every_formation_uri_as_json(Monitor *monitor, if (!context.parsedOk) { /* errors have already been logged */ + if (context.strVal) + { + free(context.strVal); + } return false; } @@ -2497,6 +2538,7 @@ monitor_print_every_formation_uri_as_json(Monitor *monitor, pgsql_finish(&monitor->pgsql); fformat(stream, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -2752,10 +2794,15 @@ monitor_print_formation_settings_as_json(Monitor *monitor, char *formation) { log_error("Failed to parse formation settings from the monitor " "for formation \"%s\"", formation); + if (context.strVal) + { + free(context.strVal); + } return false; } fformat(stdout, "%s\n", context.strVal); + free(context.strVal); return true; } @@ -2794,6 +2841,10 @@ monitor_synchronous_standby_names(Monitor *monitor, log_error("Failed to get the synchronous_standby_names setting value " " from the monitor for formation %s and group %d", formation, groupId); + if (context.strVal) + { + free(context.strVal); + } return false; } @@ -2803,10 +2854,15 @@ monitor_synchronous_standby_names(Monitor *monitor, " from the monitor for formation %s and group %d," "see above for details", formation, groupId); + if (context.strVal) + { + free(context.strVal); + } return false; } strlcpy(synchronous_standby_names, context.strVal, size); + free(context.strVal); return true; } diff --git a/src/bin/pg_autoctl/parsing.c b/src/bin/pg_autoctl/parsing.c index 386e77d58..084a6d595 100644 --- a/src/bin/pg_autoctl/parsing.c +++ b/src/bin/pg_autoctl/parsing.c @@ -267,6 +267,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, if (json_type(json) != JSONObject) { log_error("Failed to parse JSON notification message: \"%s\"", message); + json_value_free(json); return false; } @@ -276,6 +277,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse JSOBJ notification state message: " "jsobj object type is not \"state\" as expected"); + json_value_free(json); return false; } @@ -285,6 +287,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse formation in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } strlcpy(nodeState->formation, str, sizeof(nodeState->formation)); @@ -301,6 +304,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse node name in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } strlcpy(nodeState->node.name, str, sizeof(nodeState->node.name)); @@ -311,6 +315,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse node host in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } strlcpy(nodeState->node.host, str, sizeof(nodeState->node.host)); @@ -324,6 +329,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse reportedState in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } nodeState->reportedState = NodeStateFromString(str); @@ -334,6 +340,7 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse goalState in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } nodeState->goalState = NodeStateFromString(str); @@ -356,9 +363,11 @@ parse_state_notification_message(CurrentNodeState *nodeState, { log_error("Failed to parse health in JSON " "notification message \"%s\"", message); + json_value_free(json); return false; } + json_value_free(json); return true; } @@ -761,6 +770,8 @@ parseNodesArray(const char *nodesJSON, "[{node_id:number, node_name:string, " "node_host:string, node_port:number, node_lsn:string, " "node_is_primary:boolean}, ...]"); + json_value_free(template); + json_value_free(json); return false; } @@ -773,6 +784,8 @@ parseNodesArray(const char *nodesJSON, "%d nodes: pg_autoctl supports up to %d nodes", len, NODE_ARRAY_MAX_COUNT); + json_value_free(template); + json_value_free(json); return false; } @@ -812,6 +825,8 @@ parseNodesArray(const char *nodesJSON, if (!parseLSN(node->lsn, &lsn)) { log_error("Failed to parse nodes array LSN value \"%s\"", node->lsn); + json_value_free(template); + json_value_free(json); return false; } @@ -825,6 +840,8 @@ parseNodesArray(const char *nodesJSON, { log_error("Failed to parse nodes array: more than one node " "is listed with \"node_is_primary\" true."); + json_value_free(template); + json_value_free(json); return false; } } @@ -832,6 +849,9 @@ parseNodesArray(const char *nodesJSON, ++nodesArrayIndex; } + json_value_free(template); + json_value_free(json); + /* now ensure the array is sorted by nodeId */ (void) pg_qsort(nodesArray->nodes, nodesArray->count, diff --git a/src/bin/pg_autoctl/pgsetup.c b/src/bin/pg_autoctl/pgsetup.c index fa9f9d38d..42e6b5de8 100644 --- a/src/bin/pg_autoctl/pgsetup.c +++ b/src/bin/pg_autoctl/pgsetup.c @@ -460,15 +460,20 @@ get_pgpid(PostgresSetup *pgSetup, bool pgIsNotRunningIsOk) { /* yeah, that happens (race condition, kind of) */ log_debug("The PID file \"%s\" is empty", pidfile); + free(contents); return false; } else if (splitLines(contents, lines, 1) != 1 || !stringToInt(lines[0], &pid)) { log_warn("Invalid data in PID file \"%s\"", pidfile); + free(contents); return false; } + free(contents); + contents = NULL; + /* postmaster PID (or negative of a standalone backend's PID) */ if (pid < 0) { @@ -764,6 +769,7 @@ pg_setup_get_local_connection_string(PostgresSetup *pgSetup, !get_env_copy("PG_REGRESS_SOCK_DIR", pg_regress_sock_dir, MAXPGPATH)) { /* errors have already been logged */ + destroyPQExpBuffer(connStringBuffer); return false; } @@ -816,8 +822,11 @@ pg_setup_get_local_connection_string(PostgresSetup *pgSetup, "long, pg_autoctl only supports connection strings up to " " %d bytes", connStringBuffer->data, connStringBuffer->len, MAXCONNINFO); + destroyPQExpBuffer(connStringBuffer); + return false; } + destroyPQExpBuffer(connStringBuffer); return true; }