Skip to content

Commit 8c86966

Browse files
committed
Release v1.8.86 — keyVariation honours TYPE_NUMBER_VARIATION_PASSWORD
EditorInstance.handleStartInputView previously hard-coded keyVariation to NORMAL for every Type.NUMBER field. That bypassed every privacy gate keyed on keyVariation == PASSWORD for TYPE_NUMBER_VARIATION_PASSWORD fields (numeric PIN / OTP entry) — most importantly the clipboard-history exclusion in performClipboardCut / performClipboardCopy, so copied PINs could land in the IME-local clipboard history. Numeric PIN fields now propagate keyVariation = PASSWORD while still selecting KeyboardMode.NUMERIC for the layout, so all existing keyVariation gates fire (clipboard history, glide delete suppression, long-press popup suppression, suggestion suppression). FLAG_SECURE on the IME window was already correct via InputAttributes.Variation.PASSWORD; only the keyVariation-side gate had the gap. Follow-up #1 from the v1.8.85 audit.
1 parent 5692031 commit 8c86966

3 files changed

Lines changed: 81 additions & 3 deletions

File tree

RELEASE_NOTES_v1.8.86.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Release v1.8.86 — keyVariation honours TYPE_NUMBER_VARIATION_PASSWORD
2+
3+
Date: 2026-05-17
4+
5+
Follow-up #1 from the v1.8.85 audit pass.
6+
7+
## What changed
8+
9+
[app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt](app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt#L75-L120)
10+
— in `handleStartInputView`, when the focused field reports
11+
`InputAttributes.Type.NUMBER`, `activeState.keyVariation` was hard-coded to
12+
`KeyVariation.NORMAL`. That meant `TYPE_NUMBER_VARIATION_PASSWORD` fields
13+
(numeric PIN / OTP entry — bank PINs, app-lock PINs, TOTP codes) bypassed
14+
every privacy gate keyed on `keyVariation == KeyVariation.PASSWORD`,
15+
including the clipboard-history exclusion in
16+
`performClipboardCut` / `performClipboardCopy`.
17+
18+
Net effect before this fix: a user copying a numeric OTP out of the IME
19+
selection (rare but possible) wrote the OTP into the IME-local clipboard
20+
history, where it would surface on the next clipboard-palette open.
21+
[FlorisImeService.applyFlagSecureForCurrentField](app/src/main/kotlin/dev/patrickgold/florisboard/FlorisImeService.kt#L562)
22+
already covered the FLAG_SECURE side via `InputAttributes.variation ==
23+
Variation.PASSWORD` (numeric PIN variation maps cleanly into that enum), so
24+
the IME window was correctly opaque to screenshots; only the local
25+
clipboard-history write was unguarded.
26+
27+
After this fix: numeric PIN fields propagate `keyVariation = PASSWORD`
28+
while still selecting `KeyboardMode.NUMERIC` for the actual layout, so all
29+
existing `keyVariation == PASSWORD` gates fire — clipboard history, glide
30+
delete suppression (see TextKeyboardLayout.kt:151 / 646 / 788), long-press
31+
popup suppression (TextKey.kt:88), and the `isComposingEnabled` /
32+
suggestion-suppression branch.
33+
34+
## Why this is a separate release
35+
36+
Per [AGENTS.md §6](AGENTS.md) (one logical improvement per release).
37+
v1.8.85 was an explicit cross-subsystem exception; subsequent follow-ups
38+
return to per-feature commits.
39+
40+
## Files touched
41+
42+
- `app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt`
43+
- `gradle.properties` — versionCode 1886 / versionName 1.8.86
44+
45+
## Verification
46+
47+
```powershell
48+
./gradlew.bat :app:testDebugUnitTest
49+
./gradlew.bat :app:lintDebug
50+
./gradlew.bat :app:assembleDebug
51+
./gradlew.bat :app:installDebug
52+
```
53+
54+
Manual QA:
55+
- Focus a field declared `android:inputType="numberPassword"`. Verify the
56+
numeric keyboard appears (mode preserved). Long-press a digit key —
57+
popup should be suppressed (now-active PASSWORD gate).
58+
- Type some digits, select them via the system selection handles, tap the
59+
IME's Cut/Copy quick action if shown. Open the clipboard palette and
60+
confirm the digits do NOT appear in the history pane. Pre-fix they did.
61+
- Focus a regular numeric field (no `numberPassword` flag). Verify
62+
long-press popups still work and clipboard cut/copy still writes to
63+
history.

app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,22 @@ class EditorInstance(context: Context) : AbstractEditorInstance(context) {
7575
super.handleStartInputView(editorInfo, isRestart)
7676
val keyboardMode = when (editorInfo.inputAttributes.type) {
7777
InputAttributes.Type.NUMBER -> {
78-
activeState.keyVariation = KeyVariation.NORMAL
78+
// TYPE_NUMBER_VARIATION_PASSWORD (numeric PIN / OTP fields)
79+
// collapses to InputAttributes.Variation.PASSWORD. Mirror
80+
// that through to keyVariation so the privacy gates that
81+
// key off `keyVariation == KeyVariation.PASSWORD`
82+
// (clipboard history in EditorInstance.performClipboardCut /
83+
// performClipboardCopy, suggestion suppression here, glide /
84+
// long-press scaling in TextKeyboardLayout, etc.) all fire
85+
// for PIN entry. Without this, a numeric-PIN copy lands in
86+
// the IME-local clipboard history.
87+
activeState.keyVariation = if (editorInfo.inputAttributes.variation ==
88+
InputAttributes.Variation.PASSWORD
89+
) {
90+
KeyVariation.PASSWORD
91+
} else {
92+
KeyVariation.NORMAL
93+
}
7994
KeyboardMode.NUMERIC
8095
}
8196
InputAttributes.Type.PHONE -> {

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ projectMinSdk=26
1515
projectTargetSdk=36
1616
projectCompileSdk=36
1717

18-
projectVersionCode=1885
19-
projectVersionName=1.8.85
18+
projectVersionCode=1886
19+
projectVersionName=1.8.86

0 commit comments

Comments
 (0)