9f5e282
test(persistance): truncated attributes assertion
Phillip Davis created
9f5e282
test(persistance): truncated attributes assertion
Phillip Davis created
a4f7fb2
fix(entities): cache MUC occupants in own DB rows
Phillip Davis created
a9d648b
Require a SCRAM iteration count of 4096 or higher
The RFC specifies a minimum iteration count of 4096 only as a "SHOULD". Therefore, requiring 4096 on the client side is technically not fully in line with the spec. However, in the existing ecosystem, the servers that we tested all use 4096 or more.
Daniel Gultsch created
3a0803f
support latest UP spec wrt pending intent
Previously we used a custom protocol extension to optionally use pending intents instead of an 'application' extra; nowadays the UnifiedPush spec supports pending intents officially (and we can stop accepting the insecure 'application' extra)
Daniel Gultsch created
abe9fe1
limit XML element nesting to 128 levels
beyond that we could theoretically get stack overflow exceptions due to the recursion in our parser
Daniel Gultsch created
53e8ec1
Always indicate support for channel binding in SASL header
This commit breaks logging in on servers that announce a -PLUS variant for SCRAM but do not support XEP-0440. On servers that do not support XEP-0440, we previously decided to use no channel binding because picking "none" was better than picking an unsupported one and failing the login. However, this behaviour also required us to indicate that we did not support channel binding; otherwise, the server, seeing an unknown binding mechanism, would fail our login. This was a decision made for the broadest possible compatibility with the pre-0440 ecosystem. Note that the y flag wasn't the only security layer. Conversations also uses pinning (if you logged in once with -PLUS, it won't fall back) and XEP-0474 (basically a fancy version of the y flag). In addition there is a setting in Conversations to always require Channel Binding. This will also automatically be turned on for conversations.im and quicksy.im. It has now been two years since XEP-0440 was released for ejabberd and Prosody, and our compatibility concerns have shifted: if you want to have -PLUS on your server, please update the server to support XEP-0440.
Daniel Gultsch created
dc5b902
fix: NPE from unsynchronized MucOptions access
- ConversationGetMucOptionsRaceTest is in its own file to make the
instrumentation barriers a little easier to see and enforce
- It simulates basically the following situation:
i. On app startup, all accounts connect to all MUCs, which
eventually triggers joinMuc, which calls
Conversation.resetMucOptions.
This happens on account's individual XMPP connection Thread.
ii. At the same time, on the UI thread, we bind
ConversationsOverviewFragment, which eventually leads to
ConversationAdapter.onBindViewHolder, which calls getMucOptions.
iii. Conversation.resetMucOptions is not synchronized, so it can
run after the null-check in getMucOptions, resulting in a null
return value.
- Used AtomicReference instead of synchronizing resetMucOptions
because joinMuc is run on a directExecutor associated with the
XmppConnection thread. While the synchronized getMucOptions was
called right after this in the existing code, the documentation for
directExecutor has this to say:
When a ListenableFuture listener is registered to run under
directExecutor, the listener can execute in any of three possible
threads:
- When a thread attaches a listener to a ListenableFuture that's
already complete, the listener runs immediately in that thread.
- When a thread attaches a listener to a ListenableFuture that's
incomplete and the ListenableFuture later completes normally,
the listener runs in the thread that completes the ListenableFuture.
- When a listener is attached to a ListenableFuture and the
ListenableFuture gets cancelled, the listener runs immediately
in the thread that cancelled the Future.
- (This is applicable, since directExecutor uses in
XmppConnectionService are extensively attached to ListenableFuture)
The docs continue:
A specific warning about locking: Code that executes user-supplied
tasks, such as ListenableFuture listeners, should take care not to
do so while holding a lock. Additionally, as a further line of
defense, prefer not to perform any locking inside a task that will
be run under directExecutor: Not only might the wait for a lock
be long, but if the running thread was holding a lock, the
listener may deadlock or break lock isolation.
- Altogether, AtomicReference seems much more aligned with how Google
intends directExecutor to be used.
Anyway, here's the stacktrace that reported this error:
```
2026-02-20 10:41:09.089 7610-7610 AndroidRuntime com.cheogram.android E FATAL EXCEPTION: main (Ask Gemini)
Process: com.cheogram.android, PID: 7610
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String eu.siacs.conversations.entities.MucOptions.getName()' on a null object reference
at eu.siacs.conversations.entities.Conversation.getName(Conversation.java:1068)
at eu.siacs.conversations.entities.Conversation.getAvatarName(Conversation.java:1784)
at eu.siacs.conversations.ui.util.AvatarWorkerTask.setContentDescription(AvatarWorkerTask.java:135)
at eu.siacs.conversations.ui.util.AvatarWorkerTask.loadAvatar(AvatarWorkerTask.java:105)
at eu.siacs.conversations.ui.adapter.ConversationAdapter.onBindViewHolder(ConversationAdapter.java:255)
at eu.siacs.conversations.ui.adapter.ConversationAdapter.onBindViewHolder(ConversationAdapter.java:33)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7846)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7953)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6742)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:7013)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6853)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6849)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2422)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1722)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1682)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:747)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4737)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4459)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:5011)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1638)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at androidx.coordinatorlayout.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1213)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:899)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:919)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1638)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at androidx.drawerlayout.widget.DrawerLayout.onLayout(DrawerLayout.java:1273)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:25626)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
```
Phillip Davis created
9c165e4
Allow camera/mic in command UI webview
Stephen Paul Weber created
780f04b
fix NPE (and other unsurfaced races)
Phillip Davis created
dd3c912
Allow build to pass without secrets
Stephen Paul Weber created
10521d1
fix ConcurrentModificationException
ConcurrentModificationException can only be triggered by (a) obviously, multiple threads modifying the same collection or (b) one thread which modifies the thread while iterating over it (see [here](https://docs.oracle.com/javase/8/docs/api/java/util/ConcurrentModificationException.html)). Assuming that `systemTags` doesn't alias `this.systemTags`, it must be (a). Also, the stacktrace we got comes from inside `old.equals`. consider: ```java final JSONArray old = this.systemTags; this.systemTags = new JSONArray(); final JSONArray old = this.systemTags; ... this.systemTags.put(...) !old.equal(...) ``` and we get ConcurrentModificationException bc Thread 2's `old` alias's thread 1's `this.systemTags` The patch fixes this bug by making suring that no references escape function scope, so no aliasing can occur.
Phillip Davis created
8bc6439
Default to jabber.fr for fallback
Stephen Paul Weber created
d8152c4
Never fall back to iterative DNS for DNSSEC
This can work around if your local resolver strips DNSSEC, but also it means resolution is bonkers slow and might even take forever / fail if DNS queries are blocked (because you're on TOR VPN or similar). So if recursive DNSSEC fails, just fail DNSSEC and fall back to regular DNS lookups.
Stephen Paul Weber created
d0488fb
Need to put this file in the source dir
Stephen Paul Weber created
8518d6a
add wasm extension and application/wasm MIME
Phillip Davis created
26eabc6
Swap play apk for free bundle
Stephen Paul Weber created
b69787c
Silly hack to render code tags at all
Stephen Paul Weber created
0c62120
fix crash from non-existant notification channel
ticket: https://todo.sr.ht/~singpolyma/soprani.ca/502
Phillip Davis created
c41c023
Use less quote for reaction fallback
Stephen Paul Weber created
0a3a86a
Put blank line after fallback quote
Stephen Paul Weber created
2ee0fee
EmojiSearch.addEmoji fixes CustomEmoji shortcodes
- now `EmojiSearch.emoji` is truly immutable, in the sense that its members are not mutated after being inserted. - attempt to fix: https://todo.sr.ht/~singpolyma/soprani.ca/473
Phillip Davis created
b05fdb5
if setAvatar to null, dont check blocked media
codepath is deleteAvatar, which is setAvatar(from, null)
Phillip Davis created
eba6c51
Use correct size for all body elements
Stephen Paul Weber created
e067ced
Also check for abilities on bare jid
If we have them
Stephen Paul Weber created
cbdb5ca
Match text sizes from new snikket
Stephen Paul Weber created
cafbf17
dont try to load messages if the activity is null
Phillip Davis created
b156e93
Make default option look less like a header
Stephen Paul Weber created
37c5e43
use synchronously initialized activity
fixes NPE when using 'Return to ongoing call' context button
Phillip Davis created
979ba82
add log to unexpected BinderProxy exception
Phillip Davis created
4985523
Add some more UI around call failures
Stephen Paul Weber created
f6802e0
add fitsSystemWindows to activity_webxdc_store.xml
Phillip Davis created
b18cb97
Upgrade sentry for the 16kb problem
Stephen Paul Weber created
47b611d
defer account cancellation to another thread
otherwise causes NetworkOnMainThreadException
Phillip Davis created
58d6ff8
kill MAM queries for blocked convos
Phillip Davis created
5059358
fix NPE by refactoring onClick
Phillip Davis created
6065d1b
use error-catching version of openInputStream
Phillip Davis created
24c6c03
unhide ImportBackupActivity ActionBar
Phillip Davis created
a8324a0
try-catch `new ToneGenerator` and log errors
trouble reproducing reports of failure stemming from `WebRTCWrapper.applyDtmfTone` failing on this constructor, specifically: ``` at android.media.ToneGenerator.native_setup(Native Method) at android.media.ToneGenerator.<init>(ToneGenerator.java:751) ``` so we log the error for next time and catch it to prevent crashing, and instead just dont play the tone
Phillip Davis created
bcbafc9
fix TOCTOU in command pager
- in CommandSession constructor, must construct a hard reference to the ViewPager to make garbage collection impossible until at least `getContext()` is called - in setupLayoutManager, current code doesn't have a case for if mPager is null. Probably we wouldn't be there anyway, but in any case the `ctx` parameter should be equivalent, i.e., it should refer to the ActivityContext, so we use that instead of going through mPager
Phillip Davis created
815d67b
do precedence right
Phillip Davis created
c2c37f2
fix(menu): return true from menu handlers
ConversationFragment.onOptionsItemSelected was using break statements instead of return true for handled menu items. This caused the method to return false (from super.onOptionsItemSelected), indicating the event was not handled. On tablets with split-pane view, this caused menu events to bubble from the temporary fragment in ConversationsOverviewFragment to the visible ConversationFragment, resulting in duplicate actions. For example, selecting "Contact details" from the context menu would open contact details twice: first for the selected conversation (correct), then for the currently active conversation (wrong), with the wrong one appearing on top. Fixed by changing all break statements to return true, matching the pattern already used in onContextItemSelected. This also adds a missing return after action_block_avatar which was previously falling through to the next case. Fixes: https://todo.sr.ht/~singpolyma/soprani.ca/437
Phillip Davis created
da4c216
filter accts in ConversationsOverviewFragment
Phillip Davis created
b11972b
escape jids in more places
Phillip Davis created
d675927
dont timeout w/o ack
Phillip Davis created
575cfdf
declare ImportBackupService in android manifest
was causing all backup restores to fail, service was never even created
Phillip Davis created
b947940
guard against null url in oob stanza
previously, would crash whole app
`if (url != null) {` makes it seem like we were
fine with the subsequent code not running anyway
Phillip Davis created
4fa90ed
Update for 16KB alignment
Stephen Paul Weber created
95bcad4
Merge branch '442-connect-via-tor-not-working' of https://git.secluded.site/cheogram-android
* '442-connect-via-tor-not-working' of https://git.secluded.site/cheogram-android: fix(settings): enable Tor conns for other flavs
Stephen Paul Weber created
011e884
fix(settings): enable Tor conns for other flavs
Remove QuickConversationsService.isConversations() checks from AppSettings.java (isUseTor, isExtendedConnectionOptions) to allow Tor connections in non-Conversations flavours. I tested by installing with a modified package ID, adding a new account, enabling the Tor toggle, and seeing that 0 out of 1 accounts were connected because Tor is unavailable. After installing/enabling Orbot and waiting a bit, I had to toggle the account to get it to try again. Fixes: https://todo.sr.ht/~singpolyma/soprani.ca/442
Amolith created
8863066
don't care abt old pw if didUnlock
Phillip Davis created