MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
427 stars 51 forks source link

certain flavor of prototype.js can break web message functionality #3021

Open szanto90balazs opened 1 year ago

szanto90balazs commented 1 year ago

Description

Native - JS web messaging is broken on some sites utilizing prototype.js.

Version SDK: 1.0.1418.22 Runtime: 107.0.1418.62 Framework: WPF OS: Win10

Repro Steps

I ran into the issue while I was visiting our Jenkins site, but I managed to narrow down the issue and make it reproducible.

  1. Get the Jenkins flavor of prototype.js

  2. Inject the following code - make sure to do it before starting navigation:

    
    webView2.CoreWebView2.WebMessageReceived += WebMessageReceived;
    // Downloaded from: https://raw.githubusercontent.com/jenkinsci/jenkins/master/war/src/main/webapp/scripts/prototype.js
    var prototypeJS = File.ReadAllText(@"prototype.js");
    await webView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(prototypeJS);
    await webView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage([{\"age\": 21}, {\"age\": 23}]);");
    
    private void WebMessageReceived(object? sender, CoreWebView2WebMessageReceivedEventArgs e)
    {
        var message = e.WebMessageAsJson;
        try
        {
            var info = System.Text.Json.JsonSerializer.Deserialize<Info[]>(message);
            Debug.WriteLine(info);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
    
    public class Info
    {
        [JsonPropertyName("age")]
        public int Age { get; set; } 
    }```
  3. Start the browser - it won't be able to deserialize the web message

Notes:

E.g. see the change in the Array.prototype:

function toJSON() {
  var results = [];
  this.each(function(object) {
   var value = Object.toJSON(object);
   if (value !== undefined) results.push(value);
  });
  return '[' + results.join(', ') + ']';
 }
"\"[{\\\"age\\\": 21}, {\\\"age\\\": 23}]\""
"[{\"age\":21},{\"age\":23}]"

AB#47984249

victorthoang commented 1 year ago

Hello @szanto90balazs,

Thanks for your bug report. I've assigned this to a dev that can best try to replicate the issue and follow up on this.

yizhao5 commented 1 year ago

@szanto90balazs. Can you provide the minimum sample code, and the URL which triggered it? Is it a problem with the escape characters of the JsonSerializer.Deserialize API? Thanks.

szanto90balazs commented 1 year ago

@victorthoang Thanks for following up.

@yizhao5 The URL can be arbitrary, as long as the page uses a certain flavor of prototype.js or just simple choose to override Array.prototype members. I can't share our Jenkins url, since it's behind auth.

Attached the minimum sample code which you can reproduce the issue with. The problem is that elements in the array are one more time, so you can't just deserialize them in one step.

MultiWindowWebView2.zip

yizhao5 commented 1 year ago

Got it. If it's not urgent, I'll find time to look at it after the recent New Year. Thanks.