Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

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

Offen Anfängerfreundlich
#423 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
65/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Ruhig
Tech-Stack
android, java
Bereich
mobile

Rechercherichtung

Lies app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java ungefähr in den Zeilen 2019–2026, beginnend mit der beschleunigten Rückschrittslogik und damit, wie sie den Codepoint vor dem Cursor ausliest. Prüfe die Löschlänge sowohl für ein einfaches Zeichen, auf das ein Emoji folgt, als auch für ein Emoji, auf das ein einfaches Zeichen folgt; fertig ist es, wenn die zweite Löschung den erneut ausgelesenen Codepoint verwendet und weder ein Emoji aufteilt noch ein einfaches Zeichen zu viel löscht.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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.

Vorherrschende Sprache
Kotlin
Sterne
1k
Forks
59
Ø Merge
13 Std. 21 Min.
Gemergte PRs (30 T.)
48

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus LeanBitLab/LeanType

Alle Issues in LeanBitLab/LeanType

Ähnliche Issues

Weitere Issues zu Kotlin

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.