Skip to content

Commit fc65b4f

Browse files
SteveSandersonMSmkArtakMSFT
authored andcommitted
Merged PR 2264: Fix encoding used in JS generated by prerenderer
Fix encoding used in JS generated by prerenderer
1 parent 124b96b commit fc65b4f

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed

src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Newtonsoft.Json;
22
using Newtonsoft.Json.Linq;
33
using System.Text;
4+
using System.Text.Encodings.Web;
45

56
namespace Microsoft.AspNetCore.SpaServices.Prerendering
67
{
@@ -49,12 +50,16 @@ public string CreateGlobalsAssignmentScript()
4950

5051
foreach (var property in Globals.Properties())
5152
{
52-
stringBuilder.AppendFormat("window.{0} = {1};",
53-
property.Name,
54-
property.Value.ToString(Formatting.None));
53+
var propertyNameJavaScriptString = JavaScriptEncoder.Default.Encode(property.Name);
54+
var valueJson = property.Value.ToString(Formatting.None);
55+
var valueJsonJavaScriptString = JavaScriptEncoder.Default.Encode(valueJson);
56+
57+
stringBuilder.AppendFormat("window[\"{0}\"] = JSON.parse(\"{1}\");",
58+
propertyNameJavaScriptString,
59+
valueJsonJavaScriptString);
5560
}
5661

5762
return stringBuilder.ToString();
5863
}
5964
}
60-
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Reference Include="Microsoft.AspNetCore.SpaServices" />
9+
</ItemGroup>
10+
11+
</Project>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Collections.Generic;
5+
using Microsoft.AspNetCore.SpaServices.Prerendering;
6+
using Newtonsoft.Json;
7+
using Newtonsoft.Json.Linq;
8+
using Xunit;
9+
10+
namespace Microsoft.AspNetCore.SpaServices.Tests
11+
{
12+
public class RenderToStringResultTest
13+
{
14+
[Fact]
15+
public void HandlesNullGlobals()
16+
{
17+
// Arrange
18+
var renderToStringResult = new RenderToStringResult();
19+
renderToStringResult.Globals = null;
20+
21+
// Act
22+
var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
23+
24+
// Assert
25+
Assert.Equal(string.Empty, actualScript);
26+
}
27+
28+
[Fact]
29+
public void HandlesGlobalsWithMultipleProperties()
30+
{
31+
// Arrange
32+
var renderToStringResult = new RenderToStringResult();
33+
renderToStringResult.Globals = ToJObject(new
34+
{
35+
FirstProperty = "first value",
36+
SecondProperty = new[] { "Array entry 0", "Array entry 1" }
37+
});
38+
39+
// Act
40+
var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
41+
42+
// Assert
43+
var expectedScript = @"window[""FirstProperty""] = JSON.parse(""\u0022first value\u0022"");" +
44+
@"window[""SecondProperty""] = JSON.parse(""[\u0022Array entry 0\u0022,\u0022Array entry 1\u0022]"");";
45+
Assert.Equal(expectedScript, actualScript);
46+
}
47+
48+
[Fact]
49+
public void HandlesGlobalsWithCorrectStringEncoding()
50+
{
51+
// Arrange
52+
var renderToStringResult = new RenderToStringResult();
53+
renderToStringResult.Globals = ToJObject(new Dictionary<string, object>
54+
{
55+
{ "Va<l'u\"e", "</tag>\"'}\u260E" }
56+
});
57+
58+
// Act
59+
var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
60+
61+
// Assert
62+
var expectedScript = @"window[""Va\u003Cl\u0027u\u0022e""] = JSON.parse(""\u0022\u003C\/tag\u003E\\\u0022\u0027}\u260E\u0022"");";
63+
Assert.Equal(expectedScript, actualScript);
64+
}
65+
66+
private static JObject ToJObject(object value)
67+
{
68+
return JsonConvert.DeserializeObject<JObject>(JsonConvert.SerializeObject(value));
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)