Skip to content

Including %22 in Android WebView postMessage payload results in SyntaxError #19611

@jordoh

Description

@jordoh

Environment

Environment:
OS: Linux 4.16
Node: 9.11.1
Yarn: 1.6.0
npm: 6.0.1
Watchman: 4.9.0
Xcode: N/A
Android Studio: Not Found

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.4 => 0.55.4

Description

On Android 4.4 and above, WebView's loadUrl performs URL decoding on the string passed in. This results in a %22 being decoded to " prior to the javascript being executed. The extra un-escaped quote results in the javascript containing a syntax error, thus failing to execute.

There are (at least) two past and present PRs that have sought to address this in injectedJavascript, by using evaluateJavascript on 4.4 and above:
#12321
#9945

I can confirm that changing ReactWebViewmanager's receiveCommand to call root.evaluateJavascript results in the expected behavior.

Steps to Reproduce

  1. Create a new app using CRNA/Expo and change App.js to:
import React, { Component } from 'react';
import { Button, Dimensions, View, WebView } from 'react-native';

const html = `
<html>
  <body>
    <div id="element">test</div>
    
    <script type="text/javascript">
        document.addEventListener("message", function(event) {
          document.querySelector("#element").textContent = "success";
        });
    </script>
  </body>
</html>
`;

export default class App extends Component {
  postMessage(text) {
    this.webView.postMessage(text);
  }

  render() {
    const { height, width } = Dimensions.get("window");

    return (
      <View style={{ flex: 1 }}>
        <Button
          onPress={ () => this.postMessage("test") }
          title="postMessage without %22"
        />
        <Button
          onPress={ () => this.postMessage("test%22") }
          title="postMessage with %22"
        />
        <WebView
          ref={ webView => this.webView = webView }
          source={ { html } }
          style={ { height, width } }
        />
      </View>
    );
  }
}
  1. Run with react-native run-android.
  2. Press postMessage with %22 button.

Expected Behavior

Text inside the WebView should change from "test" to "success". Expected behavior can be observed by pressing the postMessage without %22 button.

Actual Behavior

Text inside the WebView does not change.

Inspecting the WebView with Chrome reveals the following error: Uncaught SyntaxError: Invalid or unexpected token

e.g. after clicking the button 4 times:
image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions