From e4f66944a7265307838d39e1fad8fbe8758af7b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Thu, 9 Aug 2018 11:10:11 -0700 Subject: [PATCH] Properly escape JavaScript code on Android (#20366) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: These changes will fix executing javascript with any special characters, by making use of the `evaluateJavascript` function on Android 4.4+, and by properly escaping the URI on Android <4.4. Fixes #19611 • Fixes #20365 • Fixes #9749 • Closes #19655 • Closes #12321 This PR supersedes #19655 by patching the same problem in all the places, and fixing it for Android <4.4 as well. Pull Request resolved: https://github.com/facebook/react-native/pull/20366 Differential Revision: D9242968 Pulled By: hramos fbshipit-source-id: f2e1abc786ba333dbd8aaa8922e716fd99ec26e0 --- .../views/webview/ReactWebViewManager.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java index 6bcc4e1857..6e55b80f8c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java @@ -16,6 +16,7 @@ import java.util.regex.Pattern; import javax.annotation.Nullable; import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; @@ -325,11 +326,25 @@ public class ReactWebViewManager extends SimpleViewManager { } } + protected void evaluateJavascriptWithFallback(String script) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + evaluateJavascript(script, null); + return; + } + + try { + loadUrl("javascript:" + URLEncoder.encode(script, "UTF-8")); + } catch (UnsupportedEncodingException e) { + // UTF-8 should always be supported + throw new RuntimeException(e); + } + } + public void callInjectedJavaScript() { if (getSettings().getJavaScriptEnabled() && injectedJS != null && !TextUtils.isEmpty(injectedJS)) { - loadUrl("javascript:(function() {\n" + injectedJS + ";\n})();"); + evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();"); } } @@ -348,7 +363,7 @@ public class ReactWebViewManager extends SimpleViewManager { }); } - loadUrl("javascript:(" + + evaluateJavascriptWithFallback("(" + "window.originalPostMessage = window.postMessage," + "window.postMessage = function(data) {" + BRIDGE_NAME + ".postMessage(String(data));" + @@ -637,9 +652,10 @@ public class ReactWebViewManager extends SimpleViewManager { break; case COMMAND_POST_MESSAGE: try { + ReactWebView reactWebView = (ReactWebView) root; JSONObject eventInitDict = new JSONObject(); eventInitDict.put("data", args.getString(0)); - root.loadUrl("javascript:(function () {" + + reactWebView.evaluateJavascriptWithFallback("(function () {" + "var event;" + "var data = " + eventInitDict.toString() + ";" + "try {" + @@ -655,7 +671,8 @@ public class ReactWebViewManager extends SimpleViewManager { } break; case COMMAND_INJECT_JAVASCRIPT: - root.loadUrl("javascript:" + args.getString(0)); + ReactWebView reactWebView = (ReactWebView) root; + reactWebView.evaluateJavascriptWithFallback(args.getString(0)); break; } }