Skip to content

Commit 5221609

Browse files
committed
webview: Encode input messages in base64
Fixes #2505 #2538 #2558 When using `postMessage` to communicate with the WebView, depending on the content of the message we send, an exception might be thrown. A minimal but reliable way to reproduce the issue is to send the string `'%22'`. Other character combinations might also cause issues. Messages are sent to the WebView in different ways for iOS/Android. This explains why the issue this is fixing is Android-specific. In iOS, a custom navigation scheme is used to pass the data into the webview (the RCTJSNavigationScheme constant one can grep for) More interesting source code reading on that can be done if one looks at `webViewDidFinishLoad` in `RTCWebView.m`. The Android messaging happens in `receiveCommand` in `ReactWebViewManager.java` It is passed by navigating to a URL of the type `javascript:(.....)` which is a standard way of injecting JavaScript into webpages. The issue comes from the fact that `loadUrl` since Android 4.4 does an URL decode on the string passed to it: https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String) `evaluateJavascript` does not: https://developer.android.com/reference/android/webkit/WebView.html#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
1 parent 74e9499 commit 5221609

File tree

3 files changed

+6
-3
lines changed

3 files changed

+6
-3
lines changed

src/webview/MessageListWeb.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import getHtml from './html/html';
1010
import renderMessagesAsHtml from './html/renderMessagesAsHtml';
1111
import { getInputMessages } from './webViewHandleUpdates';
1212
import * as webViewEventHandlers from './webViewEventHandlers';
13+
import { objToBase64 } from '../utils/encoding';
1314

1415
export default class MessageListWeb extends Component<Props> {
1516
context: Context;
@@ -29,7 +30,7 @@ export default class MessageListWeb extends Component<Props> {
2930

3031
sendMessages = (messages: WebviewInputMessage[]): void => {
3132
if (this.webview && messages.length > 0) {
32-
this.webview.postMessage(JSON.stringify(messages), '*');
33+
this.webview.postMessage(objToBase64(messages), '*');
3334
}
3435
};
3536

src/webview/js/generatedEs3.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ var messageHandlers = {
241241
document.addEventListener('message', function (e) {
242242
scrollEventsDisabled = true;
243243
244-
var messages = JSON.parse(e.data);
244+
var decodedData = decodeURIComponent(escape(window.atob(e.data)));
245+
var messages = JSON.parse(decodedData);
245246
messages.forEach(function (msg) {
246247
messageHandlers[msg.type](msg);
247248
});

src/webview/js/js.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ const messageHandlers = {
261261
document.addEventListener('message', e => {
262262
scrollEventsDisabled = true;
263263
// $FlowFixMe
264-
const messages: WebviewInputMessage[] = JSON.parse(e.data);
264+
const decodedData = decodeURIComponent(escape(window.atob(e.data)));
265+
const messages: WebviewInputMessage[] = JSON.parse(decodedData);
265266
messages.forEach((msg: WebviewInputMessage) => {
266267
// $FlowFixMe
267268
messageHandlers[msg.type](msg);

0 commit comments

Comments
 (0)