Skip to content

Fix for WebView.EvaluateJavaScriptAsync fails to execute JavaScript containing newline characters #29126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

praveenkumarkarunanithi
Copy link
Contributor

Root Cause

The EvaluateJavaScriptAsync method did not account for multi-line JavaScript strings containing newline characters (\r\n, \r, \n). These newline characters caused script execution issues on platforms like Windows (WebView2) and iOS (WKWebView), either silently failing to execute or throwing runtime exceptions due to unprocessed newline characters in the script string.

Description of Change

The JavaScript string is now normalized by replacing all newline characters (\r\n, \r, \n) with a space before execution. This ensures consistent behavior and compatibility across platforms.

Issues Fixed

Fixes #11905

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Screenshots

Before Issue Fix After Issue Fix
withoutfix withfix

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Apr 22, 2025
Copy link
Contributor

Hey there @@praveenkumarkarunanithi! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Apr 22, 2025
@praveenkumarkarunanithi praveenkumarkarunanithi changed the title Fix 11905 Fix for WebView.EvaluateJavaScriptAsync fails to execute JavaScript containing newline characters Apr 22, 2025
@praveenkumarkarunanithi praveenkumarkarunanithi marked this pull request as ready for review April 22, 2025 15:28
@praveenkumarkarunanithi praveenkumarkarunanithi requested a review from a team as a code owner April 22, 2025 15:28
public async Task TestEscapeJsStringHandlesNewlines()
{
string scriptWithNewlines = "var x = 5;\r\n" +
"var y = 10;\r" +
Copy link
Contributor

@MartyIX MartyIX Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does happen when there is javascript code: var myString = "<NEWLINE HERE>"; console.log(myString);? It would be nice to have such a test.

Copy link
Contributor Author

@praveenkumarkarunanithi praveenkumarkarunanithi Apr 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MartyIX , Our fix replaces literal newline characters with spaces to ensure JavaScript executes properly across all platforms. JavaScript string escape sequences (like \n) are not affected since they're represented differently in code:
string jsWithEscapeSequence = "var myString = '\\n';";
since standard practice is to use \n escape sequences to represent newlines in strings,most real-world code won't be affected.

Copy link
Contributor

@MartyIX MartyIX Apr 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point I wanted to make was simply: Your PR can modify original behavior of user's JavaScript code. I believe it should be mentioned in the PR description. If it is acceptable or not, is not up to me. I just want to make sure it's explicitly acknowledged.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw: #29139 was merged to the inflight branch yesterday. Would it make sense to test against that branch if your workaround is still needed?

I'm basically very interested what causes that on Windows you observe "silent failure". Do you possibly know where the limitation come from? Or what is buggy?

Copy link
Member

@mattleibow mattleibow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR should land after #27528

But, as @MartyIX says, newlines may have meaning in the context of JS. For example, they use backtics to represent the multi line strings:

let poll = `Is .NET MAUI cool?
- Yes!
- Yes!
- Yes!
Wow, so it is!
`
console.log(poll);

as well as backslashes:

let poll = 'Is .NET MAUI cool? \n\
- Yes! \n\
- Yes! \n\
- Yes! \n\
Wow, so it is! \n\
'
console.log(poll);

We need to add tets for these as well.

@praveenkumarkarunanithi
Copy link
Contributor Author

This PR should land after #27528

But, as @MartyIX says, newlines may have meaning in the context of JS. For example, they use backtics to represent the multi line strings:

let poll = `Is .NET MAUI cool?
- Yes!
- Yes!
- Yes!
Wow, so it is!
`
console.log(poll);

as well as backslashes:

let poll = 'Is .NET MAUI cool? \n\
- Yes! \n\
- Yes! \n\
- Yes! \n\
Wow, so it is! \n\
'
console.log(poll);

We need to add tets for these as well.

@mattleibow , I've optimized the fix to handle both scenarios you mentioned:
Template literals with backticks for multiline strings
Backslash line continuations with embedded \n escape sequences
I've added test cases for both scenarios in WebViewHelperTests.cs to verify proper handling. The implementation correctly preserves JavaScript string semantics while ensuring proper escaping for WebView evaluation.

As recommended, I've worked these changes on top of PR #27528 and updated this PR to include those changes. This approach ensures my PR can be smoothly merged after PR #27528 is completed.

@MartyIX
Copy link
Contributor

MartyIX commented Jul 2, 2025

FYI: I opened this issue for Windows' WebView: MicrosoftEdge/WebView2Feedback#5288. The thing is that this

script = "try{eval('" + script + "')}catch(e){'null'};";

should not be necessary for Windows based on WebView2 documentation:

A function that has no explicit return value returns undefined. If the script that was run throws an unhandled exception, then the result is also null. This method is applied asynchronously. If the method is run after the NavigationStarting event during a navigation, the script runs in the new document when loading it, around the time ContentLoading is run. This operation works even if IsScriptEnabled is set to false.

(Emphasis mine)

Sadly, this is not how it work in practice. Anyway, we will see what the guys will say -- either there is a bug in the documentation or in the product.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-webview WebView community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Webview.EvaluateJavaScriptAsync does not execute with newline
4 participants