Skip to content
This repository was archived by the owner on Feb 25, 2021. It is now read-only.

Commit 284774a

Browse files
Reject script tags in components, but allow overriding. Fixes #552 (#553)
1 parent 9c60e78 commit 284774a

File tree

6 files changed

+128
-0
lines changed

6 files changed

+128
-0
lines changed

src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorDiagnosticFactory.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ public static RazorDiagnostic CreateEventHandler_Duplicates(SourceSpan? source,
165165
"'bind', 'bind-value' or 'bind-value-change'",
166166
RazorDiagnosticSeverity.Error);
167167

168+
public static readonly RazorDiagnosticDescriptor DisallowedScriptTag = new RazorDiagnosticDescriptor(
169+
"BL9992",
170+
() => "Script tags should not be placed inside components because they cannot be updated dynamically. To fix this, move the script tag to the 'index.html' file or another static location. For more information see http://some/link",
171+
RazorDiagnosticSeverity.Error);
172+
173+
public static RazorDiagnostic Create_DisallowedScriptTag(SourceSpan? source)
174+
{
175+
var diagnostic = RazorDiagnostic.Create(DisallowedScriptTag, source ?? SourceSpan.Undefined);
176+
return diagnostic;
177+
}
178+
168179
public static RazorDiagnostic CreateBindAttribute_InvalidSyntax(SourceSpan? source, string attribute)
169180
{
170181
var diagnostic = RazorDiagnostic.Create(

src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorRuntimeNodeWriter.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ public override void WriteHtmlContent(CodeRenderingContext context, HtmlContentI
243243

244244
if (nextToken.Type == HtmlTokenType.StartTag)
245245
{
246+
RejectDisallowedHtmlTags(node, nextTag);
247+
246248
_scopeStack.IncrementCurrentScopeChildCount(context);
247249

248250
codeWriter
@@ -304,6 +306,26 @@ public override void WriteHtmlContent(CodeRenderingContext context, HtmlContentI
304306
}
305307
}
306308

309+
private void RejectDisallowedHtmlTags(IntermediateNode node, HtmlTagToken tagToken)
310+
{
311+
// Disallow <script> in components as per #552
312+
// Case-sensitive comparison is fine because AngleSharp always lowercases tag names
313+
if (tagToken.Name.Equals("script", StringComparison.Ordinal))
314+
{
315+
const string suppressErrorAttributeName = "suppress-error";
316+
if (string.Equals(tagToken.GetAttribute(suppressErrorAttributeName), "BL9992", StringComparison.Ordinal))
317+
{
318+
tagToken.Attributes.RemoveAll(kvp => kvp.Key.Equals(suppressErrorAttributeName, StringComparison.Ordinal));
319+
}
320+
else
321+
{
322+
var adjustedSpan = CalculateSourcePosition(node.Source, tagToken.Position);
323+
var diagnostic = BlazorDiagnosticFactory.Create_DisallowedScriptTag(adjustedSpan);
324+
throw new RazorCompilerException(diagnostic);
325+
}
326+
}
327+
}
328+
307329
public override void WriteUsingDirective(CodeRenderingContext context, UsingDirectiveIntermediateNode node)
308330
{
309331
context.CodeWriter.WriteUsing(node.Content, endLine: true);

test/Microsoft.AspNetCore.Blazor.Build.Test/DiagnosticRazorIntegrationTest.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,28 @@ public void OldCodeBlockAttributeSyntax_ReportsError()
8787
var diagnostic = Assert.Single(generated.Diagnostics);
8888
Assert.Equal("BL9979", diagnostic.Id);
8989
}
90+
91+
[Fact]
92+
public void RejectsScriptTag()
93+
{
94+
// Arrange/Act
95+
var result = CompileToCSharp(@"Hello
96+
<div>
97+
<script src='anything'>
98+
something
99+
</script>
100+
</div>
101+
Goodbye");
102+
103+
// Assert
104+
Assert.Collection(result.Diagnostics,
105+
item =>
106+
{
107+
Assert.Equal("BL9992", item.Id);
108+
Assert.Equal("Script tags should not be placed inside components because they cannot be updated dynamically. To fix this, move the script tag to the 'index.html' file or another static location. For more information see http://some/link", item.GetMessage());
109+
Assert.Equal(2, item.Span.LineIndex);
110+
Assert.Equal(4, item.Span.CharacterIndex);
111+
});
112+
}
90113
}
91114
}

test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,5 +365,24 @@ void OnClick(UIEventArgs e) {
365365
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
366366
CompileToAssembly(generated);
367367
}
368+
369+
[Fact]
370+
public void ScriptTag_WithErrorSuppressed()
371+
{
372+
// Arrange/Act
373+
var generated = CompileToCSharp(@"
374+
<div>
375+
<script src='some/url.js' anotherattribute suppress-error='BL9992'>
376+
some text
377+
some more text
378+
</script>
379+
</div>
380+
");
381+
382+
// Assert
383+
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
384+
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
385+
CompileToAssembly(generated);
386+
}
368387
}
369388
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// <auto-generated/>
2+
#pragma warning disable 1591
3+
namespace Test
4+
{
5+
#line hidden
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Threading.Tasks;
10+
public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
11+
{
12+
#pragma warning disable 1998
13+
protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
14+
{
15+
base.BuildRenderTree(builder);
16+
builder.OpenElement(0, "div");
17+
builder.AddContent(1, "\n ");
18+
builder.OpenElement(2, "script");
19+
builder.AddAttribute(3, "src", "some/url.js");
20+
builder.AddAttribute(4, "anotherattribute", "");
21+
builder.AddContent(5, "\n some text\n some more text\n ");
22+
builder.CloseElement();
23+
builder.AddContent(6, "\n");
24+
builder.CloseElement();
25+
builder.AddContent(7, "\n");
26+
}
27+
#pragma warning restore 1998
28+
}
29+
}
30+
#pragma warning restore 1591
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Document -
2+
NamespaceDeclaration - - Test
3+
UsingDirective - (3:1,1 [14] ) - System
4+
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
5+
UsingDirective - (53:3,1 [19] ) - System.Linq
6+
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
7+
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
8+
MethodDeclaration - - protected override - void - BuildRenderTree
9+
CSharpCode -
10+
IntermediateToken - - CSharp - base.BuildRenderTree(builder);
11+
HtmlContent - (0:0,0 [146] x:\dir\subdir\Test\TestComponent.cshtml)
12+
IntermediateToken - (0:0,0 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Html - <div>
13+
IntermediateToken - (5:0,5 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
14+
IntermediateToken - (11:1,4 [7] x:\dir\subdir\Test\TestComponent.cshtml) - Html - <script
15+
IntermediateToken - (18:1,11 [18] x:\dir\subdir\Test\TestComponent.cshtml) - Html - src='some/url.js'
16+
IntermediateToken - (36:1,29 [17] x:\dir\subdir\Test\TestComponent.cshtml) - Html - anotherattribute
17+
IntermediateToken - (53:1,46 [24] x:\dir\subdir\Test\TestComponent.cshtml) - Html - suppress-error='BL9992'
18+
IntermediateToken - (77:1,70 [1] x:\dir\subdir\Test\TestComponent.cshtml) - Html - >
19+
IntermediateToken - (78:1,71 [49] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n some text\n some more text\n
20+
IntermediateToken - (127:4,4 [9] x:\dir\subdir\Test\TestComponent.cshtml) - Html - </script>
21+
IntermediateToken - (136:4,13 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
22+
IntermediateToken - (138:5,0 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - </div>
23+
IntermediateToken - (144:5,6 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n

0 commit comments

Comments
 (0)