-
-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Bug Report
Prerequisites
- Can you reproduce the problem in a MWE?
- Are you running the latest version of AngleSharp? AngleSharp v0.13.0
- Did you check the FAQs to see if that helps you?
- Are you reporting to the correct repository? (there are multiple AngleSharp libraries, e.g.,
AngleSharp.Cssfor CSS support) - Did you perform a search in the issues?
Description
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
Steps to Reproduce
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 Solution
So, 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 👍