diff --git a/src/doveadm/client-connection-http.c b/src/doveadm/client-connection-http.c index 06bdb092ad..0cd0fdb142 100644 --- a/src/doveadm/client-connection-http.c +++ b/src/doveadm/client-connection-http.c @@ -374,7 +374,7 @@ doveadm_http_server_read_request(struct client_connection_http *conn) conn->method_err = 0; p_free_and_null(conn->client.pool, conn->method_id); conn->cmd = NULL; - array_clear(&conn->pargv); + doveadm_cmd_params_clean(&conn->pargv); conn->json_state = JSON_STATE_COMMAND_NAME; } else if (conn->json_state == JSON_STATE_COMMAND_NAME) { if (type != JSON_TYPE_STRING) break; @@ -462,6 +462,8 @@ doveadm_http_server_read_request(struct client_connection_http *conn) return; io_remove(&conn->client.io); + doveadm_cmd_params_clean(&conn->pargv); + if (rc == -2 || (rc == 1 && conn->json_state != JSON_STATE_DONE)) { /* this will happen if the parser above runs into unexpected element, but JSON is OK */ http_server_request_fail_close(conn->http_server_request, 400, "Unexpected element in input"); diff --git a/src/doveadm/doveadm-cmd.c b/src/doveadm/doveadm-cmd.c index b7ad8298f4..316bbbbc93 100644 --- a/src/doveadm/doveadm-cmd.c +++ b/src/doveadm/doveadm-cmd.c @@ -243,6 +243,18 @@ bool doveadm_cmd_param_istream(int argc, struct doveadm_cmd_param* params, const return FALSE; } +void doveadm_cmd_params_clean(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv) +{ + struct doveadm_cmd_param *param; + + array_foreach_modifiable(pargv, param) { + if (param->type == CMD_PARAM_ISTREAM && + param->value.v_istream != NULL) + i_stream_destroy(&(param->value.v_istream)); + } + array_clear(pargv); +} + static void doveadm_cmd_params_to_argv(const char *name, int pargc, const struct doveadm_cmd_param* params, ARRAY_TYPE(const_string) *argv) @@ -366,7 +378,7 @@ bool doveadm_cmd_try_run_ver2(const char *cmd_name, int argc, const char *argv[] int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const char *argv[]) { struct doveadm_cmd_param *param; - ARRAY(struct doveadm_cmd_param) pargv; + ARRAY_TYPE(doveadm_cmd_param_arr_t) pargv; ARRAY_TYPE(getopt_option_array) opts; const char *cptr; unsigned int pargc; @@ -395,6 +407,7 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha break; case '?': case ':': + doveadm_cmd_params_clean(&pargv); return -1; default: // hunt the option @@ -423,6 +436,7 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha } if (!found) { i_error("Extraneous arguments found"); + doveadm_cmd_params_clean(&pargv); return -1; } } @@ -432,10 +446,6 @@ int doveadm_cmd_run_ver2(const struct doveadm_cmd_ver2 *cmd, int argc, const cha // FIXME: Unsure what do to with return value cmd->cmd(cmd, pargc, param); - // unref istreams - array_foreach_modifiable(&pargv, param) { - if (param->type == CMD_PARAM_ISTREAM && param->value.v_istream != NULL) - i_stream_unref(¶m->value.v_istream); - } + doveadm_cmd_params_clean(&pargv); return 0; } diff --git a/src/doveadm/doveadm-cmd.h b/src/doveadm/doveadm-cmd.h index 7e9498218f..86ff9324f4 100644 --- a/src/doveadm/doveadm-cmd.h +++ b/src/doveadm/doveadm-cmd.h @@ -113,6 +113,8 @@ bool doveadm_cmd_param_str(int argc, const struct doveadm_cmd_param* params, con bool doveadm_cmd_param_array(int argc, struct doveadm_cmd_param* params, const char *name, ARRAY_TYPE(const_string)** value); bool doveadm_cmd_param_istream(int argc, struct doveadm_cmd_param* params, const char *name, struct istream** value); +void doveadm_cmd_params_clean(ARRAY_TYPE(doveadm_cmd_param_arr_t) *pargv); + extern struct doveadm_cmd_ver2 doveadm_cmd_stop_ver2; extern struct doveadm_cmd_ver2 doveadm_cmd_reload_ver2; extern struct doveadm_cmd_ver2 doveadm_cmd_stats_reset_ver2;