"; string actual = sanitizer.Sanitize(htmlFragment); // Assert // intentionally keep it failing to get notice when reviewing unit tests so can disucss string expected = "
"; Assert.Equal(expected, actual, ignoreCase: true); } ///| ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// )\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " \"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// )\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " )\"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " \"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// )\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " )\"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// alert(\"XSS\");//<\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " \"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// alert(\"XSS\");//<)\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " )\"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// )\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// )\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// a=/XSS/alert(a.source)\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// a=/XSS/alert(a.source))\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = @"";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// \" SRC=\"http://ha.ckers.org/xss.js\">\">";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = " \" SRC=\"http://ha.ckers.org/xss.js\">\"> ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// Test ";
string actual = sanitizer.Sanitize(htmlFragment);
// Assert
string expected = "![]() Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// ![]() ";
actual = sanitizer.Sanitize(html);
expected = @"";
Assert.Equal(expected, actual, ignoreCase: true);
html = @"";
actual = sanitizer.Sanitize(html);
expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
html = @"";
actual = sanitizer.Sanitize(html);
expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
html = @" ";
actual = sanitizer.Sanitize(html);
expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
html = @"";
actual = sanitizer.Sanitize(html);
expected = "";
Assert.Equal(expected, actual, ignoreCase: true);
html = " Test ";
actual = sanitizer.Sanitize(html, "http://www.example.com");
expected = @"![]() Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// Test ";
var actual = sanitizer.Sanitize(html);
var expected = @"Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// test ";
var actual = sanitizer.Sanitize(html);
var expected = @"test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
/// o"; Assert.Equal(@"fo o", sanitizer.Sanitize(html), ignoreCase: true); html = @"foo"; Assert.Equal(html, sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeEscapeTextTest() { var sanitizer = Sanitizer; var html = @"fo&"; Assert.Equal(@"fo&", sanitizer.Sanitize(html), ignoreCase: true); html = @"<foo>"; Assert.Equal(@"<foo>", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeEntityrefTextTest() { var sanitizer = Sanitizer; var html = @"foö"; Assert.Equal(@"foö", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeEscapeAttrTest() { var sanitizer = Sanitizer; var html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeCloseEmptyTagTest() { var sanitizer = Sanitizer; var html = @"fo o"; Assert.Equal(@"fo o", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeInvalidEntityTest() { var sanitizer = Sanitizer; var html = @"&junk;"; Assert.Equal(@"&junk;", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeRemoveScriptElemTest() { var sanitizer = Sanitizer; var html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeRemoveOnclickAttrTest() { var sanitizer = Sanitizer; var html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeRemoveCommentsTest() { var sanitizer = Sanitizer; var html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeRemoveStyleScriptsTest() { var sanitizer = Sanitizer; // Inline style with url() using javascript: scheme var html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
// Inline style with url() using javascript: scheme, using control char
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
// Inline style with url() using javascript: scheme, in quotes
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
// IE expressions in CSS not allowed
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
// Inline style with url() using javascript: scheme, using unicode
// escapes
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
html = @" ";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeRemoveStylePhishingTest()
{
var sanitizer = Sanitizer;
// The position property is not allowed
var html = @"";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
// Normal margins get passed through
html = @"";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeRemoveSrcJavascriptTest()
{
var sanitizer = Sanitizer;
var html = @" XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void CapitalExpressionTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeUrlWithJavascriptTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeCapitalUrlWithJavascriptTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeUnicodeEscapesTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeBackslashWithoutHexTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeUnsafePropsTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeCssHackTest()
{
var sanitizer = Sanitizer;
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizePropertyNameTest()
{
var sanitizer = Sanitizer;
var html = @"prop ";
Assert.Equal(@"prop ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeUnicodeExpressionTest()
{
var sanitizer = Sanitizer;
// Fullwidth small letters
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
// Fullwidth capital letters
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
// IPA extensions
html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void SanitizeUnicodeUrlTest()
{
var sanitizer = Sanitizer;
// IPA extensions
var html = @"XSS ";
Assert.Equal(@"XSS ", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void RemovingTagEventTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.RemovingTag += (s, e) => e.Cancel = e.Tag.NodeName == "BLINK";
var html = @"";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void RemovingAttributeEventTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.RemovingAttribute += (s, e) => e.Cancel = e.Attribute.Name == "onclick";
var html = @"";
Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true);
}
[Fact]
public void RemovingAttributeEventTagTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.RemovingAttribute += (s, e) => Assert.IsAssignableFrom"; string actual = sanitizer.Sanitize(htmlFragment); // Assert string expected = " "; Assert.Equal(expected, actual, ignoreCase: true); } [Fact] public void AllowDataAttributesTest() { var sanitizer = new HtmlSanitizer() { AllowDataAttributes = true }; var html = @""; Assert.Equal(html, sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void AllowDataAttributesCaseTest() { var sanitizer = new HtmlSanitizer() { AllowDataAttributes = true }; var html = @""; Assert.Equal(html, sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void AllowDataAttributesOffTest() { var sanitizer = new HtmlSanitizer() { AllowDataAttributes = false }; var html = @""; Assert.Equal(@"", sanitizer.Sanitize(html), ignoreCase: true); } [Fact] public void SanitizeNonClosedTagTest() { var sanitizer = Sanitizer; var html = @" Hallo ";
var actual = sanitizer.Sanitize(html);
Assert.Equal("Test1 Test2 Test3 Test4", actual);
}
[Fact]
public void KeepChildNodesTest()
{
var sanitizer = new HtmlSanitizer { KeepChildNodes = true };
sanitizer.AllowedTags.Remove("div");
var html = @"Test1 Bold Bold World ", sanitized, ignoreCase: true); } [Fact] public void AutoLinkTest() { var sanitizer = new HtmlSanitizer(); sanitizer.PostProcessNode += (s, e) => { if (e.Node is IText text) { var autolinked = Regex.Replace(text.NodeValue, @"https?://[^\s]+[^\s!?.:;,]+", m => $@"{m.Value}", RegexOptions.IgnoreCase); if (autolinked != text.NodeValue) { var f = new HtmlParser().ParseDocument(autolinked); foreach (var node in f.Body.ChildNodes) e.ReplacementNodes.Add(node); } } }; var html = @"Click here: http://example.com/. ";
Assert.Equal(@"Click here: http://example.com/. ", sanitizer.Sanitize(html), ignoreCase: true);
Assert.Equal(@"Check out https://www.google.com.", sanitizer.Sanitize("Check out https://www.google.com."), ignoreCase: true);
}
[Fact]
public void RussianTextTest()
{
// Arrange
var s = Sanitizer;
// Act
var htmlFragment = "Тест";
var actual = s.Sanitize(htmlFragment, "");
// Assert
var expected = htmlFragment;
Assert.Equal(expected, actual, ignoreCase: true);
}
[Fact]
public void DisallowCssPropertyValueTest()
{
// Arrange
var s = new HtmlSanitizer { DisallowCssPropertyValue = new Regex(@"^rgba\(0.*") };
// Act
var htmlFragment = @"Test ";
var actual = s.Sanitize(htmlFragment);
// Assert
var expected = @"Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
[Fact]
public void CssKeyTest()
{
// Arrange
var s = Sanitizer;
// Act
var htmlFragment = @"Test ";
var actual = s.Sanitize(htmlFragment);
// Assert
var expected = @"Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
[Fact]
public void InvalidBaseUrlTest()
{
// Arrange
var s = Sanitizer;
// Act
var htmlFragment = @"Test ";
var actual = s.Sanitize(htmlFragment, "hallo");
// Assert
var expected = @"Test ";
Assert.Equal(expected, actual, ignoreCase: true);
}
[Fact]
public void XhtmlTest()
{
// Arrange
var s = Sanitizer;
// Act
var htmlFragment = @"Test ");
Assert.Equal("bad", removedClass);
Assert.Equal(RemoveReason.NotAllowedCssClass, reason);
}
[Fact]
public void RemoveEventForEmptyClassAttributeAfterClassRemoval()
{
RemoveReason? reason = null;
string attributeName = null;
var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "other" });
s.RemovingAttribute += (sender, args) =>
{
attributeName = args.Attribute.Name;
reason = args.Reason;
};
s.Sanitize(@"Test ");
Assert.Equal("class", attributeName);
Assert.Equal(RemoveReason.ClassAttributeEmpty, reason);
}
[Fact]
public void DocumentTest()
{
var s = new HtmlSanitizer();
s.AllowedTags.Add("title");
var html = "Test ";
var actual = s.SanitizeDocument(html);
Assert.Equal(html, actual);
}
[Fact]
public void DocumentFromFragmentTest()
{
var s = Sanitizer;
var html = "Test ";
var actual = s.SanitizeDocument(html);
Assert.Equal("Test ", actual);
}
[Fact]
public void FragmentFromDocumentTest()
{
var s = Sanitizer;
var html = "Test ";
var actual = s.Sanitize(html);
Assert.Equal("Test ", actual);
}
[Fact]
public void StyleTagTest()
{
var s = new HtmlSanitizer();
s.AllowedTags.Add("style");
var html = "Test ";
var actual = s.SanitizeDocument(html);
Assert.Equal("Test ", actual);
}
[Fact]
public void StyleAtTest()
{
var s = new HtmlSanitizer();
s.AllowedTags.Add("style");
s.AllowedAtRules.Add(AngleSharp.Css.Dom.CssRuleType.Media);
s.AllowedAtRules.Add(AngleSharp.Css.Dom.CssRuleType.Keyframes);
s.AllowedAtRules.Add(AngleSharp.Css.Dom.CssRuleType.Keyframe);
s.AllowedAtRules.Add(AngleSharp.Css.Dom.CssRuleType.Page);
var html = @"";
var actual = s.SanitizeDocument(html);
Assert.Equal(@"".Replace("\r\n", "\n"),
actual);
}
[Fact]
public void DataTest()
{
// https://github.com/mganss/HtmlSanitizer/issues/66
var sanitizer = new HtmlSanitizer()
{
AllowDataAttributes = true
};
sanitizer.AllowedSchemes.Add("data");
var html = @"
Test "; var actual = s.Sanitize(html); Assert.Equal("Test ", actual); } [Fact] public void OpenTagFragmentTest() { // https://github.com/mganss/HtmlSanitizer/issues/75 var s = Sanitizer; var html = "abc Test4 Test2 Test4 ";
var actual = sanitizer.Sanitize(html);
Assert.Equal("Test1 Test2 Test3 Test4", actual);
}
[Fact]
public void NormalizeTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.PostProcessNode += (s, e) =>
{
Assert.Single(e.Document.Body.ChildNodes);
var text = e.Node as IText;
Assert.NotNull(text);
Assert.Equal("Test1Test2", text.NodeValue);
};
var html = @"Test1Test2";
var actual = sanitizer.Sanitize(html);
Assert.Equal("Test1Test2", actual);
}
[Fact]
public void RemovingCommentTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.RemovingComment += (s, e) => e.Cancel = e.Comment.TextContent.Contains("good comment");
var html = @"";
var actual = sanitizer.Sanitize(html);
Assert.Equal("", actual);
}
[Fact]
public void TrailingSlashTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedSchemes.Add("resources");
var html = " ";
var actual = sanitizer.Sanitize(html);
Assert.Equal(html, actual, ignoreCase: true);
}
[Fact]
public void FileUrlTest()
{
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedSchemes.Add("file");
var html = @"test";
var actual = sanitizer.Sanitize(html);
Assert.Equal(html, actual);
}
[Fact]
public void SvgTest()
{
// https://github.com/mganss/HtmlSanitizer/issues/119
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedTags.Add("svg");
var html = @"";
var actual = sanitizer.Sanitize(html);
Assert.Equal("", actual);
}
[Fact]
public void SquareBracketTest()
{
// https://github.com/mganss/HtmlSanitizer/issues/137
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedAttributes.Add("[minutes]");
var html = @"123 ";
var actual = sanitizer.Sanitize(html);
Assert.Equal(html, actual);
}
[Fact]
public void FilterUrlTest()
{
// https://github.com/mganss/HtmlSanitizer/issues/156
var sanitizer = new HtmlSanitizer();
sanitizer.FilterUrl += (s, e) => e.SanitizedUrl = "https://www.example.com/test.png";
var html = @" |