From 46354c39380731c377021f5b6ae8d20ab4c1886f Mon Sep 17 00:00:00 2001 From: Aleksey Kondakov <112566801+A-Kimpo@users.noreply.github.com> Date: Mon, 26 Oct 2026 02:46:39 +0500 Subject: [PATCH] Fix: unmounted secureTextEntry TextInput retained by the measurement cache Added logic to strip specific spans from the text buffer to prevent memory leaks. --- .../com/facebook/react/views/textinput/ReactEditText.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt index 5858f865273f..73b4de50289a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt @@ -32,6 +32,8 @@ import android.text.TextUtils import android.text.TextWatcher import android.text.method.KeyListener import android.text.method.QwertyKeyListener +import android.text.style.CharacterStyle +import android.text.style.ParagraphStyle import android.util.TypedValue import android.view.ActionMode import android.view.DragEvent @@ -1242,6 +1244,12 @@ public open class ReactEditText public constructor(context: Context) : AppCompat } catch (e: IndexOutOfBoundsException) { logSoftException(TAG, e) } + // The copy only feeds measurement, so drop editor bookkeeping spans. Some of them reference + // this view's Editable (PasswordTransformationMethod.Visible), and the cache is evicted only + // from finalize(), so keeping them would keep this view reachable for good. + stripSpansOfKind(sb, Any::class.java) { span -> + span !is CharacterStyle && span !is ParagraphStyle && span !is ReactSpan + } } // If we don't have text, make sure we have *something* to measure.