Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JSStringToSTLString: truncate string on conversion failure
Summary: [A recent change to JSStringToSTLString](#26955) causes a crash when the function is invoked with invalid UTF-16 data. The old behaviour, restored here, was to truncate the string before the first invalid character. Here's how [the original code](https://github.com/facebook/react-native/blob/aee88b6843cea63d6aa0b5879ad6ef9da4701846/ReactCommon/jsi/JSCRuntime.cpp#L287) handled this case: ``` std::string JSStringToSTLString(JSStringRef str) { size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str); // ^ maxBytes >= 1 regardless of str's contents std::vector<char> buffer(maxBytes); // ^ vector is zero initialised JSStringGetUTF8CString(str, buffer.data(), maxBytes); // ^ writes '\0' at the first invalid character and returns early (see JSC source code) return std::string(buffer.data()); // ^ copies the string up to the first '\0' } ``` See the JSC implementations of [`JSStringGetUTF8CString`](https://opensource.apple.com/source/JavaScriptCore/JavaScriptCore-7600.8.7/API/JSStringRef.cpp.auto.html) and [`convertUTF16ToUTF8`](https://opensource.apple.com/source/WTF/WTF-7600.7.2/wtf/unicode/UTF8.cpp.auto.html). Based on the fact that `JSStringGetUTF8CString` *always* null-terminates the buffer - even when it bails out of converting an invalid string - here we're able to both 1. keep the fast path (not zero-initialising, not scanning for the null terminator) for the common case when the data is valid and JSStringGetUTF8CString returns a nonzero length; and 2. return the truncated string when JSStringGetUTF8CString returns an error code of 0, by scanning for the null terminator. Changelog: [General] [Fixed] - Fix crash when passing invalid UTF-16 data from JSC into native code Differential Revision: D19902751 fbshipit-source-id: 06bace2719800e921ec115ad6a29251eafd473f6
- Loading branch information