Accelerated backspace measures the wrong code point and can split an emoji
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 65/100
調査の方向性
app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java の2019~2026行付近を読み、加速されたバックスペースのロジックと、カーソルの前にあるコードポイントをどのように読み取るかを確認してください。通常の文字の後に絵文字が続く場合と、絵文字の後に通常の文字が続く場合の両方について削除長を確認してください。2回目の削除で再読み込みしたコードポイントが使われ、絵文字を分割したり通常の文字を余分に削除したりしなければ完了です。
索引モデルが issue の本文から書いたものです。
説明
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, solengthToDeleteAgainis1. A singlecharis removed from a multi-charemoji, splitting it. - First char an emoji, second plain → the branch evaluates
true, sogetCharCountToDeleteBeforeCursor()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.
- 主要言語
- Kotlin
- スター
- 1k
- フォーク
- 59
- 平均マージ
- 13時間 21分
- マージ済み PR(30日)
- 48
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
LeanBitLab/LeanType のほかの issue
-
Voice input fails in browser address bars due to incorrect password field detection (v4.2.9, follow-up to #516)対応中かも @LeanBitLab が今日担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
LeanBitLab/LeanType#713 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 3/5 1〜2日 初心者へのやさしさ 54/100
LeanBitLab/LeanType#717 ·
メンテナーはふだん 1 日以内に返信
-
Crush Report対応中かも @LeanBitLab が今日担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 20/100
LeanBitLab/LeanType#715 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Text Expander/cursor-handling bug対応中かも @LeanBitLab が 3 日前に担当しました。 オープンbug
難易度 3/5 1〜2日 初心者へのやさしさ 62/100
LeanBitLab/LeanType#703 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
LeanBitLab/LeanType#699 ·
メンテナーはふだん 1 日以内に返信
LeanBitLab/LeanType の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Kotlin/kotlinx-io#529 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
mcnaveen/health-connect-webhook#110 ·
メンテナーはふだん 1 日以内に返信
-
Delete all aboveオープンenhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
mjaakko/NeoStumbler#1307 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
tanujnotes/Olauncher#770 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100