Cleanup of the conversion-safety warnings exposed by enabling
-Wconversion / -Wsign-compare in the previous commit, plus guard
clauses at the few places where unsigned arithmetic could actually
misbehave.
Build:
- configure.ac drops -Wno-error=conversion and
-Wno-error=float-conversion. Only -Wno-error=sign-conversion and
-Wno-error=sign-compare remain, gating the ~230 sign warnings
inherited from upstream that will be cleaned up in follow-ups.
Type / conversion fixes (no behaviour change):
- Length-like locals in command/cmd_ac.c, command/cmd_funcs.c,
pgp/gpg.c, tools/autocomplete.c, tools/parser.c and ui/mucwin.c
switched from int to size_t / glong (matching strlen /
g_utf8_strlen return type) so we no longer need an (int) cast and
loop counters / array sizes stay in their natural unsigned domain.
- g_timer_elapsed / GTimeSpan -> int casts in session.c, iq.c,
core.c, server_events.c, window.c.
- _win_print_wrapped: indent parameter and local curx/maxx switched
from size_t to int to match _win_indent / getcurx / getmaxx.
- Port casts (int -> unsigned short) at the libstrophe boundary in
connection.c and session.c, each preceded by
g_assert(port >= 0 && port <= UINT16_MAX) so the truncation is
documented at the call-site.
- curl_off_t / fread size_t results cast at usage in http_upload.c,
http_download.c, omemo/crypto.c.
- strtoul results cast to uint32_t in xmpp/omemo.c and omemo/omemo.c
where device/prekey IDs are genuinely 32-bit.
- config/color.c: fg/bg/palette indices switched to `short`
end-to-end (find_col, color_hash, find_closest_col,
_color_pair_cache_get, cache.pairs), so the ncurses init_pair
boundary needs at most one (short)i cast for the cache index. Also
TODO-noted: init_extended_pair is needed for >15-bit palettes.
- xmpp/avatar.c: float arithmetic explicitly casts its int operands.
- tests/functionaltests/proftest.c: read() result handling uses
size_t for the accumulator, _read_output returns ssize_t, and the
buffer-shift check happens before space subtraction so the
expression cannot underflow.
Real-risk guard clauses (the part that actually fixes bugs):
- src/ui/statusbar.c _tabs_width: `end > opened_tabs - 1` rewritten
as `end < opened_tabs` so opened_tabs == 0 no longer underflows.
- src/ui/statusbar.c _status_bar_draw_extended_tabs: the mirror
comparison rewritten as `end >= opened_tabs`.
- src/ui/statusbar.c status_bar_draw: replaced
`MAX(0, getmaxx - (int)_tabs_width)` with an explicit precheck
before subtraction.
- src/omemo/omemo.c prekey selection: prekey_index is now uint32_t
and randomized into an unsigned buffer, so modulo with prekeys_len
cannot yield a negative index for g_list_nth_data.
- src/omemo/crypto.c omemo_decrypt_func: PKCS#5/PKCS#7 unpadding
reads `plaintext[plaintext_len - 1]`, which would underflow on a
malformed empty ciphertext and read past the heap buffer. Reject
plaintext_len == 0 before the padding peek and validate the
padding byte against the buffer length before the unpad loop.
Initialise plaintext = NULL so the early `goto out` cannot free
uninitialised memory.
- src/ui/inputwin.c (4 mbrlen sites) and src/ui/window.c
_win_print_wrapped: mbrlen() returns 0 for the null wide
character. The existing checks rejected (size_t)-1 / -2 but
treated 0 as a valid step, so the surrounding loops would either
advance by SIZE_MAX (i += ch_len - 1) or spin in place
(word_pos += 0 forever). Add `|| ch_len == 0` to each guard;
inside the spell-check word-emission loop also fall back to a
one-byte advance.
- Defensive `len > 0 ? len - 1 : 0` prechecks at the strlen-based
g_strndup / loop sites in ui/console.c, plugins/c_api.c and
plugins/python_plugins.c.
Allow sending byte sequences to the Profanity PTY without a newline.
Now we can simulate control characters, specifically the `TAB` key
(`\t`), to trigger autocompletion.
Autocompletion failed for nicknames using non Latin scripts. We used
`g_str_to_ascii`, which replaces characters it cannot transliterate with
'?', leading search failures and false matches between different
scripts.
Now we do:
Use `g_utf8_casefold` for case-insensitive UTF-8 comparison. This
ensures that like 'Σ' correctly match 'σ' across all Unicode scripts,
providing correct results for non English nicknames.
If we don't fine anything typing a base ASCII character matches an
accented one (typing `e` matches `è`). This pass uses `g_str_to_ascii`
followed by `g_ascii_strdown` for comparison. It is now restricted to
run if the search string itself is valid ASCII, preventing the
"everything matches '?'" bug in non Latin scripts.
Autocomplete items are sorted using `strcmp`. `g_utf8_collate` provides
linguistical ordering for a specific language. But its behavior is
locale dependent and undefined when comparing strings from different
scripts. `strcmp` does byte-wise ordering that correctly follows Unicode
code order for UTF-8 strings.
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.
They were disabled in 171b6e73c9.
Enable the functional test suite and replaces the
dependency on libexpect with a custom solution.
The native solution allows for specific optimizations like automatic
ANSI code stripping, which is essential for reliable pattern matching in
an ncurses interface.
Custom PTY management via libutil provides full control over the process
lifecycle, resolving issues where tests would hang indefinitely.
We use forkpty from libutil.
Addiiotnally this commit implements automatic ANSI escape sequence
filtering to improve matching consistency.
This will get rid of the colors in matches. It's still something that we
need to think about more since basically we will not test out
color/theme system this way.
We also add non-blocking poll() and SIGKILL based teardown logic to
ensure clean test termination.
We added the functional tests to both autotools and meson.
They are only build when tests are enabled and stabber + libutil are
present.
Meson will print this out nicely in the summary.
Regards https://github.com/profanity-im/profanity/issues/789
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.
- 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
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
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).
- 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
As 9f2abc75 accidentally got the ordering of some of the includes wrong,
I decided to propose my initial solution again.
Additional to that, I've opened a MR against CMocka to solve this on
their side, since I believe that the current way this is done is not
sustainable [0].
[0] https://gitlab.com/cmocka/cmocka/-/merge_requests/91
Fixes: 9f2abc75 ("Fix tests with gcc15 (uintptr_t)")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
CProof note: our new tests need to also be updated.
- Modified chatwin_outgoing_msg to call _chatwin_set_last_message for corrected messages, using replace_id per XEP-0308.
- Updated _chatwin_set_last_message to skip redundant and invalid free/strdup for same pointers.
- Added null checks in _chatwin_set_last_message for safety.
- Fixes autocompletion suggesting original message content instead of corrected content.
Fixes#24
As 9f2abc75 accidentally got the ordering of some of the includes wrong,
I decided to propose my initial solution again.
Additional to that, I've opened a MR against CMocka to solve this on
their side, since I believe that the current way this is done is not
sustainable [0].
[0] https://gitlab.com/cmocka/cmocka/-/merge_requests/91
Fixes: 9f2abc75 ("Fix tests with gcc15 (uintptr_t)")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
## Summary
Fixes https://github.com/profanity-im/profanity/issues/1907
Update functional and unit test code to comply with the current cmocka test runner.
## Changes
- `UnitTest` struct to `CMUnitTest` struct
- `unit_test()` macro to `cmocka_unit_test(f)` macro
- `unit_test_setup_teardown()` macro to `cmocka_unit_test_setup_teardown` macro
- `run_tests()` macro to `cmocka_run_group_tests()` function
- Setup and teardown functions return `int` instead of `void`
## Testing
### Unit Tests
`make check`
### Functional Tests
I did not compile or run functional tests because they are *shelved* for now.
### Valgrind
I'm not entirely sure how to fun Valgrind in this case. I did not do fancy memory management, so it should be fine.