Added null check for jidp in cmd_sub to handle jid_create returning NULL.
Crash occurred when processing malformed JID inputs like @example.com.
Ensures robust handling of invalid JIDs.
Fixes#22
- Added null check for `jid` in `cmd_caps` to handle `jid_create` returning NULL.
- Crash occurred when processing malformed inputs like `@example.com` in `/caps`.
- Ensures robust handling of invalid JID strings in `WIN_CHAT` and `WIN_CONSOLE` cases.
Fixes#20
Implement /force-encryption command to configure forced encryption
settings with on|off and policy resend-to-confirm|block options.
The changes enhance user experience by clarifying encryption requirements
and providing actionable commands. Users can now press Enter again to
confirm unencrypted messages in resend-to-confirm mode.
The synchronous `get_message_from_editor` blocked the main loop (`prof_run`) while launching an external editor like `vim`, halting network I/O in `session_process_events` and preventing incoming message reception.
Introduced `get_message_from_editor_async` for `cmd_editor` to run the editor asynchronously. It forks and execs the editor in a thread (`editor_thread`), suspending NCurses to free the terminal. The main loop skips `inp_readline` and `ui_update` via a new `background_mode` flag while the editor runs, allowing `session_process_events` to keep the connection alive.
On editor completion, `editor_process` (called per loop iteration) resumes NCurses with `ui_resize`, inserts the result into the readline buffer and clears `background_mode`.
Retained synchronous `get_message_from_editor` for ~20 existing code paths (e.g., `vcard_nickname`) to avoid breaking them.
Tested with `vim` and `nano`: confirms no rendering conflicts, messages received during editing, and seamless resume. Edge cases like editor crashes handled via error logging and seamless resume.
Previously, features like `XMPP_FEATURE_OMEMO_DEVICELIST_NOTIFY` were
added in separate init methods (e.g., `omemo_devicelist_subscribe`) via
`caps_add_feature`, triggering `cl_ev_presence_send` and sending multiple
"online" XMPP presence stanzas. This caused other clients to see users
as appearing "online" multiple times.
This change adds `STANZA_NS_MOOD_NOTIFY` and
`XMPP_FEATURE_OMEMO_DEVICELIST_NOTIFY` in `caps_init`, ensuring they are
in `prof_features` early. This allows `caps_add_feature` to exit early
when called for these features, avoiding redundant presence updates.
When paging down beyond the visible chat buffer, the scroll position could
jump unexpectedly. This occurred because the visual distance from the bottom
(e.g. 6 lines until the last message) wasn’t preserved after loading new
messages from the DB.
This patch fixes that by capturing the visual offset (`current_offset`) before
the DB fetch and reapplying it after, based on the y-position of the final
buffer entry. This ensures consistent and smooth scroll transitions, even
as message heights vary.
In addition to fixing the visual glitch, this commit introduces a targeted
performance optimization: once the bottom of the chat has been reached
(`WIN_SCROLL_REACHED_BOTTOM`), we skip expensive operations entirely —
including datetime lookups and entry formatting — during further page_down
events. This reduces performance stalls
during rapid paging (e.g. holding the Page Down key at the bottom of the scrolling area).
This update also adapts to the recent change in `chatwin_db_history()`,
which now returns a `db_history_result_t` instead of `gboolean`, allowing
correct differentiation between an empty result and an actual DB error.
Together, these changes:
- Fix a scroll-jump bug in `page_down`
- Improve performance and responsiveness during rapid navigation
- Align with improved DB result handling
The function did not decref the Python object on type error paths,
resulting in a reference count leak. This caused memory to accumulate
over time. Added Py_XDECREF on all early return paths to properly free
the Python object reference and prevent leaks.
- Introduce static helper `_truncate_datetime_suffix()` to safely trim datetime strings, removing unwanted suffixes like timezone offsets
- Replace manual string management with auto_gchar and g_strdup for safer, clearer ownership and to prevent leaks
- Add safety checks and logging warnings for unexpected datetime string lengths or null pointers
- Refactor _mam_rsm_id_handler to use the helper function and updated string handling
- Change log_database_get_previous_chat parameters for consistent ownership semantics, avoiding double frees and mem leaks
- Overall improve stability and prevent memory leaks during log database queries
This commit refines the existing logic in win_page_up() by:
- Improving comments to clearly explain the rationale behind adjusting
the scroll offset relative to the first buffer entry’s visual position,
helping future maintainers understand why this is necessary.
- Fixing offset recalculation to better handle cases where older messages
with variable heights are loaded from the DB, improving scroll smoothness.
- Changing the logging of negative *page_start values from warning to debug,
recognizing that this can be a normal scenario when insufficient history is loaded.
- Simplifying some conditionals and renaming variables for clearer intent.
No changes yet applied to win_page_down(), but similar improvements could
be considered in the future.
Overall, this enhances the robustness and user experience of scrolling up
in chat windows, while preserving existing functional logic.
f27fa98 commit introduced issue of scrolling seemingly randomly being stuck and the following message flood in the logs: "WRN: Ncurses Overflow..."
A pad is an off-screen buffer — larger than the visible terminal screen — that you can scroll, render parts of, or update selectively.
Unlike regular windows, a pad is not tied to screen size. You can create a pad that's 1,000 lines tall, even if your terminal is only 40 lines tall.
This commit addresses the issue by increasing PAD_SIZE to a reasonable number,
allowing messages from buffer to be displayed without overflowing NCurses' window size (maxy).
Minor change: add .cache folder to gitignore
Improves code robustness by calling _theme_close() in theme_init() when the
theme was already initialized, preventing potential memory leaks or
inconsistent state.
Closes#4
Simple `ui_resize` is sufficient for rerendering all the elements.
Other calls create complexity, slow down the applications and even introduce mem leaks.
`ui_resize` technique is already used widely, including `cmd_editor` case.
Fixes#4
- Update formatting for stub files
- Update docs
While original project, Profanity, provides valuable basis for this
fork, we are not affiliated with the upstream. This commit
is updating documentation to reflect accurate information.
The docs are going to be updated further once the website is created.
Reviewed-on: devs/profanity#5
Co-authored-by: Jabber Developer <jabber.developer@jabber.space>
Co-committed-by: Jabber Developer <jabber.developer@jabber.space>
Current setup of the infratstrcture with DIND
was causing issues with volume binding,
leading to a false-positive error on code formatting check.
This commit addresses the issue by removing dependency on a container,
but at the same time it limits choice of formatting version.
This fix does not address the underlying issue with the architecture.
As an additional change, package versions are updated.
We must only return early in cases where we received a roster push with
1. a `from` attribute
2. that `from` is not our bare JID
The server sends roster pushes without `from` attribute and we must accept
them.
Fixes#2035
Fixes: bac24601da ("Introduce `equals_our_barejid()`")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
> The returned data is valid until changes to the hash release those keys.
As of the doc of `g_hash_table_get_keys()` [0].
> The returned data is valid until hash_table is modified.
As of the doc of `g_hash_table_get_values()` [1].
Use this property and create the lists when modifying the hashtable.
The `keys` list is most of the time used sorted, so sort it immediately. In
the cases where it was not used sorted, it does not matter.
This started off by looking into whether this can be improved.
`g_hash_table_foreach()` is discouraged to be used and proposes to use
a `GHashTableIter`. Since our lists are not modified very often it does not
really make sense, so I decided to keep using lists, but allocating
those lists statically instead of per invocation.
Instead of using a list, we could maybe use the `GArray` version, but
I am not sure whether it wouldn't be even better to replace the
`GHashTable` all along to store the `windows` instead.
[0] https://docs.gtk.org/glib/type_func.HashTable.get_keys.html
[1] https://docs.gtk.org/glib/type_func.HashTable.get_values.html
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Instead of c&p'ing the same code again and again, put everything in a
struct and loop over it.
This also fixes `vcard` not being in included in `all`.
Fixes: f934c5b59f ("Add vCard support")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
`http_dl->bytes_received` was already free'd when it was accessed inside
`aesgcm_file_get()`.
Change `http_file_get()` to optionally return the number of bytes received
so we know how much data we have to decrypt.
This fixes#1994
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
* use `calloc()` to allocate zero-initialized structs.
* order the allocation of members by their declaration.
* order the freeing of members in reverse order.
* move init of `silent` flag in plugin case.
* fix double free of `tmpname` in `aesgcm_file_get()`.
* make some functions static.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
```
==500714== Invalid free() / delete / delete[] / realloc()
==500714== at 0x484A78B: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==500714== by 0x5BDCD58: g_free (in /usr/lib64/libglib-2.0.so.0.8200.2)
==500714== by 0x49016B: http_file_put (http_upload.c:175)
==500714== by 0x5F613B1: start_thread (in /usr/lib64/libc.so.6)
==500714== by 0x5FE63D3: clone (in /usr/lib64/libc.so.6)
==500714== Address 0x86f6510 is 0 bytes inside a block of size 53 free'd
==500714== at 0x484A78B: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==500714== by 0x5BDCD58: g_free (in /usr/lib64/libglib-2.0.so.0.8200.2)
==500714== by 0x490299: http_file_put (http_upload.c:324)
==500714== by 0x5F613B1: start_thread (in /usr/lib64/libc.so.6)
==500714== by 0x5FE63D3: clone (in /usr/lib64/libc.so.6)
==500714== Block was alloc'd at
==500714== at 0x48477C4: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==500714== by 0x5F548A7: __vasprintf_internal (in /usr/lib64/libc.so.6)
==500714== by 0x5C2DD1D: g_vasprintf (in /usr/lib64/libglib-2.0.so.0.8200.2)
==500714== by 0x5BF8D97: g_strdup_vprintf (in /usr/lib64/libglib-2.0.so.0.8200.2)
==500714== by 0x5BF8E58: g_strdup_printf (in /usr/lib64/libglib-2.0.so.0.8200.2)
==500714== by 0x490264: http_file_put (http_upload.c:318)
==500714== by 0x5F613B1: start_thread (in /usr/lib64/libc.so.6)
==500714== by 0x5FE63D3: clone (in /usr/lib64/libc.so.6)
```
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>