Fix crash when calling substring() on a string containing emoji. (#23609)

Summary:
Fixes #23459. It is not legal to write the character array of a std::string, and can result in undefined behavior.

[General] [Fixed] - Crash when substring intersects with emoji
Pull Request resolved: https://github.com/facebook/react-native/pull/23609

Differential Revision: D14198159

Pulled By: mdvacca

fbshipit-source-id: 71060b1b99ddab89793c98c09f99ec9974479e62
This commit is contained in:
ericlewis 2019-03-01 00:53:00 -08:00 committed by Mike Grabowski
parent 370947d2b2
commit caba1cb2e1
4 changed files with 12 additions and 8 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 KiB

After

Width:  |  Height:  |  Size: 309 KiB

View File

@ -615,11 +615,13 @@ class TextExample extends React.Component<{}> {
Works with other text styles
</Text>
</RNTesterBlock>
<RNTesterBlock title="Substring Emoji (should only see 'test')">
<Text>{'test🙃'.substring(0, 5)}</Text>
</RNTesterBlock>
</RNTesterPage>
);
}
}
const styles = StyleSheet.create({
backgroundColorText: {
left: 5,

View File

@ -428,6 +428,12 @@ exports.examples = [
);
},
},
{
title: "Substring Emoji (should only see 'test')",
render: function() {
return <Text>{'test🙃'.substring(0, 5)}</Text>;
},
},
{
title: 'Text metrics',
render: function() {

View File

@ -238,14 +238,10 @@ class JSCRuntime : public jsi::Runtime {
// JSStringRef utilities
namespace {
std::string JSStringToSTLString(JSStringRef str) {
std::string result;
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
result.resize(maxBytes);
size_t bytesWritten = JSStringGetUTF8CString(str, &result[0], maxBytes);
// JSStringGetUTF8CString writes the null terminator, so we want to resize
// to `bytesWritten - 1` so that `result` has the correct length.
result.resize(bytesWritten - 1);
return result;
std::vector<char> buffer(maxBytes);
JSStringGetUTF8CString(str, buffer.data(), maxBytes);
return std::string(buffer.data());
}
JSStringRef getLengthString() {