Skip to content

fix(macos): stop a secure TextInput throwing as it takes focus - #3141

Open
Bron Davies (brondavies) wants to merge 1 commit into
microsoft:mainfrom
brondavies:fix/secure-text-field-delegate
Open

Bron Davies (brondavies) wants to merge 1 commit into
microsoft:mainfrom
brondavies:fix/secure-text-field-delegate

Conversation

@brondavies

Copy link
Copy Markdown

Summary:

Fixes #3138.

A TextInput with secureTextEntry crashes as it takes focus on macOS. -[NSSecureTextView setDelegate:] requires an NSSecureTextField and throws "NSSecureTextFieldCell is not secure because the secure field editor's delegate must be an NSSecureTextField!". Since #2895, RCTUISecureTextField subclasses RCTUITextField, with an NSSecureTextFieldCell for the masking and secure input.

This change makes the field answer isKindOfClass: for NSSecureTextField. That alone is not enough: NSSecureTextView then sends its delegate -_shouldShowIndicators as it draws, and the unrecognised selector throws from -[NSSecureTextView drawRect:]. We used the isKindOfClass: half alone in our app first, and it crashed that way a few minutes into using the field. NSSecureTextField answers that one from a flag that only its private setter turns on, so the field answers NO, as a real one does. From AppKit's disassembly, it's the only NSSecureTextField-only message NSSecureTextView sends its delegate.

The alternative is for RCTUISecureTextField to be a real NSSecureTextField subclass again, which #2895 moved away from. This keeps #2895's structure; happy to go the other way if you'd rather not answer a private selector.

Test Plan:

RNTester-macOS (Debug, arm64, Xcode 27.1, macOS 26.6.2), Playground showing <TextInput secureTextEntry={true} placeholder="Password" style={{borderWidth: 1, height: 30}} />:

  • On main, calling focus() on the field terminates the app with the exception in macOS: a secure TextInput crashes the app when it takes focus #3138.
  • With this change:
    • it focuses, and typing secret puts 6 characters in the field editor;
    • the field editor is an NSSecureTextView;
    • [firstResponder _shouldShowIndicators], evaluated in lldb, goes through the delegate path that crashed in drawRect: and returns NO.
  • The same two methods are in our app (react-native-macos 0.83.0) as a patch-package patch, where the password field focuses and takes typing, and the same lldb check returns NO.

Since RCTUISecureTextField became an RCTUITextField subclass with an NSSecureTextFieldCell (microsoft#2895), AppKit refuses it as the secure field editor's delegate: -[NSSecureTextView setDelegate:] throws "NSSecureTextFieldCell is not secure because the secure field editor's delegate must be an NSSecureTextField!" when the field becomes first responder.

It now answers isKindOfClass: for NSSecureTextField. NSSecureTextView then also sends it -_shouldShowIndicators while drawing, which NSSecureTextField answers from a flag that is off by default, so it answers NO.
@brondavies
Bron Davies (brondavies) requested a review from a team as a code owner October 23, 2026 15:07
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS: a secure TextInput crashes the app when it takes focus

1 participant