Skip to content

Commit

Permalink
Fix possible NSRangeException when updating typing attributes in resp…
Browse files Browse the repository at this point in the history
…onse to new text content (#47737)

Summary:
Pull Request resolved: #47737

We may see an NSRangeException when setting new AttributedString content, where setting the AttributedString itself changes selection (before we mutate it later).

It seems like the selection here is not in a good state yet in regards to the AttributedString backing exposed (since we are reading it while modifying it). So let's fold the logic for updating typing attributes into the collection of ignored work from non-user-selection updates, since programatically setting an AttributedString will already trigger updating typing attributes.

I also added a nil check here, which is unrelated to the crash, but it seems like we should have it for safety...

Changelog:
[iOS][Fixed] - Fix possible NSRangeException when updating typing attributes in response to new text content

Reviewed By: cipolleschi

Differential Revision: D66202986

fbshipit-source-id: fded492b5022c5fef5b9563f93a57549d06a7020
  • Loading branch information
NickGerleman authored and facebook-github-bot committed Nov 20, 2024
1 parent 48ea686 commit 6e06a81
Showing 1 changed file with 7 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,15 @@ - (void)textInputDidChange

- (void)textInputDidChangeSelection
{
[self _updateTypingAttributes];
if (_comingFromJS) {
return;
}

// T207198334: Setting a new AttributedString (_comingFromJS) will trigger a selection change before the backing
// string is updated, so indicies won't point to what we want yet. Only respond to user selection change, and let
// `_setAttributedString` handle updating typing attributes if content changes.
[self _updateTypingAttributes];

const auto &props = static_cast<const TextInputProps &>(*_props);
if (props.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
[self textInputDidChange];
Expand Down Expand Up @@ -722,7 +727,7 @@ - (void)_setAttributedString:(NSAttributedString *)attributedString
// https://github.com/facebook/react-native/blob/3102a58df38d96f3dacef0530e4dbb399037fcd2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/internal/span/SetSpanOperation.kt#L30
- (void)_updateTypingAttributes
{
if (_backedTextInputView.attributedText.length > 0) {
if (_backedTextInputView.attributedText.length > 0 && _backedTextInputView.selectedTextRange != nil) {
NSUInteger offsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument
toPosition:_backedTextInputView.selectedTextRange.start];

Expand Down

0 comments on commit 6e06a81

Please sign in to comment.