Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Accelerated backspace measures the wrong code point and can split an emoji

Aperta Adatta ai principianti
#423 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
65/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
android, java
Ambito
mobile

Direzione di ricerca

Leggi app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java intorno alle righe 2019–2026, iniziando dalla logica di backspace accelerato e da come legge il code point prima del cursore. Controlla la lunghezza dell’eliminazione sia per un carattere normale seguito da un’emoji, sia per un’emoji seguita da un carattere normale; il lavoro è concluso quando la seconda eliminazione usa il code point riletto e non divide un’emoji né elimina un carattere normale in eccesso.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

In InputLogic.handleBackspaceEvent, the accelerated (held-backspace) second deletion measures its length from the first code point instead of the one it is actually about to delete. When the second character back is a multi-code-point emoji, this deletes the wrong number of chars and can split the emoji, leaving an orphaned surrogate or a stray variation selector / ZWJ.

Present at tag v4.1.2 (f0ff166ae).

Location

app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java, around lines 2019–2026:

final int codePointBeforeCursorToDeleteAgain = mConnection.getCodePointBeforeCursor();
if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) {
    final int lengthToDeleteAgain = codePointBeforeCursor > 0xFE00          // <-- first code point
            || StringUtils.mightBeEmoji(codePointBeforeCursor)              // <-- first code point
                    ? mConnection.getCharCountToDeleteBeforeCursor()
                    : 1;
    mConnection.deleteTextBeforeCursor(lengthToDeleteAgain);
    totalDeletedLength += lengthToDeleteAgain;
}

The guard correctly re-reads the cursor into codePointBeforeCursorToDeleteAgain, but the ternary that decides the delete length still tests codePointBeforeCursor — the value from before the first deletion.

Consequences

Both directions are wrong:

  • First char plain, second an emoji → the branch evaluates false, so lengthToDeleteAgain is 1. A single char is removed from a multi-char emoji, splitting it.
  • First char an emoji, second plain → the branch evaluates true, so getCharCountToDeleteBeforeCursor() is used against a plain character and may remove more than intended.

Only reachable once mDeleteCount > Constants.DELETE_ACCELERATE_AT, i.e. while holding backspace, which is probably why it has gone unnoticed.

Suggested fix

Use the re-read value in the condition, so it describes the character actually being deleted:

final int lengthToDeleteAgain = codePointBeforeCursorToDeleteAgain > 0xFE00
        || StringUtils.mightBeEmoji(codePointBeforeCursorToDeleteAgain)
                ? mConnection.getCharCountToDeleteBeforeCursor()
                : 1;

Notes

Found while merging v4.1.2 into a downstream fork. This almost certainly predates LeanType — the surrounding accelerated-delete code comes from the HeliBoard/AOSP lineage — so it may be worth forwarding to Helium314/HeliBoard as well.

I have no reproduction on a physical device; this is from reading the code, so please sanity-check the emoji-splitting claim against real input before acting on it.

Lingua principale
Kotlin
Stelle
1k
Fork
59
Merge medio
13h 21m
PR unite (30g)
48

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di LeanBitLab/LeanType

Tutte le issue di LeanBitLab/LeanType

Issue simili

Altre issue su Kotlin

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.