Skip to content

Commit

Permalink
Fix multiline TextInput crash when inserting/removing lots of text (#…
Browse files Browse the repository at this point in the history
…29307)

Summary:
Multiline `TextInput` can crash when really long texts are inserted and removed quickly. This is caused by the fact that [`-[NSAttributedString string]`](https://developer.apple.com/documentation/foundation/nsattributedstring/1412616-string?language=objc) doesn't really return a copy, and may mutate the string while it is being used by `convertIdToFollyDynamic`. See microsoft#489 (comment) for more details on the issue.

This issue was originally reported in microsoft#486 and was fixed in microsoft#489.

## Changelog

[iOS] [Fixed] - Fix multiline TextInput crash when inserting/removing lots of text

Pull Request resolved: #29307

Test Plan:
1. Open RNTester > TextInput
2. Search for a multiline example
3. Copy some large text and paste it into the text input view
4. Remove some (or all) text
5. Repeat steps 3-4

Reviewed By: shergin

Differential Revision: D22488854

Pulled By: JoshuaGross

fbshipit-source-id: 6fab7818d68538450d93460361ff5934caf86c10
  • Loading branch information
tido64 authored and facebook-github-bot committed Jul 17, 2020
1 parent 3137c44 commit 15dda0a
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions Libraries/Text/TextInput/RCTBaseTextInputView.m
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ - (void)textInputDidBeginEditing

[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
reactTag:self.reactTag
text:self.backedTextInputView.attributedText.string
text:[self.backedTextInputView.attributedText.string copy]
key:nil
eventCount:_nativeEventCount];
}
Expand All @@ -347,13 +347,13 @@ - (void)textInputDidEndEditing
{
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeEnd
reactTag:self.reactTag
text:self.backedTextInputView.attributedText.string
text:[self.backedTextInputView.attributedText.string copy]
key:nil
eventCount:_nativeEventCount];

[_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur
reactTag:self.reactTag
text:self.backedTextInputView.attributedText.string
text:[self.backedTextInputView.attributedText.string copy]
key:nil
eventCount:_nativeEventCount];
}
Expand All @@ -367,7 +367,7 @@ - (BOOL)textInputShouldReturn
// (no connection to any specific "submitting" process).
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit
reactTag:self.reactTag
text:self.backedTextInputView.attributedText.string
text:[self.backedTextInputView.attributedText.string copy]
key:nil
eventCount:_nativeEventCount];

Expand Down Expand Up @@ -422,7 +422,7 @@ - (NSString *)textInputShouldChangeText:(NSString *)text inRange:(NSRange)range
}
}

NSString *previousText = backedTextInputView.attributedText.string ?: @"";
NSString *previousText = [backedTextInputView.attributedText.string copy] ?: @"";

if (range.location + range.length > backedTextInputView.attributedText.string.length) {
_predictedText = backedTextInputView.attributedText.string;
Expand Down Expand Up @@ -468,7 +468,7 @@ - (void)textInputDidChange

if (_onChange) {
_onChange(@{
@"text": self.attributedText.string,
@"text": [self.attributedText.string copy],
@"target": self.reactTag,
@"eventCount": @(_nativeEventCount),
});
Expand Down

0 comments on commit 15dda0a

Please sign in to comment.