Added support for ignoring integrity attribute on fallback for the Link TagHelper

- Do not include integrity attribute when asp-fallback-intergrity-check is false
 - Added Unit Tests, manual tests

Addresses #7845
This commit is contained in:
jmhmaine 2018-06-05 09:34:15 -04:00 committed by N. Taylor Mullen
parent 4f7e849cc1
commit 8a77ed23d3
13 changed files with 226 additions and 14 deletions

View File

@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("link", Attributes = HrefIncludeAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = HrefExcludeAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackHrefAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackHrefIntegrityCheckAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackHrefIncludeAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackHrefExcludeAttributeName, TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("link", Attributes = FallbackTestClassAttributeName, TagStructure = TagStructure.WithoutEndTag)]
@ -40,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string HrefIncludeAttributeName = "asp-href-include";
private const string HrefExcludeAttributeName = "asp-href-exclude";
private const string FallbackHrefAttributeName = "asp-fallback-href";
private const string FallbackHrefIntegrityCheckAttributeName = "asp-fallback-href-integrity-check";
private const string FallbackHrefIncludeAttributeName = "asp-fallback-href-include";
private const string FallbackHrefExcludeAttributeName = "asp-fallback-href-exclude";
private const string FallbackTestClassAttributeName = "asp-fallback-test-class";
@ -147,6 +149,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlAttributeName(FallbackHrefAttributeName)]
public string FallbackHref { get; set; }
/// <summary>
/// Boolean value that determines if Integrity Hash will be compared with <see cref="FallbackHref"/> value.
/// Value defaults to true if not provided.
/// Must be used in conjunction with <see cref="FallbackHref"/>.
/// </summary>
[HtmlAttributeName(FallbackHrefIntegrityCheckAttributeName)]
public bool? FallbackHrefIntegrityCheck { get; set; }
/// <summary>
/// Value indicating if file version should be appended to the href urls.
/// </summary>
@ -367,6 +377,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
continue;
}
// do not write integrity attribute when FallbackHrefIntegrityCheck is false
if (attribute.Name.Equals("integrity", StringComparison.OrdinalIgnoreCase) && FallbackHrefIntegrityCheck == false)
{
continue;
}
attribute.WriteTo(StringWriter, HtmlEncoder);
StringWriter.Write(' ');
}

View File

@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlTargetElement("script", Attributes = FallbackSrcIncludeAttributeName)]
[HtmlTargetElement("script", Attributes = FallbackSrcExcludeAttributeName)]
[HtmlTargetElement("script", Attributes = FallbackTestExpressionAttributeName)]
[HtmlTargetElement("script", Attributes = FallbackIntegrityCheckAttributeName)]
[HtmlTargetElement("script", Attributes = AppendVersionAttributeName)]
public class ScriptTagHelper : UrlResolutionTagHelper
{
@ -34,6 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
private const string SrcExcludeAttributeName = "asp-src-exclude";
private const string FallbackSrcAttributeName = "asp-fallback-src";
private const string FallbackSrcIncludeAttributeName = "asp-fallback-src-include";
private const string FallbackIntegrityCheckAttributeName = "asp-fallback-integrity-check";
private const string FallbackSrcExcludeAttributeName = "asp-fallback-src-exclude";
private const string FallbackTestExpressionAttributeName = "asp-fallback-test";
private const string SrcAttributeName = "src";
@ -129,6 +131,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
[HtmlAttributeName(FallbackSrcAttributeName)]
public string FallbackSrc { get; set; }
/// <summary>
/// Boolean value that determines if Integrity Hash will be compared with <see cref="FallbackSrc"/> value.
/// Value defaults to true if not provided.
/// Must be used in conjunction with <see cref="FallbackSrc"/>.
/// </summary>
[HtmlAttributeName(FallbackIntegrityCheckAttributeName)]
public bool? FallbackIntegrityCheck { get; set; }
/// <summary>
/// Value indicating if file version should be appended to src urls.
/// </summary>
@ -312,6 +322,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var attribute = attributes[i];
if (!attribute.Name.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase))
{
// do not write integrity attribute when fallbackintegrityCheck is false
if (attribute.Name.Equals("integrity", StringComparison.OrdinalIgnoreCase) && FallbackIntegrityCheck == false) continue;
StringWriter.Write(' ');
attribute.WriteTo(StringWriter, HtmlEncoder);
}

View File

@ -19,11 +19,27 @@
// Fallback to globbed src
</script>
<script>(false||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/site.js]]" title='"the" title'></script>]]"));</script>
<script src="HtmlEncode[[/styles/siteIntegrity.js?a=integrity]]" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script loading primary source, applied integrity hash to primary source.
</script>
<script>(true||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/sub/site2.js?a=integrity]]" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ="></script>]]"));</script>
<script src="HtmlEncode[[/styles/siteIntegrity.js?a=integrity]]" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, applies integrity hash to fallback.
</script>
<script>(false||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/sub/siteIntegrity2.js?a=integrity]]" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ="></script>]]"));</script>
<script src="HtmlEncode[[/styles/siteIntegrity.js?a=integrity]]" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, ignores integrity hash on fallback.
</script>
<script>(false||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/sub/siteIntegrity3.js?a=integrity]]" crossorigin="anonymous"></script>]]"));</script>
<script src="HtmlEncode[[/blank.js]]">
// Fallback to globbed src with exclude
</script>
<script>(false||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script>]]"));</script>
<script>(false||document.write("JavaScriptEncode[[<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/siteIntegrity.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity2.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity3.js]]"></script>]]"));</script>
<script src="HtmlEncode[[/blank.js]]">
// Fallback to globbed and static src
@ -65,7 +81,7 @@
<script src="HtmlEncode[[/styles/site.js]]"></script>
<!-- Globbed script tag with existing file and exclude -->
<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script>
<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/siteIntegrity.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity2.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity3.js]]"></script>
<script>
// Globbed script tag missing include
@ -76,7 +92,7 @@
</script>
<!-- Globbed script tag with comma separated include pattern -->
<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script><script src="HtmlEncode[[/styles/sub/site3.js]]"></script>
<script src="HtmlEncode[[/styles/site.js]]"></script><script src="HtmlEncode[[/styles/siteIntegrity.js]]"></script><script src="HtmlEncode[[/styles/sub/site2.js]]"></script><script src="HtmlEncode[[/styles/sub/site3.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity2.js]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity3.js]]"></script>
<!-- Globbed script tag with missing file -->
@ -110,9 +126,9 @@
</script>
<!-- Globbed script tag with existing files and version -->
<script src="HtmlEncode[[/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script><script src="HtmlEncode[[/styles/sub/site3.js?v=lmeAMiqm76lnGyqHhu6PIBHAC0Vt46mgVB_KaG_gGdA]]"></script>
<script src="HtmlEncode[[/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/styles/siteIntegrity.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ]]"></script><script src="HtmlEncode[[/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script><script src="HtmlEncode[[/styles/sub/site3.js?v=lmeAMiqm76lnGyqHhu6PIBHAC0Vt46mgVB_KaG_gGdA]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity2.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity3.js?v=6I1ncApSzTYytACF7244bg3a_sEnKrGH8nVudoaN984]]"></script>
<!-- Globbed script tag with existing file, exclude and version -->
<script src="HtmlEncode[[/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script>
<script src="HtmlEncode[[/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I]]"></script><script src="HtmlEncode[[/styles/siteIntegrity.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ]]"></script><script src="HtmlEncode[[/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity2.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ]]"></script><script src="HtmlEncode[[/styles/sub/siteIntegrity3.js?v=6I1ncApSzTYytACF7244bg3a_sEnKrGH8nVudoaN984]]"></script>
</body>
</html>

View File

@ -19,11 +19,27 @@
// Fallback to globbed src
</script>
<script>(false||document.write("\u003Cscript src=\u0022\/styles\/site.js\u0022 title=\u0027\u0022the\u0022 title\u0027\u003E\u003C\/script\u003E"));</script>
<script src="/styles/siteIntegrity.js?a=integrity" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script loading primary source, applied integrity hash to primary source.
</script>
<script>(true||document.write("\u003Cscript src=\u0022\/styles\/sub\/site2.js?a=integrity\u0022 crossorigin=\u0022anonymous\u0022 integrity=\u0022sha256-tMQLOHBNPE829MHQPO8metegsGobA\/henDPOvtZOWhQ=\u0022\u003E\u003C\/script\u003E"));</script>
<script src="/styles/siteIntegrity.js?a=integrity" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, applies integrity hash to fallback.
</script>
<script>(false||document.write("\u003Cscript src=\u0022\/styles\/sub\/siteIntegrity2.js?a=integrity\u0022 crossorigin=\u0022anonymous\u0022 integrity=\u0022sha256-tMQLOHBNPE829MHQPO8metegsGobA\/henDPOvtZOWhQ=\u0022\u003E\u003C\/script\u003E"));</script>
<script src="/styles/siteIntegrity.js?a=integrity" crossorigin="anonymous" integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, ignores integrity hash on fallback.
</script>
<script>(false||document.write("\u003Cscript src=\u0022\/styles\/sub\/siteIntegrity3.js?a=integrity\u0022 crossorigin=\u0022anonymous\u0022\u003E\u003C\/script\u003E"));</script>
<script src="/blank.js">
// Fallback to globbed src with exclude
</script>
<script>(false||document.write("\u003Cscript src=\u0022\/styles\/site.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/styles\/sub\/site2.js\u0022\u003E\u003C\/script\u003E"));</script>
<script>(false||document.write("\u003Cscript src=\u0022\/styles\/site.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/styles\/siteIntegrity.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/styles\/sub\/site2.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/styles\/sub\/siteIntegrity2.js\u0022\u003E\u003C\/script\u003E\u003Cscript src=\u0022\/styles\/sub\/siteIntegrity3.js\u0022\u003E\u003C\/script\u003E"));</script>
<script src="/blank.js">
// Fallback to globbed and static src
@ -65,7 +81,7 @@
<script src="/styles/site.js"></script>
<!-- Globbed script tag with existing file and exclude -->
<script src="/styles/site.js"></script><script src="/styles/sub/site2.js"></script>
<script src="/styles/site.js"></script><script src="/styles/siteIntegrity.js"></script><script src="/styles/sub/site2.js"></script><script src="/styles/sub/siteIntegrity2.js"></script><script src="/styles/sub/siteIntegrity3.js"></script>
<script>
// Globbed script tag missing include
@ -76,7 +92,7 @@
</script>
<!-- Globbed script tag with comma separated include pattern -->
<script src="/styles/site.js"></script><script src="/styles/sub/site2.js"></script><script src="/styles/sub/site3.js"></script>
<script src="/styles/site.js"></script><script src="/styles/siteIntegrity.js"></script><script src="/styles/sub/site2.js"></script><script src="/styles/sub/site3.js"></script><script src="/styles/sub/siteIntegrity2.js"></script><script src="/styles/sub/siteIntegrity3.js"></script>
<!-- Globbed script tag with missing file -->
@ -110,9 +126,9 @@
</script>
<!-- Globbed script tag with existing files and version -->
<script src="/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I"></script><script src="/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0"></script><script src="/styles/sub/site3.js?v=lmeAMiqm76lnGyqHhu6PIBHAC0Vt46mgVB_KaG_gGdA"></script>
<script src="/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I"></script><script src="/styles/siteIntegrity.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ"></script><script src="/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0"></script><script src="/styles/sub/site3.js?v=lmeAMiqm76lnGyqHhu6PIBHAC0Vt46mgVB_KaG_gGdA"></script><script src="/styles/sub/siteIntegrity2.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ"></script><script src="/styles/sub/siteIntegrity3.js?v=6I1ncApSzTYytACF7244bg3a_sEnKrGH8nVudoaN984"></script>
<!-- Globbed script tag with existing file, exclude and version -->
<script src="/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I"></script><script src="/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0"></script>
<script src="/styles/site.js?v=jx1PJjLX32-xgQQx2BxnckU9QH9DVKkm4-M5bSK869I"></script><script src="/styles/siteIntegrity.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ"></script><script src="/styles/sub/site2.js?v=pwJaxaQxnb-rPAdF2JlAp4xiPNq1XuJFd6TyOOfNF-0"></script><script src="/styles/sub/siteIntegrity2.js?v=tMQLOHBNPE829MHQPO8metegsGobA_henDPOvtZOWhQ"></script><script src="/styles/sub/siteIntegrity3.js?v=6I1ncApSzTYytACF7244bg3a_sEnKrGH8nVudoaN984"></script>
</body>
</html>

View File

@ -3,5 +3,4 @@
<form method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
<form action="" method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
<form action="/Foo/Bar/Baz.html" method="get"></form>
<form action="/Foo/Bar/Baz.html" method="post"></form>
<form action="/RedirectToPage" method="post"><input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
<form action="/Foo/Bar/Baz.html" method="post"></form>

View File

@ -263,7 +263,49 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
tagHelper.FallbackTestValue = "hidden";
tagHelper.AppendVersion = true;
}
}
},
// asp-fallback-href-integrity-check Attribute true
{
new TagHelperAttributeList
{
new TagHelperAttribute("asp-fallback-href", "test.css"),
new TagHelperAttribute("asp-fallback-test-class", "hidden"),
new TagHelperAttribute("asp-fallback-test-property", "visibility"),
new TagHelperAttribute("asp-fallback-test-value", "hidden"),
new TagHelperAttribute("asp-append-version", "true"),
new TagHelperAttribute("asp-fallback-href-integrity-check", "true")
},
tagHelper =>
{
tagHelper.FallbackHref = "test.css";
tagHelper.FallbackTestClass = "hidden";
tagHelper.FallbackTestProperty = "visibility";
tagHelper.FallbackTestValue = "hidden";
tagHelper.AppendVersion = true;
tagHelper.FallbackHrefIntegrityCheck = true;
}
},
// asp-fallback-href-integrity-check Attribute false
{
new TagHelperAttributeList
{
new TagHelperAttribute("asp-fallback-href", "test.css"),
new TagHelperAttribute("asp-fallback-test-class", "hidden"),
new TagHelperAttribute("asp-fallback-test-property", "visibility"),
new TagHelperAttribute("asp-fallback-test-value", "hidden"),
new TagHelperAttribute("asp-append-version", "true"),
new TagHelperAttribute("asp-fallback-href-integrity-check", "false")
},
tagHelper =>
{
tagHelper.FallbackHref = "test.css";
tagHelper.FallbackTestClass = "hidden";
tagHelper.FallbackTestProperty = "visibility";
tagHelper.FallbackTestValue = "hidden";
tagHelper.AppendVersion = true;
tagHelper.FallbackHrefIntegrityCheck = false;
}
},
};
}
}

View File

@ -156,6 +156,20 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
tagHelper.FallbackTestExpression = "isavailable()";
}
},
{
new TagHelperAttributeList
{
new TagHelperAttribute("asp-fallback-src", "test.js"),
new TagHelperAttribute("asp-fallback-test", "isavailable()"),
new TagHelperAttribute("asp-fallback-integrity-check", "false")
},
tagHelper =>
{
tagHelper.FallbackSrc = "test.js";
tagHelper.FallbackTestExpression = "isavailable()";
tagHelper.FallbackIntegrityCheck = false;
}
},
{
new TagHelperAttributeList
{
@ -182,6 +196,22 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
tagHelper.FallbackTestExpression = "isavailable()";
}
},
{
new TagHelperAttributeList
{
new TagHelperAttribute("asp-fallback-src", "test.js"),
new TagHelperAttribute("asp-fallback-src-include", "*.js"),
new TagHelperAttribute("asp-fallback-test", "isavailable()"),
new TagHelperAttribute("asp-fallback-integrity-check", "false")
},
tagHelper =>
{
tagHelper.FallbackSrc = "test.js";
tagHelper.FallbackSrcInclude = "*.css";
tagHelper.FallbackTestExpression = "isavailable()";
tagHelper.FallbackIntegrityCheck = false;
}
},
{
new TagHelperAttributeList
{

View File

@ -46,6 +46,35 @@
asp-fallback-test-property="visibility"
asp-fallback-test-value="hidden" />
<!-- Fallback to static href with no asp-fallback-href-integrity-check attribute, default behavior is to keep integrity hash -->
<link href="~/styles/site.min.css?a=b&c=d" rel="stylesheet" data-extra="test" title='"the" title'
integrity="XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh+pQc="
crossorigin="anonymous"
asp-fallback-href="~/styles/site.css?a=b&c=d"
asp-fallback-test-class="hidden"
asp-fallback-test-property="visibility"
asp-fallback-test-value="hidden" />
<!-- Fallback to static href with asp-fallback-href-integrity-check set to true, default behavior is to keep integrity hash -->
<link href="~/styles/site.min.css?a=b&c=d" rel="stylesheet" data-extra="test" title='"the" title'
integrity="XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh+pQc="
crossorigin="anonymous"
asp-fallback-href="~/styles/site.css?a=b&c=d"
asp-fallback-test-class="hidden"
asp-fallback-test-property="visibility"
asp-fallback-test-value="hidden"
asp-fallback-href-integrity-check="true" />
<!-- Fallback to static href with asp-fallback-href-integrity-check set to false, removes integrity attribute on fallback so that different CSS can be loaded -->
<link href="~/styles/site.min.css?a=b&c=d" rel="stylesheet" data-extra="test" title='"the" title'
integrity="XY7YsMemPf8AGU4SIX9ED9eOjK1LOQWu2dmCNmh+pQc="
crossorigin="anonymous"
asp-fallback-href="~/styles/siteIntegrity.css?a=b&c=d"
asp-fallback-test-class="hidden"
asp-fallback-test-property="visibility"
asp-fallback-test-value="hidden"
asp-fallback-href-integrity-check="false" />
<!-- Fallback to static href with dynamic attributes -->
<link href="~/styles/site.min.css?a=b&c=d" rel="@("stylesheet")" data-extra="@("test")" title='@(@"""the"" title")'
asp-fallback-href="~/styles/site.css?a=b&c=d"

View File

@ -1,4 +1,4 @@
@*
@*
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*@
@ -22,6 +22,33 @@
<script src="~/blank.js" asp-fallback-src-include="**/site.js" asp-fallback-test="false" title='"the" title'>
// Fallback to globbed src
</script>
<script src="~/styles/siteIntegrity.js?a=integrity"
asp-fallback-src="~/styles/sub/site2.js?a=integrity"
asp-fallback-test="true"
crossorigin="anonymous"
integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script loading primary source, applied integrity hash to primary source.
</script>
<script src="~/styles/siteIntegrity.js?a=integrity"
asp-fallback-src="~/styles/sub/siteIntegrity2.js?a=integrity"
asp-fallback-test="false"
asp-fallback-integrity-check="true"
crossorigin="anonymous"
integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, applies integrity hash to fallback.
</script>
<script src="~/styles/siteIntegrity.js?a=integrity"
asp-fallback-src="~/styles/sub/siteIntegrity3.js?a=integrity"
asp-fallback-test="false"
asp-fallback-integrity-check="false"
crossorigin="anonymous"
integrity="sha256-tMQLOHBNPE829MHQPO8metegsGobA/henDPOvtZOWhQ=">
// Script uses fallback source, ignores integrity hash on fallback.
</script>
<script src="~/blank.js"
asp-fallback-src-include="**/*.js"

View File

@ -0,0 +1,6 @@
body::after {
display: block;
color: #0fa912;
margin-top: 2.4em;
content: "Stylesheet 'siteIntegrity.css' loaded successfully!";
}

View File

@ -0,0 +1,6 @@
(function () {
var p = document.createElement("P");
p.appendChild(document.createTextNode("Integrity Script loaded successfully!"));
p.style.color = "#0fa912";
document.body.appendChild(p);
})();

View File

@ -0,0 +1,6 @@
(function () {
var p = document.createElement("P");
p.appendChild(document.createTextNode("Integrity Script loaded successfully!"));
p.style.color = "#0fa912";
document.body.appendChild(p);
})();

View File

@ -0,0 +1,6 @@
(function () {
var p = document.createElement("P");
p.appendChild(document.createTextNode("Integrity Script with different hash loaded successfully!"));
p.style.color = "#0fa912";
document.body.appendChild(p);
})();