@@ -11062,6 +11062,16 @@ static bool project_db_is_servable(const char *project, const char *db_path) {
1106211062 return servable;
1106311063}
1106411064
11065+ /* The three heap strings handle_index_repository owns from
11066+ * cbm_mcp_get_string_arg / resolved_repo_path_from_project_arg. One release
11067+ * point keeps the dozen early-return paths in step; free(NULL) is a no-op, so
11068+ * a path may pass NULL for an argument it never obtained. */
11069+ static void index_args_free(char *repo_path, char *mode_str, char *name_override) {
11070+ free(repo_path);
11071+ free(mode_str);
11072+ free(name_override);
11073+ }
11074+
1106511075static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1106611076 char *repo_path = cbm_mcp_get_string_arg(args, "repo_path");
1106711077 char *mode_str = cbm_mcp_get_string_arg(args, "mode");
@@ -11074,15 +11084,12 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1107411084 }
1107511085
1107611086 if (!repo_path) {
11077- free(mode_str);
11078- free(name_override);
11087+ index_args_free(NULL, mode_str, name_override);
1107911088 return cbm_mcp_text_result("repo_path is required", true);
1108011089 }
1108111090
1108211091 if (!resolve_session_repo_path(srv, &repo_path)) {
11083- free(mode_str);
11084- free(name_override);
11085- free(repo_path);
11092+ index_args_free(repo_path, mode_str, name_override);
1108611093 return cbm_mcp_text_result("failed to resolve repo_path", true);
1108711094 }
1108811095
@@ -11102,26 +11109,20 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1110211109 if (repo_path && repo_path[0] &&
1110311110 !cbm_workspace_root_allowed(repo_path, cbm_workspace_home_dir(), cbm_workspace_cache_dir(),
1110411111 allowed_root, boundary_err, sizeof(boundary_err))) {
11105- free(mode_str);
11106- free(name_override);
11107- free(repo_path);
11112+ index_args_free(repo_path, mode_str, name_override);
1110811113 return cbm_mcp_text_result(boundary_err, true);
1110911114 }
1111011115
1111111116 if (mode_str && strcmp(mode_str, "cross-repo-intelligence") == 0) {
11112- free(mode_str);
1111311117 char *result = handle_cross_repo_mode(srv, repo_path, name_override, args);
11114- free(name_override);
11115- free(repo_path);
11118+ index_args_free(repo_path, mode_str, name_override);
1111611119 return result;
1111711120 }
1111811121
1111911122 cbm_index_resource_policy_t resource_policy;
1112011123 char policy_error[CBM_SZ_256] = {0};
1112111124 if (!load_index_policy(srv, args, &resource_policy, policy_error, sizeof(policy_error))) {
11122- free(mode_str);
11123- free(name_override);
11124- free(repo_path);
11125+ index_args_free(repo_path, mode_str, name_override);
1112511126 return cbm_mcp_text_result(policy_error, true);
1112611127 }
1112711128
@@ -11133,9 +11134,7 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1113311134 worker_args ? srv->index_executor(srv->index_executor_context, repo_path, worker_args)
1113411135 : NULL;
1113511136 free(worker_args);
11136- free(repo_path);
11137- free(mode_str);
11138- free(name_override);
11137+ index_args_free(repo_path, mode_str, name_override);
1113911138 return coordinated ? coordinated
1114011139 : cbm_mcp_text_result(
1114111140 "daemon index coordinator could not start the operation", true);
@@ -11148,9 +11147,7 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1114811147 char *mutation_project =
1114911148 cbm_project_name_from_path(name_override && name_override[0] ? name_override : repo_path);
1115011149 if (!mutation_project) {
11151- free(repo_path);
11152- free(mode_str);
11153- free(name_override);
11150+ index_args_free(repo_path, mode_str, name_override);
1115411151 return cbm_mcp_text_result("could not resolve index project name", true);
1115511152 }
1115611153
@@ -11163,24 +11160,18 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1116311160 char *worker_args = index_args_with_repo_path(args, repo_path, &resource_policy);
1116411161 if (!worker_args) {
1116511162 free(mutation_project);
11166- free(repo_path);
11167- free(mode_str);
11168- free(name_override);
11163+ index_args_free(repo_path, mode_str, name_override);
1116911164 return cbm_mcp_text_result("failed to prepare supervised index request", true);
1117011165 }
1117111166 char *supervised = index_run_supervised(srv, worker_args);
1117211167 free(worker_args);
1117311168 if (supervised) {
1117411169 free(mutation_project);
11175- free(repo_path);
11176- free(mode_str);
11177- free(name_override);
11170+ index_args_free(repo_path, mode_str, name_override);
1117811171 return supervised;
1117911172 }
1118011173 free(mutation_project);
11181- free(repo_path);
11182- free(mode_str);
11183- free(name_override);
11174+ index_args_free(repo_path, mode_str, name_override);
1118411175 return cbm_mcp_text_result(
1118511176 "index supervision failed before a contained worker could start; no "
1118611177 "in-process fallback was attempted",
@@ -11189,18 +11180,14 @@ static char *handle_index_repository(cbm_mcp_server_t *srv, const char *args) {
1118911180
1119011181 if (!mcp_project_mutation_begin(srv, mutation_project)) {
1119111182 free(mutation_project);
11192- free(repo_path);
11193- free(mode_str);
11194- free(name_override);
11183+ index_args_free(repo_path, mode_str, name_override);
1119511184 return cbm_mcp_text_result("index operation blocked by another mutation for this project",
1119611185 true);
1119711186 }
1119811187 if (mcp_request_cancelled(srv)) {
1119911188 mcp_project_mutation_end(srv, mutation_project);
1120011189 free(mutation_project);
11201- free(repo_path);
11202- free(mode_str);
11203- free(name_override);
11190+ index_args_free(repo_path, mode_str, name_override);
1120411191 return cbm_mcp_text_result("index operation cancelled for this request", true);
1120511192 }
1120611193
0 commit comments