mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fixes TextInput crashes when any text is entered while running as iOS app on apple silicon mac (#49320)
Summary: Fixes https://github.com/facebook/react-native/issues/48544. We can make `RCTWeakEventEmitterWrapper` to subclass `NSDictionary` that Textinput supports encode it. System allowed classes are: ``` Allowed classes are: {( "'NSMorphology' (0x20088b6d8) [/System/Library/Frameworks/Foundation.framework]", "'NSString' (0x2003f4738) [/System/Library/Frameworks/Foundation.framework]", "'NSInflectionRule' (0x20088d348) [/System/Library/Frameworks/Foundation.framework]", "'UIColor' (0x2006c0520) [/System/iOSSupport/System/Library/PrivateFrameworks/UIKitCore.framework]", "'NSTextAttachment' (0x20042af98) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSShadow' (0x20042ae30) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSTextEncapsulation' (0x200897e50) [/System/Library/Frameworks/CoreText.framework]", "'NSTextAlternatives' (0x20042af70) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSFont' (0x20042a9f8) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSAttributedString' (0x2003f3838) [/System/Library/Frameworks/Foundation.framework]", "'NSData' (0x2003ed528) [/System/Library/Frameworks/CoreFoundation.framework]", "'NSURL' (0x2003ed938) [/System/Library/Frameworks/CoreFoundation.framework]", "'NSAdaptiveImageGlyph' (0x2008ae538) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSNumber' (0x2003f4238) [/System/Library/Frameworks/Foundation.framework]", "'NSParagraphStyle' (0x20042ad40) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSDictionary' (0x2003ed5a0) [/System/Library/Frameworks/CoreFoundation.framework]", "'UIFont' (0x20042c668) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSColor' (0x200412350) [/System/Library/Frameworks/AppKit.framework]", "'NSGlyphInfo' (0x20042aa98) [/System/Library/PrivateFrameworks/UIFoundation.framework]", "'NSArray' (0x2003ed460) [/System/Library/Frameworks/CoreFoundation.framework]", "'NSPresentationIntent' (0x20088da28) [/System/Library/Frameworks/Foundation.framework]" )} ``` ## Changelog: [IOS] [FIXED] - Fixes TextInput crashes when any text is entered while running as iOS app on apple silicon mac Pull Request resolved: https://github.com/facebook/react-native/pull/49320 Test Plan: Run RNTester on apple silicon mac, and entered some text in textinput, no crash occured. Also, verified that the caret was not jumping around, thus preserving the original fix. https://github.com/user-attachments/assets/6304f6e7-c663-4351-ace8-ab1842ee545f Reviewed By: javache Differential Revision: D69981500 Pulled By: cipolleschi fbshipit-source-id: 2af9b280e42f621446efda9b101af50525e8fef7
This commit is contained in:
committed by
React Native Bot
parent
68055f2d8a
commit
e2b081e66f
+1
-7
@@ -99,11 +99,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
||||
[_backedTextInputView.defaultTextAttributes mutableCopy];
|
||||
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
|
||||
eventEmitterWrapper.eventEmitter = _eventEmitter;
|
||||
defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
|
||||
#endif
|
||||
defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
|
||||
|
||||
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
||||
}
|
||||
@@ -263,10 +259,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
||||
if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
|
||||
NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
|
||||
RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
defaultAttributes[RCTAttributedStringEventEmitterKey] =
|
||||
_backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
|
||||
#endif
|
||||
_backedTextInputView.defaultTextAttributes = defaultAttributes;
|
||||
}
|
||||
|
||||
|
||||
+24
-3
@@ -52,8 +52,29 @@ BOOL RCTIsAttributedStringEffectivelySame(
|
||||
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
||||
const facebook::react::TextAttributes &baseTextAttributes);
|
||||
|
||||
@interface RCTWeakEventEmitterWrapper : NSObject
|
||||
@property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
|
||||
@end
|
||||
static inline NSData *RCTWrapEventEmitter(const facebook::react::SharedEventEmitter &eventEmitter)
|
||||
{
|
||||
auto eventEmitterPtr = new std::weak_ptr<const facebook::react::EventEmitter>(eventEmitter);
|
||||
return [[NSData alloc] initWithBytesNoCopy:eventEmitterPtr
|
||||
length:sizeof(eventEmitterPtr)
|
||||
deallocator:^(void *ptrToDelete, NSUInteger) {
|
||||
delete (std::weak_ptr<facebook::react::EventEmitter> *)ptrToDelete;
|
||||
}];
|
||||
}
|
||||
|
||||
static inline facebook::react::SharedEventEmitter RCTUnwrapEventEmitter(NSData *data)
|
||||
{
|
||||
if (data.length == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto weakPtr = dynamic_cast<std::weak_ptr<const facebook::react::EventEmitter> *>(
|
||||
(std::weak_ptr<const facebook::react::EventEmitter> *)data.bytes);
|
||||
if (weakPtr) {
|
||||
return weakPtr->lock();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
+1
-43
@@ -16,45 +16,6 @@
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@implementation RCTWeakEventEmitterWrapper {
|
||||
std::weak_ptr<const EventEmitter> _weakEventEmitter;
|
||||
}
|
||||
|
||||
- (void)setEventEmitter:(SharedEventEmitter)eventEmitter
|
||||
{
|
||||
_weakEventEmitter = eventEmitter;
|
||||
}
|
||||
|
||||
- (SharedEventEmitter)eventEmitter
|
||||
{
|
||||
return _weakEventEmitter.lock();
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_weakEventEmitter.reset();
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
// We consider the underlying EventEmitter as the identity
|
||||
if (![object isKindOfClass:[self class]]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
auto thisEventEmitter = [self eventEmitter];
|
||||
auto otherEventEmitter = [((RCTWeakEventEmitterWrapper *)object) eventEmitter];
|
||||
return thisEventEmitter == otherEventEmitter;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
// We consider the underlying EventEmitter as the identity
|
||||
return (NSUInteger)_weakEventEmitter.lock().get();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
|
||||
{
|
||||
assert(fontWeight > 50);
|
||||
@@ -405,10 +366,8 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
|
||||
{
|
||||
auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
|
||||
|
||||
#if !TARGET_OS_MACCATALYST
|
||||
if (fragment.parentShadowView.componentHandle) {
|
||||
RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
|
||||
eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
|
||||
auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
|
||||
|
||||
NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
|
||||
@{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
|
||||
@@ -416,7 +375,6 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
|
||||
[nsAttributedStringFragment addAttributes:additionalTextAttributes
|
||||
range:NSMakeRange(0, nsAttributedStringFragment.length)];
|
||||
}
|
||||
#endif
|
||||
|
||||
return nsAttributedStringFragment;
|
||||
}
|
||||
|
||||
+4
-5
@@ -280,11 +280,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
// after (fraction == 1.0) the last character, then the attribute is valid.
|
||||
if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
|
||||
(fraction < 1 || characterIndex < textStorage.length - 1)) {
|
||||
RCTWeakEventEmitterWrapper *eventEmitterWrapper =
|
||||
(RCTWeakEventEmitterWrapper *)[textStorage attribute:RCTAttributedStringEventEmitterKey
|
||||
atIndex:characterIndex
|
||||
effectiveRange:NULL];
|
||||
return eventEmitterWrapper.eventEmitter;
|
||||
NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
|
||||
atIndex:characterIndex
|
||||
effectiveRange:NULL];
|
||||
return RCTUnwrapEventEmitter(eventEmitterWrapper);
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
Reference in New Issue
Block a user