fix(ai): fix memory leaks in _ai_request_thread

Replace manual g_free calls with auto_gchar for local_provider_name,
local_model, local_api_key, and response_data to ensure automatic
cleanup and prevent memory leaks.
This commit is contained in:
2026-05-15 11:29:10 +00:00
parent 5e329c77e1
commit 7469f31c78

View File

@@ -1419,10 +1419,10 @@ _ai_request_thread(gpointer data)
* list modifications). We must snapshot all fields atomically. * list modifications). We must snapshot all fields atomically.
* ===================================================================== */ * ===================================================================== */
pthread_mutex_lock(&session->lock); pthread_mutex_lock(&session->lock);
gchar* local_provider_name = g_strdup(session->provider_name); auto_gchar gchar* local_provider_name = g_strdup(session->provider_name);
AIProvider* local_provider = ai_provider_ref(session->provider); AIProvider* local_provider = ai_provider_ref(session->provider);
gchar* local_model = g_strdup(session->model); auto_gchar gchar* local_model = g_strdup(session->model);
gchar* local_api_key = g_strdup(session->api_key ? session->api_key : ""); auto_gchar gchar* local_api_key = g_strdup(session->api_key ? session->api_key : "");
pthread_mutex_unlock(&session->lock); pthread_mutex_unlock(&session->lock);
log_debug("[AI-THREAD] Session: %s/%s", local_provider_name, local_model); log_debug("[AI-THREAD] Session: %s/%s", local_provider_name, local_model);
@@ -1492,6 +1492,7 @@ _ai_request_thread(gpointer data)
long http_code = 0; long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
log_debug("[AI-THREAD] HTTP response code: %ld", http_code); log_debug("[AI-THREAD] HTTP response code: %ld", http_code);
auto_gchar gchar* response_data = g_steal_pointer(&response.data);
if (res != CURLE_OK) { if (res != CURLE_OK) {
auto_gchar gchar* error_msg = g_strdup(curl_easy_strerror(res)); auto_gchar gchar* error_msg = g_strdup(curl_easy_strerror(res));
@@ -1500,17 +1501,14 @@ _ai_request_thread(gpointer data)
} else if (http_code >= 400) { } else if (http_code >= 400) {
/* Handle HTTP errors */ /* Handle HTTP errors */
log_debug("[AI-THREAD] HTTP error response body (%zu bytes): %s", log_debug("[AI-THREAD] HTTP error response body (%zu bytes): %s",
response.size, response.data ? response.data : "NULL"); response.size, response_data);
/* Try to extract the actual error message from the JSON response */ /* Try to extract the actual error message from the JSON response */
auto_gchar gchar* parsed_error = ai_parse_error_message(response.data); auto_gchar gchar* parsed_error = ai_parse_error_message(response_data);
auto_gchar gchar* error_msg = parsed_error ? g_strdup_printf("HTTP %ld: %s", http_code, parsed_error) : g_strdup_printf("HTTP %ld: %s", http_code, response.data && strlen(response.data) > 0 ? response.data : "Unknown error"); auto_gchar gchar* error_msg = parsed_error ? g_strdup_printf("HTTP %ld: %s", http_code, parsed_error) : g_strdup_printf("HTTP %ld: %s", http_code, response_data && strlen(response_data) > 0 ? response_data : "Unknown error");
log_error("AI request failed for %s/%s: %s", local_provider_name, local_model, error_msg); log_error("AI request failed for %s/%s: %s", local_provider_name, local_model, error_msg);
_aiwin_display_error(user_data, error_msg); _aiwin_display_error(user_data, error_msg);
} else { } else {
/* Parse response - transfer ownership to auto_gchar for cleanup */ log_debug("[AI-THREAD] Raw API response (%zu bytes): %s", response.size, response_data);
log_debug("[AI-THREAD] Raw API response (%zu bytes): %s", response.size, response.data ? response.data : "NULL");
auto_gchar gchar* response_data = response.data;
response.data = NULL;
auto_gchar gchar* content = ai_parse_response(response_data); auto_gchar gchar* content = ai_parse_response(response_data);
if (content) { if (content) {
/* Add assistant response to history (under lock) */ /* Add assistant response to history (under lock) */
@@ -1531,11 +1529,7 @@ _ai_request_thread(gpointer data)
curl_slist_free_all(headers); curl_slist_free_all(headers);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
/* Cleanup local copies */
g_free(local_provider_name);
ai_provider_unref(local_provider); ai_provider_unref(local_provider);
g_free(local_model);
g_free(local_api_key);
g_free(args); g_free(args);