Skip to content

Commit 58c3a4c

Browse files
ericlewisfacebook-github-bot
authored andcommitted
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: #23609 Differential Revision: D14198159 Pulled By: mdvacca fbshipit-source-id: 71060b1b99ddab89793c98c09f99ec9974479e62
1 parent e903d80 commit 58c3a4c

File tree

4 files changed

+12
-8
lines changed

4 files changed

+12
-8
lines changed

RNTester/js/TextExample.android.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -615,11 +615,13 @@ class TextExample extends React.Component<{}> {
615615
Works with other text styles
616616
</Text>
617617
</RNTesterBlock>
618+
<RNTesterBlock title="Substring Emoji (should only see 'test')">
619+
<Text>{'test🙃'.substring(0, 5)}</Text>
620+
</RNTesterBlock>
618621
</RNTesterPage>
619622
);
620623
}
621624
}
622-
623625
const styles = StyleSheet.create({
624626
backgroundColorText: {
625627
left: 5,

RNTester/js/TextExample.ios.js

+6
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,12 @@ exports.examples = [
428428
);
429429
},
430430
},
431+
{
432+
title: "Substring Emoji (should only see 'test')",
433+
render: function() {
434+
return <Text>{'test🙃'.substring(0, 5)}</Text>;
435+
},
436+
},
431437
{
432438
title: 'Text metrics',
433439
render: function() {

ReactCommon/jsi/JSCRuntime.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,10 @@ class JSCRuntime : public jsi::Runtime {
246246
// JSStringRef utilities
247247
namespace {
248248
std::string JSStringToSTLString(JSStringRef str) {
249-
std::string result;
250249
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
251-
result.resize(maxBytes);
252-
size_t bytesWritten = JSStringGetUTF8CString(str, &result[0], maxBytes);
253-
// JSStringGetUTF8CString writes the null terminator, so we want to resize
254-
// to `bytesWritten - 1` so that `result` has the correct length.
255-
result.resize(bytesWritten - 1);
256-
return result;
250+
std::vector<char> buffer(maxBytes);
251+
JSStringGetUTF8CString(str, buffer.data(), maxBytes);
252+
return std::string(buffer.data());
257253
}
258254

259255
JSStringRef getLengthString() {

0 commit comments

Comments
 (0)