Compare commits

...

11 Commits

Author SHA1 Message Date
Michael Ganss
e709a525f3 Remove beta label 2020-02-28 17:01:21 +01:00
Michael Ganss
146d5e4f60 Fix #206 2020-02-28 16:50:59 +01:00
Michael Ganss
3a1c6f73ef Merge pull request #208 from mganss/dependabot/nuget/Microsoft.NET.Test.Sdk-16.5.0
Bump Microsoft.NET.Test.Sdk from 16.4.0 to 16.5.0
2020-02-06 11:38:12 +01:00
dependabot-preview[bot]
f3988f9bbe Bump Microsoft.NET.Test.Sdk from 16.4.0 to 16.5.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.4.0 to 16.5.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v16.4.0...v16.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-06 04:35:11 +00:00
Michael Ganss
4afaf4bd57 Fix/ignore code analysis issues 2020-01-24 13:40:13 +01:00
Michael Ganss
088a429ff4 Target netcoreapp2.2 in test project 2020-01-24 12:41:21 +01:00
Michael Ganss
60e35106c1 Include framework in coverage file name
Target netcoreapp2.2 in test project
2020-01-24 12:37:32 +01:00
Michael Ganss
db8012157c Merge pull request #204 from mganss/dependabot/nuget/coverlet.msbuild-2.8.0
Bump coverlet.msbuild from 2.7.0 to 2.8.0
2020-01-06 11:34:51 +01:00
dependabot-preview[bot]
970b963de0 Bump coverlet.msbuild from 2.7.0 to 2.8.0
Bumps [coverlet.msbuild](https://github.com/tonerdo/coverlet) from 2.7.0 to 2.8.0.
- [Release notes](https://github.com/tonerdo/coverlet/releases)
- [Commits](https://github.com/tonerdo/coverlet/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 04:34:51 +00:00
Michael Ganss
81d967943e Merge pull request #201 from mganss/dependabot/nuget/System.Text.Encoding.CodePages-4.7.0
Bump System.Text.Encoding.CodePages from 4.6.0 to 4.7.0
2019-12-04 11:53:14 +01:00
dependabot-preview[bot]
f275182881 Bump System.Text.Encoding.CodePages from 4.6.0 to 4.7.0
Bumps [System.Text.Encoding.CodePages](https://github.com/dotnet/corefx) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/dotnet/corefx/releases)
- [Commits](https://github.com/dotnet/corefx/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 04:31:56 +00:00
6 changed files with 36 additions and 41 deletions

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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.

View File

@@ -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>

View File

@@ -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);