AngleSharp.Css
for CSS support)As the title says, loading jQuery 2.2.4 causes a deadlock. I'm using the following source:https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js
var config = Configuration.Default .WithRequester(new HttpClientRequester()) .WithDefaultLoader(new LoaderOptions() { IsResourceLoadingEnabled = true }) .WithJs() .WithEventLoop()); var document = await BrowsingContext.New(config).OpenAsync(r => r.Content(@" <!DOCTYPE html> <html> <head> <script src=""https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js""></script> </head> <body> The body </body> </html>"));
After investigation, it turns out that the issue comes from setting innerHTML
while the document is loading. Here is a simple repro:
var config = Configuration.Default .WithRequester(new HttpClientRequester()) .WithDefaultLoader(new LoaderOptions() { IsResourceLoadingEnabled = true }) .WithJs() .WithEventLoop()); var document = await BrowsingContext.New(config).OpenAsync(r => r.Content(@" <!DOCTYPE html> <html> <head> <script> var div = document.createElement('div'); document.documentElement.appendChild(div).innerHTML = '<span></span>'; </script> </head> <body> The body </body> </html>"));
Expected behavior: OpenAsync
should return the document with the script loaded
Actual behavior: OpenAsync
is blocked and does not finish ever
Environment details: .Net Core 3.1
Possible SolutionSo, after a bunch of debugging, I found the deadlock happens in AngleSharp.Html.Parser.Dom.HtmlDomBuilder.cs:L141.
After parsing the last html part of the fragment, the tokenizer returns an EndOfFile
token and is passed through the following methods:
The End
method then sets _waiting = _document.FinishLoadingAsync();
which is causing the deadlock. So, I think the End
method should not be called when a fragment is being parsed, but I'm not quite sure where exactly to put the condition. Also, I don't know if there are other cases appart of document fragments which could cause this issue.
Here's what I changed and now jQuery loads correctly.
HtmlDomBuilder.cs:L1511
case HtmlTokenType.EndOfFile: { + if (IsFragmentCase) + return; CheckBodyOnClosing(token); if (_templateModes.Count != 0) { InTemplate(token); } else { End(); } return; }
Is my thinking correct? Also the changes are to be done in the AngleSharp repo, but I'm posting here because I tought the issue is more related to scripting. Should I open an issue in the AngleSharp repo as well or just a PR is enough?
Awesome project btw 👍
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4