Compare commits
11 Commits
216e8bbb16
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e709a525f3 | ||
|
|
146d5e4f60 | ||
|
|
3a1c6f73ef | ||
|
|
f3988f9bbe | ||
|
|
4afaf4bd57 | ||
|
|
088a429ff4 | ||
|
|
60e35106c1 | ||
|
|
db8012157c | ||
|
|
970b963de0 | ||
|
|
81d967943e | ||
|
|
f275182881 |
@@ -15,16 +15,16 @@ test_script:
|
||||
- ps: |
|
||||
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) {
|
||||
dotnet tool install --global dotnet-sonarscanner
|
||||
dotnet sonarscanner begin /k:"mganss_HtmlSanitizer" /v:$env:APPVEYOR_BUILD_VERSION /o:"mganss-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:sonar_token" /d:sonar.cs.opencover.reportsPaths="$($env:APPVEYOR_BUILD_FOLDER)\coverage.xml" /d:sonar.coverage.exclusions="**/Program.cs"
|
||||
dotnet sonarscanner begin /k:"mganss_HtmlSanitizer" /v:$env:APPVEYOR_BUILD_VERSION /o:"mganss-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:sonar_token" /d:sonar.cs.opencover.reportsPaths="$($env:APPVEYOR_BUILD_FOLDER)\coverage.netcoreapp2.2.xml" /d:sonar.coverage.exclusions="**/Program.cs"
|
||||
dotnet build
|
||||
}
|
||||
- dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput="..\..\coverage.xml" test\HtmlSanitizer.Tests\HtmlSanitizer.Tests.csproj -f netcoreapp2.1
|
||||
- dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput="..\..\coverage.xml" test\HtmlSanitizer.Tests\HtmlSanitizer.Tests.csproj -f netcoreapp2.2
|
||||
- ps: |
|
||||
if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER) {
|
||||
dotnet sonarscanner end /d:sonar.login="$env:sonar_token"
|
||||
}
|
||||
- pip install codecov
|
||||
- codecov -f "coverage.xml"
|
||||
- codecov -f "coverage.netcoreapp2.2.xml"
|
||||
artifacts:
|
||||
- path: 'src\**\*.nupkg'
|
||||
on_success:
|
||||
|
||||
@@ -58,9 +58,8 @@ namespace Ganss.XSS
|
||||
/// <param name="allowedAttributes">The allowed HTML attributes such as "href" and "alt". When <c>null</c>, uses <see cref="DefaultAllowedAttributes"/></param>
|
||||
/// <param name="uriAttributes">The HTML attributes that can contain a URI such as "href". When <c>null</c>, uses <see cref="DefaultUriAttributes"/></param>
|
||||
/// <param name="allowedCssProperties">The allowed CSS properties such as "font" and "margin". When <c>null</c>, uses <see cref="DefaultAllowedCssProperties"/></param>
|
||||
/// <param name="allowedCssClasses">CSS class names which are allowed in the value of a class attribute. When <c>null</c>, any class names are allowed.</param>
|
||||
public HtmlSanitizer(IEnumerable<string> allowedTags = null, IEnumerable<string> allowedSchemes = null,
|
||||
IEnumerable<string> allowedAttributes = null, IEnumerable<string> uriAttributes = null, IEnumerable<string> allowedCssProperties = null, IEnumerable<string> allowedCssClasses = null)
|
||||
IEnumerable<string> allowedAttributes = null, IEnumerable<string> uriAttributes = null, IEnumerable<string> allowedCssProperties = null)
|
||||
{
|
||||
AllowedTags = new HashSet<string>(allowedTags ?? DefaultAllowedTags, StringComparer.OrdinalIgnoreCase);
|
||||
AllowedSchemes = new HashSet<string>(allowedSchemes ?? DefaultAllowedSchemes, StringComparer.OrdinalIgnoreCase);
|
||||
@@ -68,7 +67,7 @@ namespace Ganss.XSS
|
||||
UriAttributes = new HashSet<string>(uriAttributes ?? DefaultUriAttributes, StringComparer.OrdinalIgnoreCase);
|
||||
AllowedCssProperties = new HashSet<string>(allowedCssProperties ?? DefaultAllowedCssProperties, StringComparer.OrdinalIgnoreCase);
|
||||
AllowedAtRules = new HashSet<CssRuleType>(DefaultAllowedAtRules);
|
||||
AllowedCssClasses = allowedCssClasses != null ? new HashSet<string>(allowedCssClasses) : null;
|
||||
AllowedClasses = new HashSet<string>(DefaultAllowedClasses, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -393,12 +392,17 @@ namespace Ganss.XSS
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the allowed CSS classes.
|
||||
/// The default allowed CSS classes.
|
||||
/// </summary>
|
||||
public static ISet<string> DefaultAllowedClasses { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the allowed CSS classes. If the set is empty, all classes will be allowed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The allowed CSS classes.
|
||||
/// The allowed CSS classes. An empty set means all classes are allowed.
|
||||
/// </value>
|
||||
public ISet<string> AllowedCssClasses { get; private set; }
|
||||
public ISet<string> AllowedClasses { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after sanitizing the document and post processing nodes.
|
||||
@@ -675,9 +679,6 @@ namespace Ganss.XSS
|
||||
var oldStyleEmpty = string.IsNullOrEmpty(tag.GetAttribute("style"));
|
||||
SanitizeStyle(tag, baseUrl);
|
||||
|
||||
var checkClasses = AllowedCssClasses != null;
|
||||
var allowedTags = AllowedCssClasses?.ToArray() ?? new string[0];
|
||||
|
||||
// sanitize the value of the attributes
|
||||
foreach (var attribute in tag.Attributes.ToList())
|
||||
{
|
||||
@@ -689,9 +690,9 @@ namespace Ganss.XSS
|
||||
}
|
||||
else
|
||||
{
|
||||
if (checkClasses && attribute.Name == "class")
|
||||
if (AllowedClasses.Any() && attribute.Name == "class")
|
||||
{
|
||||
var removedClasses = tag.ClassList.Except(allowedTags).ToArray();
|
||||
var removedClasses = tag.ClassList.Except(AllowedClasses).ToArray();
|
||||
|
||||
foreach (var removedClass in removedClasses)
|
||||
RemoveCssClass(tag, removedClass, RemoveReason.NotAllowedCssClass);
|
||||
@@ -976,10 +977,12 @@ namespace Ganss.XSS
|
||||
{
|
||||
return new Uri(baseUri, iri.Value).AbsoluteUri;
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (UriFormatException)
|
||||
{
|
||||
iri = null;
|
||||
}
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
}
|
||||
else iri = null;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<AppVeyor_Build_Version Condition="'$(APPVEYOR_BUILD_VERSION)' == ''">1.0.0</AppVeyor_Build_Version>
|
||||
<AssemblyVersion>5.0.0.0</AssemblyVersion>
|
||||
<FileVersion>$(AppVeyor_Build_Version).0</FileVersion>
|
||||
<PackageVersion>$(AppVeyor_Build_Version)-beta</PackageVersion>
|
||||
<PackageVersion>$(AppVeyor_Build_Version)</PackageVersion>
|
||||
<Authors>Michael Ganss</Authors>
|
||||
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
|
||||
<AssemblyName>HtmlSanitizer</AssemblyName>
|
||||
@@ -31,7 +31,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" Version="[0.13.0]" />
|
||||
<PackageReference Include="AngleSharp.Css" Version="[0.13.0]" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.6.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -91,12 +91,12 @@ namespace Ganss.XSS
|
||||
Regex DisallowCssPropertyValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the allowed CSS classes.
|
||||
/// Gets or sets the allowed CSS classes. If the set is empty, all classes will be allowed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The allowed CSS classes.
|
||||
/// The allowed CSS classes. An empty set means all classes are allowed.
|
||||
/// </value>
|
||||
ISet<string> AllowedCssClasses { get; }
|
||||
ISet<string> AllowedClasses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after sanitizing the document and post processing nodes.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.1;net46</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp2.2;net46</TargetFrameworks>
|
||||
<AssemblyName>HtmlSanitizer.Tests</AssemblyName>
|
||||
<PackageId>HtmlSanitizer.Tests</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
@@ -25,17 +25,17 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.7.0">
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.8.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="AngleSharp.Xml" Version="0.13.0" />
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.7.0">
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.8.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
@@ -46,7 +46,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages">
|
||||
<Version>4.6.0</Version>
|
||||
<Version>4.7.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1497,6 +1497,7 @@ S
|
||||
{
|
||||
Assert.Equal(expected, actual, ignoreCase: true);
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -1508,6 +1509,7 @@ S
|
||||
|
||||
Assert.Equal(expectedNet35, actual, ignoreCase: true);
|
||||
}
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2546,7 +2548,7 @@ rl(javascript:alert(""foo""))'>";
|
||||
RemoveReason? reason = null;
|
||||
string removedClass = null;
|
||||
|
||||
var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "good" });
|
||||
var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "good" } };
|
||||
s.RemovingCssClass += (sender, args) =>
|
||||
{
|
||||
reason = args.Reason;
|
||||
@@ -2565,7 +2567,7 @@ rl(javascript:alert(""foo""))'>";
|
||||
RemoveReason? reason = null;
|
||||
string attributeName = null;
|
||||
|
||||
var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "other" });
|
||||
var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "other" } };
|
||||
s.RemovingAttribute += (sender, args) =>
|
||||
{
|
||||
attributeName = args.Attribute.Name;
|
||||
@@ -2907,11 +2909,13 @@ zqy1QY1kkPOuMvKWvvmFIwClI2393jVVcp91eda4+J+fIYDbfJa7RY5YcNrZhTuV//9k="">
|
||||
if (Interlocked.Decrement(ref waiting) == 0) allGo.Set();
|
||||
m.Invoke(tests, null);
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception ex)
|
||||
{
|
||||
Interlocked.CompareExchange(ref firstException, ex, null);
|
||||
Interlocked.Increment(ref failures);
|
||||
}
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
})).ToList();
|
||||
|
||||
foreach (var thread in threads)
|
||||
@@ -2938,7 +2942,7 @@ zqy1QY1kkPOuMvKWvvmFIwClI2393jVVcp91eda4+J+fIYDbfJa7RY5YcNrZhTuV//9k="">
|
||||
[Fact]
|
||||
public void AllowClassesTest()
|
||||
{
|
||||
var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "good" });
|
||||
var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "good" } };
|
||||
|
||||
var html = @"<div class=""good bad"">Test</div>";
|
||||
var actual = sanitizer.Sanitize(html);
|
||||
@@ -2965,22 +2969,10 @@ zqy1QY1kkPOuMvKWvvmFIwClI2393jVVcp91eda4+J+fIYDbfJa7RY5YcNrZhTuV//9k="">
|
||||
Assert.Equal(@"<div class=""good"">Test</div>", actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveClassAttributeIfNoAllowedClassesTest()
|
||||
{
|
||||
// Empty array for allowed classes = no classes allowed
|
||||
var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new string[0]);
|
||||
|
||||
var html = @"<div class=""good bad"">Test</div>";
|
||||
var actual = sanitizer.Sanitize(html);
|
||||
|
||||
Assert.Equal(@"<div>Test</div>", actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveClassAttributeIfEmptyTest()
|
||||
{
|
||||
var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "other" });
|
||||
var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "other" } };
|
||||
|
||||
var html = @"<div class=""good bad"">Test</div>";
|
||||
var actual = sanitizer.Sanitize(html);
|
||||
|
||||
Reference in New Issue
Block a user