Skip to content

Commit

Permalink
Fix possible NSOutOfRangeException when updating typing attributes in…
Browse files Browse the repository at this point in the history
… response to new text content

Summary:
We may see an NSOutOfRangeException 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 NSOutOfRangeException when updating typing attributes in response to new text content

Differential Revision: D66202986
  • Loading branch information
NickGerleman authored and facebook-github-bot committed Nov 20, 2024
1 parent a865975 commit 9cb4f6f
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 9cb4f6f

Please sign in to comment.