Commit Graph

7649 Commits

Author SHA1 Message Date
063b2ccdc8 (broken) add json parsing for ai 2026-05-01 19:01:31 +00:00
f4221e27ac fix(ai): fix leak from ai_get_provider_key 2026-05-01 18:50:21 +00:00
cdcc45b7c6 ref(pref): add newline at the end of the file 2026-05-01 18:47:46 +00:00
f133d81a05 fix(ai): use atomic operations for refcounting
Replace plain ref_count++/-- with g_atomic_int_inc and
g_atomic_int_dec_and_test for both AIProvider and AISession refcounts.
Prevents data races when ref/unref is called from worker threads.
2026-05-01 18:24:57 +00:00
a16237d16b fix(ai): convert \n escape sequences to actual newlines in LLM responses 2026-05-01 18:21:47 +00:00
cfe6ea46e2 feat(ai): disable request storage via store:false parameter
Add store:false to AI API requests to prevent OpenAI, Perplexity, and
other providers from storing conversation data or using it for training.

Both the OpenAI Responses API and Perplexity API support the store
parameter to control whether requests are persisted. Setting it to false
ensures conversations remain private and are not retained by the provider.

Privacy:
- Requests are not stored by AI providers
- Conversations are not used for model training
- Aligns with CProof's privacy-first design
2026-05-01 17:05:44 +00:00
2fc7f3d672 fix(ai): validate aiwin pointer to prevent UAF when window closed
Prevent use-after-free in the AI request worker thread when the user
closes the AI window during the 60-second HTTP request timeout. Without
this fix, the worker may dereference a dangling pointer and crash or
exhibit undefined behavior.

The _ai_request_thread function in ai_client.c previously cast user_data
to ProfAiWin* and used it directly without verifying the window was still
alive. Added wins_ai_exists() to iterate through all AI windows and check
if the pointer is still valid before use.

Safety:
- wins_ai_exists() iterates all AI windows (handles multiple AI windows)
- Worker skips UI update if window was freed, just cleans up
- Logs warning when dangling pointer is detected
2026-05-01 17:03:47 +00:00
fe0a46da58 refactor(ai): add UI display helpers
Add static _aiwin_display_error() and
_aiwin_display_response() helpers to reduce mutex repetition and
log warnings when aiwin is NULL or invalid.
2026-05-01 16:36:07 +00:00
cead417e78 refactor(ai): remove redundant callback layer from AI client
The ai_response_cb and ai_error_cb parameters were always passed the
same functions (aiwin_display_response and aiwin_display_error),
making the callback indirection redundant and complicating the call
chain.

Remove ai_callback_data_t, _ai_callback_invoke(), and
_ai_invoke_callback(). Simplify _ai_request_thread and ai_send_prompt
to directly call aiwin_display_error() and aiwin_display_response()
when user_data is a valid ProfAiWin*.
2026-05-01 13:34:00 +00:00
00f11eb704 fix(ai): guard NULL search_str and update tests for new cycling behavior
Update ai_providers_find() to handle NULL search_str safely by treating it
as an empty string, preventing a segfault in strdup() within autocomplete_complete().

Rename test_ai_providers_find_case_sensitive to test_ai_providers_find_case_insensitive
to reflect the new case-insensitive matching contract. Update all affected tests to
expect cycling behavior (NULL/empty returns first provider) and use auto_gchar for
automatic memory management.

Use `gchar` instead of `char` in ai_providers_find for consistency
2026-05-01 13:08:28 +00:00
4913a3d5a4 ref(ai): remove inaccurate logging 2026-05-01 12:56:57 +00:00
634fb7d7eb fix(ai): standardize lock handling in _ai_invoke_callback
Take the global lock mutex before invoking all callbacks (success
and error) to ensure thread-safety. Previously some paths took the
lock and others did not, creating asymmetric behavior that could
lead to data races when callbacks access UI state.
2026-05-01 11:35:09 +00:00
461c0c32dd refactor(ai): use stateful autocomplete for provider name matching
Replace the manual GHashTable iteration in ai_providers_find() with the
existing stateful autocomplete system. Provider names are now kept in
sync via autocomplete_add/remove during ai_add_provider/ai_remove_provider,
and ai_providers_find delegates to autocomplete_complete() for deterministic
tab-completion cycling through sorted results.

This eliminates manual GList allocation, iteration, and cleanup, while
providing consistent forward/backward cycling behavior shared by all
autocomplete callers.
2026-04-30 23:16:12 +00:00
002a6ed15b refactor(ai): flatten autocomplete into sequential prefix-matching chain
Replace the deeply nested conditional tree in _ai_autocomplete() with a
flat sequential chain of autocomplete_param_with_*() calls. Each call
tries a specific command prefix (e.g., "/ai set provider", "/ai start")
and returns immediately on match — a common, reliable pattern for
command-line tab completion.

The previous design nested provider-name autocomplete inside
g_strv_length() and g_strcmp0() checks, meaning /ai<tab> and /ai <tab>
would never reach the subcommand matcher. The new flat structure ensures
every prefix is tried in order, with the most specific prefixes first
and the generic /ai subcommand fallback last.

This pattern — sequential prefix matching with early return — is the
standard approach for autocomplete dispatch: each handler owns its
prefix, no shared state or argument parsing is needed, and adding a
new subcommand is a single append to the chain.
2026-04-30 23:10:14 +00:00
dc75f16221 fix(ai): move generic subcommand autocomplete outside nested conditionals
The generic `/ai <subcommand>` tab-completion was nested inside conditional
blocks that prevented it from firing in common cases — for example,
`/ai<tab>` or `/ai <tab>` would never match subcommands because the
`autocomplete_param_with_ac()` call was guarded by argument count checks
and nested inside the explicit handler branches.

Move the fallback subcommand autocomplete to execute unconditionally after
all explicit handler branches, ensuring `/ai <tab>` always lists available
subcommands regardless of argument count or which subcommand was typed.

Also move the `/ai set` subcommand fallback outside the inner else-block
so it runs whenever args[0] is "set", not only when num_args >= 2.
2026-04-30 22:51:07 +00:00
da0bf43d73 fix(ai): join multi-word arguments in cmd_ai_correct
Use g_strjoinv to join all arguments from args[1] onwards into a
single prompt string. Previously only args[1] was used, truncating
multi-word prompts like '/ai correct hello world' to just 'hello'
2026-04-30 19:24:39 +00:00
9e1f9b666e fix(ai): fix provider_name leak and const-cast in cmd_ai_start
Use auto_gchar temporary for g_strndup result in cmd_ai_start to
prevent memory leak. Fix const-cast warning by using a proper
non-const temporary variable.
2026-04-30 19:14:49 +00:00
93ad7379e2 fix(ai): align ai_list_providers with documented contract
Remove ai_provider_ref() from ai_list_providers() so the returned
providers do not need to be unref'd by the caller. This matches the
header docstring which states "caller must not free the list or
providers". Also update all callers (cmd_ai_providers, tests) to
remove redundant ai_provider_unref() calls.
2026-04-30 19:09:46 +00:00
caa0b3ccba fix(ai): remove redundant g_strdup on api_key assignment
ai_get_provider_key() already returns a freshly g_strdup'd copy of
the API key. The outer g_strdup in ai_session_create() created an
unnecessary second copy, leaking the original pointer.
2026-04-30 19:06:49 +00:00
c9a5239117 fix(ai): remove API key from debug log
Remove the log_debug line in ai_client.c that leaked the first 10
characters of the API key into logs. This is also contained a memory leak (g_strndup
return value was never freed).
2026-04-30 19:05:33 +00:00
25e0459979 fix(ai): persist API keys to disk after set/remove operations
API keys set via /ai set token were only stored in memory and lost
on client restart. prefs_ai_set_token() and prefs_ai_remove_token()
mutated the in-memory prefs but never called _save_prefs(), unlike
other preference setters in the same file.

Both functions now call _save_prefs() after mutating the keyfile,
ensuring API keys persist across client restarts as advertised.
2026-04-30 19:01:10 +00:00
bccd3ecded fix(ai): remove duplicate assistant response in the message history 2026-04-30 18:05:51 +00:00
cff05ca802 ref(ai): move unfitting functions out of window.c; create aiwin.c 2026-04-30 18:01:24 +00:00
9c8ad57b59 ref(ai): add stub, fix includes, move aiwin_send_message location 2026-04-30 17:41:36 +00:00
1f1770bd58 fix(ai): set correct links in tests, fix headers 2026-04-30 17:02:54 +00:00
e43e8378b0 feat(ai): add AI client with multi-provider support and UI
Add an AI client module that integrates with OpenAI-compatible API
providers (OpenAI, Perplexity, and custom providers) to provide
AI-assisted responses within the profanity client.

The implementation includes:

- src/ai/ai_client.c/h: Core AI client with provider management,
  session handling, and async HTTP request handling via libcurl.
  Supports per-provider API keys stored in preferences, reference-
  counted sessions, and conversation history tracking.

- src/ui/window.c/window_list.c: New AI window type (ProfAiWin) for
  displaying AI conversations, with response streaming and error
  display capabilities.

- Command integration: New `/ai` command (cmd_defs.c, cmd_funcs.c)
  for creating sessions, sending prompts, and managing providers.
  Provider autocomplete support in cmd_ac.c.

- Preferences integration: API keys for providers are persisted in
  the preferences system (config/preferences.c).

- Unit tests: 472 lines of comprehensive tests covering provider
  management, session lifecycle, JSON escaping, and autocomplete
  (tests/unittests/test_ai_client.c).

Architecture decisions:
- Asynchronous design: HTTP requests run on a separate thread to
  avoid blocking the main UI loop. Callbacks are invoked on the main
  thread via direct function call (profanity uses ncurses, not GLib
  main loop).
- Reference counting: Both AIProvider and AISession use ref counting
  for safe shared ownership.
- Response size limit: 10MB cap on HTTP responses to prevent OOM.
2026-04-29 19:23:33 +00:00
0feacbc9da ci: simulate Pikaur flag duplication in Arch Linux CI
Inject system flags from /etc/makepkg.conf into the CI environment to
detect build collisions caused by Pikaur's configuration bug.

Pikaur's cascading logic causes flags from /etc/makepkg.conf to be
merged into the build environment. This creates collisions with flags
defined in the project's Makefile.am (e.g., duplicate -D_FORTIFY_SOURCE
definitions), which can cause builds to fail for users.

By exporting these flags in the CI environment, we ensure that any
code change that is sensitive to flag duplication will trigger a
failure in our Arch Linux CI matrix, preventing broken builds from
reaching users.

Implementation details:
- Detects Arch Linux via /etc/os-release.
- Uses a sed-based flattener to handle multi-line variables and
  trailing backslashes in makepkg.conf.
- Exports the flags to the shell environment so that 'configure'
  and 'make' inherit them naturally, maintaining parity with a
  real Pikaur session.
2026-04-21 10:17:44 +00:00
0722dc9e36 build(pikaur): Fix failure due to duplicated flag and warnings 2026-04-13 19:52:24 +00:00
f84ed1bf6a perf(functests): speedup — profrc pre-baking, pty-close shutdown, parallel port pools
Replace 16 interactive UI setup commands with pre-written profrc file
containing [ui] and [notifications] sections (~1800ms saved per test).

Replace sleep(1) + blocking waitpid with close(pty fd) → SIGHUP →
polling waitpid(WNOHANG) → SIGTERM/SIGKILL fallback chain (~4900ms
saved per test).

Remove post-stbbr_start() and post-stbbr_stop() sleeps — bind+listen
completes synchronously before stbbr_start() returns, and
pthread_join() in stbbr_stop() guarantees socket cleanup (~200ms saved).

Add PORTS_PER_GROUP=50 isolated port ranges per test group to enable
safe parallel execution of 4 groups without port conflicts.
2026-03-12 18:20:35 +03:00
9ec01fa8cc fix: CWE-134 format string audit and compiler hardening
Security:
Fix CWE-134 in iq.c: user-controlled string passed as format argument
Add G_GNUC_PRINTF annotations to all variadic printf-like wrappers
in ui.h, log.h and http_common.h
Compiler flags (configure.ac):

Replace basic -Wformat/-Wformat-nonliteral with -Wformat=2
Add -Wextra, -Wnull-dereference, -Wpointer-arith,
-Wimplicit-function-declaration, -Wundef, -Wfloat-equal,
-Wredundant-decls, -Walloc-zero
Add -fstack-protector-strong, -fno-common, -D_FORTIFY_SOURCE=2
Add GCC-specific flags via AC_COMPILE_IFELSE: -Wlogical-op,
-Wduplicated-cond, -Wduplicated-branches, -Wstringop-overflow,
-Warray-bounds=2
Suppress noisy -Wextra sub-warnings: -Wno-unused-parameter,
-Wno-missing-field-initializers, -Wno-sign-compare,
-Wno-cast-function-type
Remove AM_CFLAGS/CFLAGS duplication
Bug fixes found by new warnings:

chatlog.c: non-MUCPM redact path passed resourcepart instead of NULL
rosterwin.c: merge duplicated if/else branches into single condition
omemo.c: redundant else-if in omemo_automatic_start; remove
unnecessary scope block and goto, use early return
console.c: pointer compared to integer 0 instead of NULL
stanza.c: increase pri_str/idle_str buffers from 10 to 12 bytes
(INT_MIN = -2147483648 needs 12 bytes including NUL)
vcard.c: NULL guard for filename before g_file_set_contents
api.c: broken log_warning() calls with extra format argument
Format mismatch fixes:

chatwin.c: Jid* → char* for %s
connection.c: %x → %lx for long flags
cmd_funcs.c: %d → %zu for size_t; cast gpointer to char* for %s
cmd_defs.c: %d → %u for g_list_length() return (guint)
iq.c: barejid → fulljid for from_jid
console.c, mucwin.c, privwin.c, account.c, omemo.c, presence.c:
gpointer → (char*) casts for %s
Const-correctness and cleanup:

database.c: const for type, query, sort variables
form.c/xmpp.h: const for form_set_value parameter
files.c: refactor to early return, eliminating NULL logfile path
muc.c/muc.h: remove meaningless top-level const on return type
common.c: const for URL string literal
Remove stale declarations: cons_show_desktop_prefs (ui.h),
connection_set_priority (connection.h),
omemo_devicelist_configure_and_request (omemo.h)
test_common.c: add currb NULL check to silence -Wnull-dereference
Tooling (check-cwe134.sh):

Reduce from 5 checks to 2 (checks 1-3 redundant with -Wformat=2)
Check 1: verify known wrappers have G_GNUC_PRINTF attribute
Check 2: auto-detect unannotated variadic printf-like functions
Match both const char* and const gchar* in variadic patterns

Author: jabber.developer2 <jabber.developer2@jabber.space>
2026-03-07 11:55:50 +01:00
1508f27e73 Merge branch 'ci/separate-build-step' 2026-03-05 18:36:13 +01:00
d4254db814 CI: Separate build and test steps 2026-03-04 23:04:51 +03:00
9e1b95a814 test(disco): remove disco_items_error_handling test
This test requires the fix from fix/xep-0030-disco-items-error-handling
branch. Moved there along with the source code fix.
2026-03-03 16:57:35 +01:00
24e1dac354 test(disco): add comprehensive XEP-0030 functional tests
Add 7 new tests for /disco command:
- disco_items_to_jid: query items to specific JID
- disco_info_empty_result: handle empty disco#info response
- disco_info_multiple_identities: multiple identity elements
- disco_info_without_name: identity without optional name attr
- disco_items_without_name: items without optional name attr
- disco_info_service_unavailable: error handling for info
- disco_items_error_handling: error handling for items (XEP-0030 §7)

The disco_items_error_handling test documents a bug where disco#items
errors are silently ignored (unlike disco#info which handles them).
This violates XEP-0030 Section 7 which requires error feedback to user.
2026-03-03 16:57:35 +01:00
f20a4da160 Add functional tests for /disco command (XEP-0030)
- Add 8 tests for disco info and disco items commands
- Fix XEP-0030 compliance bug: show message for empty disco#items results
- Tests cover: identity display, features, server/jid queries, error handling,
  items display, empty results, and connection requirement
2026-03-03 16:57:35 +01:00
663a959f9c test: add functional tests for autoping (XEP-0199)
- autoping_set_interval: verify /autoping set command
- autoping_set_zero_disables: verify disabling autoping
- autoping_timeout_set: verify /autoping timeout command
- autoping_timeout_zero_disables: verify disabling timeout
- autoping_sends_ping_after_interval: verify automatic ping IQ
- autoping_server_not_supporting_ping: verify error handling

Fast tests (command parsing) in Group 1, slow tests (timer-based) in Group 3.
2026-03-03 16:57:35 +01:00
31538580fb fix arch build 2026-02-18 17:39:25 +01:00
37ca2de308 ci: fix arch build 2026-02-17 16:30:52 +01:00
4fce333c9a fix(xmpp): show message for empty disco#items results (XEP-0030)
Per XEP-0030 section 3.1: 'if an entity has no associated items,
it MUST return an empty <query/> element.'

The client should display 'No service discovery items for X' when
receiving an empty result, not silently ignore it.

Previous version introduced in commit f28655c5c (2016-05-08) which added an early
return when child == NULL, preventing the message from being shown.
2026-02-11 01:10:55 +03:00
467222d0ca fix(ui,db): harden NULL handling, fix CWE-134, optimize iterations
security(CWE-134): fix format string injections + add CI check
fix(ui): subwindow lifecycle, newwin/newpad guards, fallback timestamps
fix(db): sqlite cleanup on failures, sqlite3_close_v2
fix(xmpp): queued_messages loop, barejid leak
perf(core): g_hash_table_iter_init instead of g_hash_table_get_keys
refactor(ui): CLAMP macro in _check_subwin_width
test: XEP-0012 and XEP-0045 functional tests

Author: jabber.developer2
Closes #58, #85
2026-02-06 19:27:40 +01:00
f8826b7c79 ci: improve CI stability with parallel builds and Valgrind
Major changes:
Run 4 build configurations in parallel with Valgrind on Linux
Add test failure detection verification (meta-test)
Port allocation per build to prevent conflicts in parallel runs
Add --coverage-only flag for dedicated coverage builds
Code quality:

Add TEST_GROUPS constant, CMOCKA patterns, helper functions
Organize ci-build.sh into sections
2026-02-02 17:47:05 +01:00
8353a29b4f fix(ci): remove insecure git clone flag, add ca-certificates
Remove -c http.sslverify=false from all git clones
(enables proper TLS verification, closes MITM risk).
Explicitly install ca-certificates in every CI Docker image.
2026-01-21 17:10:37 +01:00
85c817ee8c ci: speed up builds 4x with parallel tests, coverage, and ccache
Split functional tests into 4 parallel groups and add check-functional-parallel target (~3x faster CI runs).
Add branch-aware LCOV coverage reporting with new --enable-coverage option and lcov summary in CI pipeline.
Enable ccache via -C configure flag for faster recompilations.
Install lcov in all Docker images and use --depth 1 git clones + parallel make -j$(nproc) for quicker container builds.
Update CONTRIBUTING.md with instructions for parallel test groups and adding new ones.

All changes are tightly related CI/performance improvements developed in sequence. No external service uploads (e.g. Codecov skipped due to Gitea incompatibility).
2026-01-21 16:35:17 +01:00
a90eef1cb2 docs: update CONTRIBUTING.md to clarify functional test guidelines 2026-01-07 11:46:40 +01:00
48ab4b9360 feat: add Valgrind suppressions and update CI/docs
- Add prof.supp with pthread TLS suppressions
- Update ci-build.sh with test configurations
- Document functional test best practices in CONTRIBUTING.md
2026-01-07 11:46:40 +01:00
8f580f91a8 refactor(tests): migrate to content-based stubbing
- Replace stbbr_for_id() with stbbr_for_query()/stbbr_send()
- Content-based stubbing matches stanzas by namespace instead of ID
- Use regex assertions for flexible output matching
- Fix timing issues in chat_session and presence tests
2026-01-07 11:46:40 +01:00
2d7de2caf6 refactor(tests): replace libexpect with forkpty() for PTY handling
- Remove dependency on libexpect/tcl
- Implement native PTY handling with forkpty()
- Add prof_output_exact/regex for flexible output matching
- Improve timeout handling and synchronization
2026-01-07 11:46:40 +01:00
889a6e2b63 build: enable functional tests unconditionally
- Remove conditional compilation for functional tests
- Always build with stabber/cmocka when available
- Simplify test configuration in Makefile.am
2026-01-07 11:46:40 +01:00
44de29a199 build(docker): add TERM env, fix SSL and reflector handling
- Add TERM=xterm-256color for PTY support in functional tests
- Disable SSL verification for git clone in restricted networks
- Add error handling for Arch reflector installation
2026-01-07 11:46:40 +01:00
e31240a4be Merge branch 'fix/connect_max_args' 2026-01-07 10:14:38 +01:00