Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

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

Aberta Para iniciantes
#423 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
65/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Pouca atividade
Stack de tecnologia
android, java
Domínio
mobile

Direção de pesquisa

Leia app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java por volta das linhas 2019–2026, começando pela lógica de backspace acelerado e pela forma como ela lê o ponto de código antes do cursor. Verifique o comprimento da exclusão tanto para um caractere comum seguido de um emoji quanto para um emoji seguido de um caractere comum; está concluído quando a segunda exclusão usa o ponto de código lido novamente e não divide um emoji nem exclui um caractere comum a mais.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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.

Linguagem predominante
Kotlin
Estrelas
1k
Forks
59
Merge médio
13h 11min
PRs com merge (30d)
47

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de LeanBitLab/LeanType

Todas as issues de LeanBitLab/LeanType

Issues semelhantes

Mais issues de Kotlin

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.