Compare commits

...

5 Commits

Author SHA1 Message Date
01b695dd70 tests(ai_client): remove remaining ai_provider_unref() before ai_client_shutdown()
All checks were successful
CI Code / Check spelling (pull_request) Successful in 28s
CI Code / Check coding style (pull_request) Successful in 36s
CI Code / Linux (arch) (pull_request) Successful in 5m47s
CI Code / Code Coverage (pull_request) Successful in 2m41s
CI Code / Linux (debian) (pull_request) Successful in 4m38s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m42s
Fix three more tests that called ai_provider_unref() on providers owned
by the hash table, causing use-after-free when ai_client_shutdown()
destroyed the hash table.

Tests fixed:
- test_ai_parse_models_null_handling
- test_ai_parse_models_escaped_quotes
- test_ai_parse_models_with_whitespace
2026-05-15 01:57:35 +00:00
91695c0d4d tests(ai_client): fix remaining ai_provider_unref() use-after-free in test_ai_parse_models_empty_json
Some checks failed
CI Code / Check spelling (pull_request) Successful in 16s
CI Code / Check coding style (pull_request) Successful in 28s
CI Code / Code Coverage (pull_request) Successful in 2m34s
CI Code / Linux (ubuntu) (pull_request) Has been cancelled
CI Code / Linux (debian) (pull_request) Has been cancelled
CI Code / Linux (arch) (pull_request) Has been cancelled
The test called ai_provider_unref(provider) on a provider owned by the
hash table, then ai_client_shutdown() destroyed the hash table and
called ai_provider_unref() again on the dangling pointer.

Fix by removing the redundant unref call.
2026-05-15 01:50:26 +00:00
360c5fb0a9 tests(ai_client): remove redundant ai_provider_unref() before ai_client_shutdown()
The tests called ai_provider_unref(provider) on providers owned by the
hash table, then called ai_client_shutdown() which destroys the hash
table and calls ai_provider_unref() again on the same dangling pointer.
This caused Invalid read of size 4 at ai_client.c:302.

Fix by removing the redundant unref calls - ai_client_shutdown() cleans
up all providers in the hash table automatically.
2026-05-15 01:50:08 +00:00
3c021c754d test(ai): prevent memory leak in provider cycle test
Some checks failed
CI Code / Check spelling (pull_request) Successful in 16s
CI Code / Check coding style (pull_request) Successful in 31s
CI Code / Code Coverage (pull_request) Successful in 2m32s
CI Code / Linux (debian) (pull_request) Failing after 3m33s
CI Code / Linux (ubuntu) (pull_request) Failing after 3m44s
CI Code / Linux (arch) (pull_request) Failing after 4m25s
Use g_hash_table_new_full with g_free to ensure provider names are
properly freed when removed from the hash table. Add missing
glib.h include.
2026-05-14 20:56:35 +00:00
33929e2ae7 chore(ai): remove invalid litellm reference from help text
Some checks failed
CI Code / Check spelling (pull_request) Successful in 17s
CI Code / Check coding style (pull_request) Successful in 31s
CI Code / Code Coverage (pull_request) Successful in 2m33s
CI Code / Linux (debian) (pull_request) Failing after 3m36s
CI Code / Linux (ubuntu) (pull_request) Failing after 3m43s
CI Code / Linux (arch) (pull_request) Failing after 4m27s
2026-05-14 20:47:44 +00:00
2 changed files with 2 additions and 9 deletions

View File

@@ -10817,7 +10817,6 @@ cmd_ai(ProfWin* window, const char* const command, gchar** args)
cons_show("Use '/ai start' to begin a chat (uses default provider/model).");
cons_show("Use '/ai models <provider>' to fetch available models.");
cons_show("Available models: https://models.litellm.ai/");
return TRUE;
}

View File

@@ -1,3 +1,4 @@
#include "glib.h"
#include "prof_cmocka.h"
#include "common.h"
#include "ai/ai_client.h"
@@ -703,7 +704,6 @@ test_ai_parse_models_openai_format(void** state)
models = g_list_next(models);
assert_string_equal("google/gemini-3-flash-preview", models->data);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -776,7 +776,6 @@ test_ai_parse_models_perplexity_format(void** state)
models = g_list_last(models);
assert_string_equal("xai/grok-4.3", models->data);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -801,7 +800,6 @@ test_ai_parse_models_array_format(void** state)
models = g_list_next(models);
assert_string_equal("model3", models->data);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -821,7 +819,6 @@ test_ai_parse_models_empty_json(void** state)
assert_null(provider->models);
assert_int_equal(0, g_list_length(provider->models));
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -837,7 +834,6 @@ test_ai_parse_models_null_handling(void** state)
ai_parse_models_from_json(provider, NULL);
assert_null(provider->models);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -861,7 +857,6 @@ test_ai_parse_models_escaped_quotes(void** state)
GList* models = provider->models;
assert_non_null(models);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -885,7 +880,6 @@ test_ai_parse_models_with_whitespace(void** state)
GList* models = provider->models;
assert_string_equal("model-with-spaces", models->data);
ai_provider_unref(provider);
ai_client_shutdown();
}
@@ -1142,7 +1136,7 @@ test_ai_providers_find_cycles_through_many(void** state)
ai_add_provider("alpine", "https://al.example/");
/* Three providers share prefix "alp": alpha, alphabet, alpine. */
GHashTable* seen = g_hash_table_new(g_str_hash, g_str_equal);
GHashTable* seen = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
for (int i = 0; i < 3; i++) {
auto_gchar gchar* match = ai_providers_find("alp", FALSE, NULL);