On Android (I couldn't test on iOS), with react-native 0.58.3, try to call substring(0,1) on a string that begins with an emoji.
You should get this error: [Error: Exception in HostFunction: basic_string::resize]
I guess this is linked to some bad conversion from UTF 16 to UTF 8.
This is not happening on 0.57.3 for instance (which I was using earlier for the same project)
const text = 'πblablabla'
try {
const newText = text.substring(0, 1)
Alert.alert(newText)
} catch(e) {
console.error(e)
}
React Native Environment Info:
System:
OS: macOS High Sierra 10.13.5
CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Memory: 41.97 MB / 8.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.15.0 - ~/.nvm/versions/node/v10.15.0/bin/node
Yarn: 1.12.3 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v10.15.0/bin/npm
Watchman: 4.7.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 10.3, macOS 10.12, tvOS 10.2, watchOS 3.2
Android SDK:
API Levels: 23, 24, 25, 26, 27, 28
Build Tools: 23.0.1, 23.0.2, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 26.0.3, 27.0.1, 27.0.3, 28.0.0, 28.0.3
System Images: android-27 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom_64
IDEs:
Android Studio: 3.1 AI-173.4670197
Xcode: 8.3.3/8E3004b - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.58.3 => 0.58.3
npmGlobalPackages:
react-native-git-upgrade: 0.2.7
I'm having a similiar issue on ios. Seems to be something to do with character boundaries on that emoji. Have tested with the following. Both fail on iOS 0.58.4
let emojiString = 'π';
<Text>{emojiString.charAt(0)}</Text>
<Text>{emojiString[0]}</Text>
I've been reliably informed that these aren't really supposed to work. The best way to do this for future use is: <Text>Array.from(emojiString)[0]</Text>
@OlivierFreyssinet this is a limitation of multi-byte characters in JS strings. While ideally it shouldn't crash/error so badly in React Native it is something that should be accounted for in user-land JS.
'π'.length
// 2
As you can see this is a multi-byte character so you'll need to use multi-byte compatible operations if you want to handle the emoji correctly.
As @wakeless pointed out using Array.from() should be safer in most cases however it will give surprising results on emojis that use joining characters like π©ββ€οΈβπβπ©:
'π©ββ€οΈβπβπ©'.length
// 11
Array.from('π©ββ€οΈβπβπ©')
// ["π©", "", "β€", "", "", "π", "", "π©"]
If you want to handle these cases, a library like https://www.npmjs.com/package/runes might useful.
import runes from "runes";
runes('π©ββ€οΈβπβπ©')
// ["π©ββ€οΈβπβπ©"]
@levibuzolic thanks for your reply!
Indeed Array.from() should be safer but the problem here is not that the emojis are not split correctly. It would be perfectly fine for me if it was handled in the same way as on previous RN versions, ie "π".substring(0,1) resulting in a "οΏ½" character.
In fact I think that there's a problem in the new JSC introduced in 0.58, because Array.from("π") throws the exact same error.
To be perfectly clear, this bug report isn't about an "unexpected result" but about an error that, if it's not caught, will make the app crash.
I'm having a similiar issue on ios. Seems to be something to do with character boundaries on that emoji. Have tested with the following. Both fail on iOS 0.58.4
let emojiString = 'π'; <Text>{emojiString.charAt(0)}</Text> <Text>{emojiString[0]}</Text>
Hi @wakeless ! Is it crashing or just displaying "οΏ½"/something similar?
Thanks everyone for reporting, since it's related to the JSC I'll try to ask around if someone can confirm this.
In the meantime, would anyone of you be kind enough to create a repro?
Actually, could you first test with the 0.59rc and LMK if it still happens?
@kelset thanks for your reply!
I just tried with the 0.59rc and it's still happening. I'm creating a repo right now.
There you go @kelset, it runs on RN 0.59.0-rc.1
https://github.com/OlivierFreyssinet/rn-substring-error
New JSC came in 0.59 not 0.58.
0.58 brought in Android 64-bit support so maybe the issue is just about 64-bit devices, in case your device is one too.
I can confirm that this issue occurs on iOS as well, it appears something else has changed. I am looking in to it.
Error: Exception in HostFunction: basic_string
Encountered this mistake also but when I console.log the split data is ok. why happend this.
My experience with emoji in strings is that the app crash if the emoji is first character in the string, but it works if the string starts with normal character (unicode or not).
On iOS, Array.from works well, but android crash also.
try
(obj.str).substring(0, 1);
Most helpful comment
@OlivierFreyssinet this is a limitation of multi-byte characters in JS strings. While ideally it shouldn't crash/error so badly in React Native it is something that should be accounted for in user-land JS.
As you can see this is a multi-byte character so you'll need to use multi-byte compatible operations if you want to handle the emoji correctly.
As @wakeless pointed out using
Array.from()should be safer in most cases however it will give surprising results on emojis that use joining characters like π©ββ€οΈβπβπ©:If you want to handle these cases, a library like https://www.npmjs.com/package/runes might useful.