925678181f45
fix: Autofill no longer crashes on third-party apps with malformed hint arrays (v2.14.11)
- time
- 2026-08-07 20:15 UTC · 2 months ago
- machine
- koh2
- parent
- 211e2d3269c5
↓ peach-android-92567818.tar.gzatlas at this save
files changed3 files
VERSION+1 −1app/src/main/java/com/peachpasswords/autofill/AssistStructureParser.kt+9 −2app/src/test/java/com/peachpasswords/autofill/AssistStructureNullHintsTest.kt+30 −0app/src/main/java/com/peachpasswords/autofill/AssistStructureParser.kt+9 −2
@@ -157,7 +157,7 @@157157 if (attrs["maxlength"] != "1") return false158158 return (attrs["type"]?.lowercase() ?: "") in setOf("", "text", "number", "tel")159159 }160- if (node.autofillHints?.any { it.equals("smsOTPCode", true) || it.equals("oneTimeCode", true) } == true) {160+ if (nonNullHints(node.autofillHints).any { it.equals("smsOTPCode", true) || it.equals("oneTimeCode", true) }) {161161 return true162162 }163163 val type = node.inputType@@ -171,8 +171,15 @@171171 172172 private enum class FieldKind { USERNAME, EMAIL, PASSWORD, OTP, CARD_NUMBER, CARD_EXP_MONTH, CARD_EXP_YEAR, CARD_EXP_DATE, CARD_CVC, CARD_NAME, NONE }173173 174+ /**175+ * Third-party apps supply the autofillHints array and some ship null176+ * entries (Facebook Messenger, 2026-08-07 Fold 7 crash loop). Hints are177+ * untrusted input: drop nulls so classification never dereferences one.178+ */179+ internal fun nonNullHints(hints: Array<String?>?): List<String> = hints?.filterNotNull().orEmpty()180+174181 private fun classify(node: AssistStructure.ViewNode): FieldKind {175- node.autofillHints?.forEach { hint ->182+ nonNullHints(node.autofillHints).forEach { hint ->176183 when (hint.lowercase()) {177184 View.AUTOFILL_HINT_PASSWORD, "password" -> return FieldKind.PASSWORD178185 View.AUTOFILL_HINT_USERNAME, "username" -> return FieldKind.USERNAMEapp/src/test/java/com/peachpasswords/autofill/AssistStructureNullHintsTest.kt+30 −0
@@ -0,0 +1,30 @@1+package com.peachpasswords.autofill2+3+import org.junit.Assert.assertEquals4+import org.junit.Assert.assertTrue5+import org.junit.Test6+7+/**8+ * Regression pin for the 2026-08-07 Fold 7 crash loop: Facebook Messenger9+ * presented an autofillHints array containing a null entry and classify()10+ * dereferenced it, crashing the autofill service on every fill request11+ * (One UI then surfaces the repeated "app keeps stopping" dialog). Hint12+ * arrays are third-party input and must never crash the parser.13+ */14+class AssistStructureNullHintsTest {15+16+ @Test fun null_hint_entries_are_dropped() {17+ assertEquals(18+ listOf("password", "username"),19+ AssistStructureParser.nonNullHints(arrayOf(null, "password", null, "username")),20+ )21+ }22+23+ @Test fun all_null_array_is_empty() {24+ assertTrue(AssistStructureParser.nonNullHints(arrayOf<String?>(null, null)).isEmpty())25+ }26+27+ @Test fun absent_hints_is_empty() {28+ assertTrue(AssistStructureParser.nonNullHints(null).isEmpty())29+ }30+}