With that command one can see the modifications of the runtime
configuration vs. the saved configuration.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
When setting up OMEMO for the first time via `/omemo gen` one had
to reconnect in order to make OMEMO work. This is fixed now.
Fixes: 5b6b5130 ("Fix OMEMO keyfile loading")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Several users have reported segfaults when starting up profanity which
has OMEMO support, but OMEMO is not set up yet.
@StefanKropp has been able to reproduce this and tracked it down to
`_load_identity()` calling `omemo_known_devices_keyfile_save()`.
The latter then calls `save_keyfile()` which calls
`g_key_file_save_to_file()`. This can then fail if one of the first two
strings is NULL and won't set the `error` on return. In its error handling
`save_keyfile()` unconditionally dereferences `error` which leads to the
segfault.
Fix this and also go through the entire codebase and verify that the usage
of `GError` is done correctly.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
The previous implementation used strstr() which would match OTR tag patterns anywhere in the message. This caused normal messages containing these patterns to incorrectly trigger OTR session initialization.
Changed to use strncmp() to verify that V1/V2 tags immediately follow the base tag, ensuring only legitimate OTR whitespace tags trigger session establishment.
Fixes#1957
When running profanity under Valgrind with slashguard enabled, the
following error could occur:
```
[...]
==4021347== Invalid read of size 1
==4021347== at 0x4851F49: memchr (vg_replace_strmem.c:986)
==4021347== by 0x45CEAD: _inp_slashguard_check (inputwin.c:183)
==4021347== by 0x45CEAD: inp_readline (inputwin.c:225)
==4021347== by 0x431184: prof_run (profanity.c:121)
==4021347== by 0x42C609: main (main.c:176)
==4021347== Address 0xe850883 is 0 bytes after a block of size 3 alloc'd
==4021347== at 0x48477C4: malloc (vg_replace_malloc.c:446)
[...]
```
`memchr()` requires the complete memory that shall be searched to be
accessible. Using `strchr()` could work for shorter strings, but we only
want to search in the first 4 chars.
Instead of somehow working around those limitations, simply search manually
in the first 4 bytes.
Fixes: 3c56b289 ("Add slashguard feature")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
In the past `Py_XDECREF()` was a macro. Preserve compat to ancient Python
versions by having a trampoline which calls `Py_XDECREF()`.
Fixes: #2043
Fixes: c0da36c4 ("Rage-cleanup.")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Replace deprecated gpgme_key_get_string_attr with modern API
This commit fixes the build failure against GPGME >= 2.0.0 where
gpgme_key_get_string_attr and GPGME_ATTR_EMAIL were removed.
Changes made:
- Replaced direct call to gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0)
- Added new helper function _gpgme_key_get_email() with backwards compatibility
- Function uses conditional compilation to support both old and new GPGME versions
Backwards Compatibility:
- GPGME < 2.0.0: Uses gpgme_key_get_string_attr() if GPGME_ATTR_EMAIL is available
- GPGME >= 2.0.0: Uses modern key->uids->email API
Forward Compatibility:
- Code compiles successfully with GPGME 2.0.0+ where deprecated functions are removed
- Uses modern GPGME API that iterates through key user IDs to find email addresses
Testing:
- Tested with GPGME 1.18.0 (backwards compatibility confirmed)
- Tested compilation compatibility for both old and new GPGME versions
- Verified the exact error from issue #2048 is resolved
- Confirmed no regression in functionality
Fixes: #2048
Resolves compilation error: 'gpgme_key_get_string_attr' undeclared
Resolves compilation error: 'GPGME_ATTR_EMAIL' undeclared
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>
In order to keep the C plugins API stable, we have to revert this part of
the changes done in 16ed7cc187.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
* Add an internal `_notifier_uninit()` function.
* Instead of `#ifdef` inside `notify()`, provide different target-specific
static implementations.
This also introduces `log_error_once()`.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Instead of always returning a `strdup()`'ed version, maybe return NULL and
handle this in the calling code.
This is still not true for `plugins_pre_chat_message_display()`, where we
return the passed `messag` in case there are no plugins, since this would
require a bigger refactor of more parts.
This also
* merges the implementation of `sv_ev_incoming_private_message()` and
`sv_ev_delayed_private_message()`, since they differed only by a single
line.
* untangles the `#ifdef` mess in `cl_ev_send_muc_msg_corrected()`.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
* Also pass `$*` to `configure` when invoking `ci-build.sh`, so one can
e.g. run `./ci-build.sh --without-xscreensaver`
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
While trying to get the unit tests working again I stumbled over all those
things that I thought could be better^TM.
Now we also know "TODO: why does this make the test fail?" - because
the unit tests are brittle AF ... and we have to init the subsystems
we use in the test, otherwise the cleanup will fail...
BTW. you can now also only run a single test ... or a pattern or so ...
you'd have to read how `cmocka_set_test_filter()` works exactly.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
* destroy/free/shutdown/close in reverse order of allocation
* more static/auto_Xfree
* less variables/strlen/GString
* properly `\0`-terminate string of testcase
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>