Skip to content

bug: Android 9 crash when spam scoring received events #619

Description

@NicolaLS

Device: Emulator
Bundle ID: com.wisp.app.debug
OS: Android 9 / API 28

On Android 9 / API 28, the app can crash after receiving events that trigger spam scoring. This was discovered by logging in with a watch-only raw hex pubkey that had relay events addressed to it, but login method is not the core issue.

Android 9 (API 28) uses ICU 60.2:
https://developer.android.com/guide/topics/resources/internationalization#versioning-nougat

NSpamFeatures object has Android 9 incompatible regex that causes the app to crash whenever the object is created:

private val EMOJI_PATTERN = Regex(
"[\\p{IsEmoji_Presentation}\\p{IsExtended_Pictographic}]"

  1. Extended_Pictographic is too new for Android 9’s ICU 60.2. Its status is stable since ICU 62 (See this)
  2. The Is prefix is supported since Android 10 (See this)

Steps to reproduce:
Install the app on a Android 9 device/emulator and login with 0000000000000000000000000000000000000000000000000000000000000000 or login with any other identity and then publish events referring to that identity (p tag) that activate spam scoring.

According to AI this is one of the events to 0000... that triggered the spam scoring but I did not look into this deeply so I am not sure whether it is correct: https://njump.me/nevent1qqsqz52esevf8gtcjkltq3d8zmzzuwjzr4vuljkq996t959a3mphqwczyqn2dz5c4g9m4lrg5qc7mnfv5l3a2l9txucuf0nrck935w4ug0u5cg0lj08

Logcat:

2026-07-08 09:29:38.991  5916-6491  AndroidRuntime          com.wisp.app.debug                   E  FATAL EXCEPTION: DefaultDispatcher-worker-16
                                                                                                    Process: com.wisp.app.debug, PID: 5916
                                                                                                    java.lang.ExceptionInInitializerError
                                                                                                    	at com.wisp.app.ml.NSpamClassifier.score(NSpamClassifier.kt:9)
                                                                                                    	at com.wisp.app.repo.NotificationRepository.warmSpamScore(NotificationRepository.kt:721)
                                                                                                    	at com.wisp.app.repo.NotificationRepository.addEvent(NotificationRepository.kt:245)
                                                                                                    	at com.wisp.app.repo.NotificationRepository.addEvent$default(NotificationRepository.kt:167)
                                                                                                    	at com.wisp.app.viewmodel.EventRouter.processRelayEvent(EventRouter.kt:152)
                                                                                                    	at com.wisp.app.viewmodel.StartupCoordinator$initRelays$4$1.emit(StartupCoordinator.kt:237)
                                                                                                    	at com.wisp.app.viewmodel.StartupCoordinator$initRelays$4$1.emit(StartupCoordinator.kt:235)
                                                                                                    	at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(SharedFlow.kt:397)
                                                                                                    	at kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
                                                                                                    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:101)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:832)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720)
                                                                                                    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707)
                                                                                                    	Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@dcdece2, Dispatchers.Default]
                                                                                                    Caused by: java.util.regex.PatternSyntaxException: U_ILLEGAL_ARGUMENT_ERROR
                                                                                                    [\p{IsEmoji_Presentation}\p{IsExtended_Pictographic}]
                                                                                                    	at java.util.regex.Pattern.compileImpl(Native Method)
                                                                                                    	at java.util.regex.Pattern.compile(Pattern.java:1344)
                                                                                                    	at java.util.regex.Pattern.<init>(Pattern.java:1328)
                                                                                                    	at java.util.regex.Pattern.compile(Pattern.java:950)
                                                                                                    	at kotlin.text.Regex.<init>(Regex.kt:88)
                                                                                                    	at com.wisp.app.ml.NSpamFeatures.<clinit>(NSpamFeatures.kt:28)
                                                                                                    	... 15 more

Impact: On Android 9/API 28, certain relay-delivered reply notifications can repeatedly crash the app, making this a practical denial-of service vector for affected users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions