[iOS] Fabric: SIGABRT on tab press when tab key contains non-ASCII characters (kCFStringEncodingUTF8 passed to -cStringUsingEncoding:)
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- ios, objective-c, react-native
- Domain
- mobile
Research direction
Start in packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm at the onPageSelectedWithKey: and onLongPressWithKey: call sites. Reproduce with the provided React Native sample using the non-ASCII 메시지 tab, then verify that pressing and long-pressing it no longer aborts under Fabric and that the emitted key remains valid UTF-8.
Written by the indexing model from the issue text.
Description
Before submitting a new issue
- I tested using the latest version of the library, as the bug might be already fixed.
- I tested using a supported version of react native.
- I checked for possible duplicate issues, with possible answers.
Bug summary
On the New Architecture (Fabric), pressing (or long-pressing) a tab whose key contains any non-ASCII character — Korean, Japanese, Chinese, Cyrillic, emoji, accented Latin, … — crashes the app instantly with SIGABRT.
RCTTabViewComponentView.mm builds the event payloads like this (L241, L250):
eventEmitter->onPageSelected(RNCTabViewEventEmitter::OnPageSelected{
.key = [key cStringUsingEncoding:kCFStringEncodingUTF8]
});
The problem: -cStringUsingEncoding: expects an NSStringEncoding (NSUTF8StringEncoding = 4), but the code passes kCFStringEncodingUTF8, which is a CFStringEncoding constant with the value 0x08000100. That value is not a valid NSStringEncoding (converting between the two families requires CFStringConvertEncodingToNSStringEncoding()).
What happens at runtime:
- For pure-ASCII keys the call happens to return a valid pointer (internal 8-bit buffer fast path), so the bug goes unnoticed in English-only apps.
- For keys containing non-ASCII characters, the conversion fails and
cStringUsingEncoding:returnsNULL(its documented behavior when the receiver cannot be converted to the given encoding). The generatedOnPageSelected/OnTabLongPressstructs declarekeyasstd::string, and constructing astd::stringfromNULLis undefined behavior →abort().
This affects every app using @bottom-tabs/react-navigation with non-ASCII screen names: react-navigation derives the route key from the screen name (a screen named 메시지 gets a route key like 메시지-AbC12xyz), and that route key is exactly what is passed to onPageSelectedWithKey: / onLongPressWithKey:. Tapping such a tab crashes immediately. Standalone TabView usage with non-ASCII navigationState route keys crashes the same way.
The old architecture is not affected (the whole file is #ifdef RCT_NEW_ARCH_ENABLED).
Library version
1.4.0 (latest release; the code is unchanged on current main — see permalinks above)
Environment info
System:
OS: macOS 26.6.1
Binaries:
Node: 22.22.1
npmPackages:
react: 19.1.0
react-native: 0.81.5
expo: ~54.0.0
react-native-bottom-tabs: 1.4.0
@bottom-tabs/react-navigation: 1.4.0
@react-navigation/native: 7.3.14
Settings:
newArchEnabled: true (Fabric)
Tested on: iPhone Simulator (iOS 26)
Steps to reproduce
- Create a React Native 0.81 app with the New Architecture enabled and install
react-native-bottom-tabs+@bottom-tabs/react-navigation. - Add a tab screen whose
namecontains non-ASCII characters, e.g.메시지(Korean). - Run the app on iOS and tap that tab (long-press also triggers it via
onTabLongPress). - The app aborts immediately — SIGABRT from the
std::stringconstructor being fedNULLinRCTTabViewComponentView.mm.
Reproducible sample code
import { NavigationContainer } from '@react-navigation/native';
import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation';
import { Text, View } from 'react-native';
const Tab = createNativeBottomTabNavigator();
const Screen = () => (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Hello</Text>
</View>
);
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={Screen} />
{/* Tapping this tab crashes the app on iOS (Fabric): */}
<Tab.Screen name="메시지" component={Screen} />
</Tab.Navigator>
</NavigationContainer>
);
}
Proposed fix
Use -UTF8String, which returns a proper UTF-8 C string for any NSString contents (with a ?: "" guard for the nil-receiver edge case), at both call sites:
--- a/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm
+++ b/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm
@@ -238,7 +238,7 @@ - (void)onPageSelectedWithKey:(NSString *)key reactTag:(NSNumber *)reactTag {
auto eventEmitter = std::static_pointer_cast<const RNCTabViewEventEmitter>(_eventEmitter);
if (eventEmitter) {
eventEmitter->onPageSelected(RNCTabViewEventEmitter::OnPageSelected{
- .key = [key cStringUsingEncoding:kCFStringEncodingUTF8]
+ .key = std::string([key UTF8String] ?: "")
});
}
}
@@ -247,7 +247,7 @@ - (void)onLongPressWithKey:(NSString *)key reactTag:(NSNumber *)reactTag {
auto eventEmitter = std::static_pointer_cast<const RNCTabViewEventEmitter>(_eventEmitter);
if (eventEmitter) {
eventEmitter->onTabLongPress(RNCTabViewEventEmitter::OnTabLongPress {
- .key = [key cStringUsingEncoding:kCFStringEncodingUTF8]
+ .key = std::string([key UTF8String] ?: "")
});
}
}
We are running exactly this as a patch-package patch in production and it fully resolves the crash. Happy to open a PR if you'd like.
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 108
- Avg merge
- 12h 42m
- Merged PRs (30d)
- 9
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from callstack/react-native-bottom-tabs
-
Difficulty 4/5 3-5 days Newbie friendliness 68/100
-
Difficulty 4/5 3-5 days Newbie friendliness 58/100
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
callstack/react-native-bottom-tabs#561 · 1 reaction ·
All issues in callstack/react-native-bottom-tabs
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
danielmiessler/LifeOS#2218 ·