Skip to content

Commit caba1cb

Browse files
ericlewisgrabbou
authored andcommitted
Fix crash when calling substring() on a string containing emoji. (facebook#23609)
Summary: Fixes facebook#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: facebook#23609 Differential Revision: D14198159 Pulled By: mdvacca fbshipit-source-id: 71060b1b99ddab89793c98c09f99ec9974479e62
1 parent 370947d commit caba1cb

File tree

4 files changed

+12
-8
lines changed

4 files changed

+12
-8
lines changed
1.69 KB
Loading

RNTester/js/TextExample.android.js

Lines changed: 3 additions & 1 deletion
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,10 @@ class JSCRuntime : public jsi::Runtime {
238238
// JSStringRef utilities
239239
namespace {
240240
std::string JSStringToSTLString(JSStringRef str) {
241-
std::string result;
242241
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
243-
result.resize(maxBytes);
244-
size_t bytesWritten = JSStringGetUTF8CString(str, &result[0], maxBytes);
245-
// JSStringGetUTF8CString writes the null terminator, so we want to resize
246-
// to `bytesWritten - 1` so that `result` has the correct length.
247-
result.resize(bytesWritten - 1);
248-
return result;
242+
std::vector<char> buffer(maxBytes);
243+
JSStringGetUTF8CString(str, buffer.data(), maxBytes);
244+
return std::string(buffer.data());
249245
}
250246

251247
JSStringRef getLengthString() {

0 commit comments

Comments
 (0)