Skip to content

Multiline Strings are not passed to the jsBridge correctly #347

@secondsun

Description

@secondsun

When a multiline string is passed from a Kotlin/JS bridge to a JavaScript callback, the newlines aren't properly escaped, causing the JSON to become invalid. This prevents the JavaScript from successfully parsing the data.

Steps to Reproduce

  1. Call a method using the JSON bridge that returns a multiline string via its callback parameter.
  2. Attempt to parse the JSON response passed to the callback.

Expected Behavior

The JSON containing the multiline string should be properly escaped (e.g., \n) when passed from Kotlin to JavaScript. This would allow the JavaScript JSON.parse() method to successfully deserialize the data, and the text would display correctly in the webview.

Actual Behavior

The newline characters in the multiline string are not escaped. Instead, they are passed as literal newline characters. This breaks the JSON format, causing a SyntaxError in the JavaScript JSON.parse() method and preventing the data from being used.

For example, in my webview I call the bridge like this :

window.webBridge.callNative("Init",JSON.stringify({}),
              function (data) {
                   console.log("Init Done", typeof data);
                   try {
                        data = JSON.parse(data);
                        try {
                            console.log("data", data);
                            document.body.innerHTML = data.text;
                        } catch (e) {
                            console.log("Error updating text ", data, e);
                        }
                    } catch (e) {
                        console.log("Error parsing data", e);
                    }


              }
            );

And this is handled with the following handler :

class InitJsBridgeHandler(): IJsMessageHandler  {
    override fun methodName(): String {
        return "Init"
    }

    override fun handle(
        message: JsMessage,
        navigator: WebViewNavigator?,
        callback: (String) -> Unit
    ) {
        val data = InitResult("""
            This is a multiline kotlin string.
            This should be displayed in the webview.
            The quick brown fox jumps over the lazy dog.
        """.trimIndent())
        val jsonString = dataToJsonString(data)
        callback(jsonString)
    }

}

@Serializable
data class InitResult(val text : String)

The string does not get printed in the web view, instead the following error is logged :

[0807/210621.900:INFO:CONSOLE(17)] "Error parsing data SyntaxError: Bad control character in string literal in JSON at position 43 (line 1 column 44)", source: https://secondsun.github.io/compose-multiplatform-webview-jsbridge-demo/ (17)

If I log the raw data parameter in the javascript console, I see the json is printed as a multiline string and not a string with escaped newlines. JSON requires the newlines to be escaped so it can be parsed in javascript.

I have created a project for reproduction : https://github.com/secondsun/compose-multiplatform-webview-jsbridge-demo/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions