Commit 81f92f1fe introduced a selective update mechanism to
_accounts_save() to prevent overwrites when running multiple instances
by only modifying the specific account being saved.
Commit 5c484c fixed a problem with that commit regarding empty accounts.
It turns there was another bug introduced:
The new implementation only set the keys that existed in memory.
So removal of keys was not possible anymore.
Fixes: 81f92f1fed
Ref: 5c484c26ed
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Unescape any character following a backslash. This fixes autocompletion
for names with escaped spaces.
For example: `/msg Thor\ Odinson hello`
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Implement backslash based escaping in the command parser and autocompletion
logic to handle contact names containing double quotes.
This stops the parser from splitting nicknames into multiple tokens, which
previously caused "Invalid usage" errors.
The parser now sees \ as an escape character for quotes and spaces in
_parse_args_helper, count_tokens and get_start. Autocomplete results are
escaped when they contain spaces, and search prefixes are unescaped before
matching. strip_arg_quotes() has also been updated to handle unescaping.
Fixes: https://github.com/profanity-im/profanity/issues/1844
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Introduce optional spellcheck highlighting in the input window using
the Enchant-2 library.
```
/spellcheck on
/spellcheck lang en_US
```
New theme color `input.misspelled`.
Fixes: https://github.com/profanity-im/profanity/issues/183
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Enable adding oneself to the roster.
Self subscriptions are implicit according to XEP-0060 / XEP-0163.
So we adapt the /sub command to handle this gracefully by just printing
an informative message.
Profanitys logic didn't handle own presence/when adding to roster
correctly. This got fixed now.
Fixes: https://github.com/profanity-im/profanity/issues/2084
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
Filter out control characters (U+0000 to U+001F) from outgoing
messages, as they are illegal in XML 1.0 (except for \t, \n, and \r).
This prevents XMPP servers from closing the connection when such
characters are accidentally or intentionally included in a message.
Fixes: https://github.com/profanity-im/profanity/issues/1437
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.
When sending OMEMO messages, we print a warning message for every
participant without a device ID on every single send:
```
Can't find a OMEMO device id for my@jid.org
```
This clutters the UI due to the high volume of repetitive information.
This is solved by tracking suppressed warnings within the window
structure. A warning for a specific JID and type is only shown once
per window context.
Suppression state is stored in the base ProfWin structure and managed
via helper functions (win_warn_needed, win_warn_sent). The state is
lazily initialized to save resources and automatically cleaned up when
the window is closed.
Warnings are explicitly reset when an OMEMO session is started or
ended to ensure users see fresh alerts when toggling encryption.
Add __attribute__((nonnull) hints to omemo_receive_message and
omemo_on_message_recv declarations to catch NULL arguments at
compiletime.
So we can set the error state unconditionally in the functions.
If an incoming OMEMO message failed to decrypt (due to missing session
keys or untrusted identities), Profanity would fall back to displaying
the raw XMPP body. This usually contained a generic string like "This
message is encrypted with OMEMO,".
We wrote the detailed reason in the debug logs but the user only saw the
fallback message and probably wondered *why* the message wasn't
displayed properly.
I'm unsure if we should display the fallback message as well though.
The /omemo fingerprint command provided a list of all keys ever
seen for a contact but did not indicate which keys were currently "active"
(present in the latest server device list). This made it difficult for users
to identify which fingerprints actually required verification to fix
encryption issues.
Users can now easily distinguish between devices currently in use and
historical keys that no longer matter.
When encryption fails users can immediately see which "active" key is
"untrusted," allowing them to verify the correct fingerprint fast.
Function `omemo_is_device_active` will check if a fingerprint belongs
to a device currently announced by the contacts server.
Make jid_is_valid() allow JIDs ending with a slash (`user@domain/`).
In these cases, the parser now treats the input as a Bare JID with no
resource part, rather than rejecting it as invalid.
We will then just get `user@domain`.
This one will need a localpart as well.
It should be used when we want to message a user for example.
While jid_is_valid() also returns TRUE for domain/server JIDs.
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
Fix several issues in cmd_ac_complete_filepath:
* Prevent a segfault when input is empty.
* Fix a double free where acstring was managed by both auto_gchar and GArray.
* Fix a memory leak when reassigning inpcp during quote stripping.
* Restore the ability to cycle through files on repeated TAB presses by
caching the last input and skipping updates if the input is already a
known completion.
* Preserve user input style (e.g. ~, ./) in autocompletion strings to
ensure matches are correctly displayed and filtered.
Bug got introduced when "cleaning" code with new compiler flags and
sanitizers: aec8e48268.
Add unit tests so this doesn't happen again.
Before that commit we didn't use the static variable but used
autocomplete_update instead. Now we avoid redundat updates and preserve
the state across tab presses. We should look at this again later.
Fix https://github.com/profanity-im/profanity/issues/2098
Use a behavior-driven naming convention for unit tests.
Functions are now named using the pattern: [unit]__[verb]__[scenario]
The __ works as a semantic separator.
Examples:
* jid_create__returns__null_from_null()
* cmd_connect__shows__usage_when_no_server_value
Benefits:
* Easy to find all tests associated with a specific function using the
mandatory prefix.
* Test output in CI now explicitly describes the unit, the expected
outcome, and the scenario being tested.
Also disabled keyhandlers tests due to missing code in src/ui.
For example cmd_account() is located in src/command/cmd_funcs.c.
The unit test was located in tests/unittests/test_cmd_account.c.
Let's move it to a subdirectory like tests/unittests/command/test_cmd_account.c
to correpsond to the same structure.
Migrate structure allocations from calloc to glibs g_new0 macro to
improve type safety and memory robustness.
* Type Safety: The macro takes the type name directly, ensuring the
allocated size always matches the pointer type.
* Static Analysis: It guarantees a non-NULL return by aborting on
failure, which silences -fanalyzer warnings regarding potential NULL
pointer dereferences.
* Readability: Removes redundant sizeof() calls and is the glib way
Also refactor the function so we pass it the current version
and don't rely on the define inside of it.
This function only allows version format in the style of "x.y.z".