From 42e18a1cc9b0a6caef6e56d9eb38bedd3c12cb30 Mon Sep 17 00:00:00 2001 From: strangelookingnerd <49242855+strangelookingnerd@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:44:44 +0100 Subject: [PATCH 1/2] Migrate tests to JUnit Jupiter * Migrate annotations and imports * Migrate assertions * Remove public visibility for test classes and methods * Minor code cleanup --- java10-shim/pom.xml | 4 +- java8-shim/pom.xml | 4 +- owasp-java-html-sanitizer/pom.xml | 4 +- .../java/org/owasp/html/AntiSamyTest.java | 120 +++---- .../test/java/org/owasp/html/Benchmark.java | 13 +- .../java/org/owasp/html/CssFuzzerTest.java | 21 +- .../java/org/owasp/html/CssGrammarTest.java | 117 +++---- .../java/org/owasp/html/CssSchemaTest.java | 37 +- .../java/org/owasp/html/CssTokensTest.java | 217 ++++++------ .../org/owasp/html/ElementPolicyTest.java | 14 +- .../java/org/owasp/html/EncodingTest.java | 35 +- .../java/org/owasp/html/ExamplesTest.java | 18 +- .../java/org/owasp/html/FuzzyTestCase.java | 13 +- .../owasp/html/HtmlChangeReporterTest.java | 10 +- .../org/owasp/html/HtmlElementTablesTest.java | 34 +- .../java/org/owasp/html/HtmlLexerTest.java | 17 +- .../html/HtmlPolicyBuilderFuzzerTest.java | 23 +- .../org/owasp/html/HtmlPolicyBuilderTest.java | 321 ++++++++---------- .../owasp/html/HtmlSanitizerFuzzerTest.java | 32 +- .../org/owasp/html/HtmlSanitizerTest.java | 133 ++++---- .../owasp/html/HtmlStreamRendererTest.java | 182 +++++----- .../java/org/owasp/html/IntVectorTest.java | 12 +- .../org/owasp/html/PolicyFactoryTest.java | 71 ++-- .../java/org/owasp/html/SanitizersTest.java | 81 +++-- .../test/java/org/owasp/html/StringsTest.java | 9 +- .../org/owasp/html/StylingPolicyTest.java | 54 ++- .../TagBalancingHtmlStreamRendererTest.java | 73 ++-- .../org/owasp/html/UrlTextExampleTest.java | 11 +- .../org/owasp/html/VerboseTestRunner.java | 85 ----- pom.xml | 7 +- 30 files changed, 817 insertions(+), 955 deletions(-) delete mode 100644 owasp-java-html-sanitizer/src/test/java/org/owasp/html/VerboseTestRunner.java diff --git a/java10-shim/pom.xml b/java10-shim/pom.xml index 080a7119..c3492999 100644 --- a/java10-shim/pom.xml +++ b/java10-shim/pom.xml @@ -37,8 +37,8 @@ java8-shim - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/java8-shim/pom.xml b/java8-shim/pom.xml index 47614e61..ae928a9b 100644 --- a/java8-shim/pom.xml +++ b/java8-shim/pom.xml @@ -18,8 +18,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/owasp-java-html-sanitizer/pom.xml b/owasp-java-html-sanitizer/pom.xml index c4597c03..424ffb65 100644 --- a/owasp-java-html-sanitizer/pom.xml +++ b/owasp-java-html-sanitizer/pom.xml @@ -114,8 +114,8 @@ provided - junit - junit + org.junit.jupiter + junit-jupiter test diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/AntiSamyTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/AntiSamyTest.java index 3a09d02e..a642c2d6 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/AntiSamyTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/AntiSamyTest.java @@ -24,15 +24,19 @@ package org.owasp.html; -import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; import org.apache.commons.codec.binary.Base64; -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -42,26 +46,19 @@ * @author Arshan Dabirsiaghi * */ -@SuppressWarnings("javadoc") -public class AntiSamyTest extends TestCase { +class AntiSamyTest { - static final boolean RUN_KNOWN_FAILURES = false; + private static final boolean RUN_KNOWN_FAILURES = false; private static HtmlSanitizer.Policy makePolicy(Appendable buffer) { final HtmlStreamRenderer renderer = HtmlStreamRenderer.create( buffer, - new Handler() { - public void handle(IOException ex) { - AssertionFailedError failure = new AssertionFailedError(); - failure.initCause(ex); - throw failure; - } - }, - new Handler() { - public void handle(String errorMessage) { - fail(errorMessage); - } - }); + ex -> { + AssertionFailedError failure = new AssertionFailedError(); + failure.initCause(ex); + throw failure; + }, + Assertions::fail); return new HtmlPolicyBuilder() .allowElements( @@ -73,12 +70,7 @@ public void handle(String errorMessage) { .allowAttributes("src").onElements("img") .allowAttributes("class", "id", "title").globally() .allowAttributes("char").matching( - new AttributePolicy() { - public String apply( - String elementName, String attributeName, String value) { - return value.length() == 1 ? value : null; - } - }).onElements("td") + (elementName, attributeName, value) -> value.length() == 1 ? value : null).onElements("td") .allowStandardUrlProtocols() .requireRelNofollowOnLinks() .allowStyling() @@ -113,26 +105,12 @@ static String sanitize(String html) { "C3c+d5Q9lyTafPLdelG1TKaLFinw1TOjyI6KkrQyHKkttfnO58WFvScl1TiRcB/iHxKahskoE2+VRLUIhctuDU4sUvQh/g9Arw0LAA4QTxuLFt01XYdigurz4FT15ox2oDGGGrRb3VGjDTXK1OWVJoLMW95EVqyMc9F+Fdej85LHE+8WesIfacjUQtTG1tzYVQTfubZq0+qxXws8QrxMLFtVE38tbeXo+Ok1/U5TUa6FjWflEfvKY3XVcl8RKkXua7fVz/Blj8Gh+dWe2cOxa0lpM75ZHyz9adQrB2Pb4571E4u2xI5un0R0MFJZBQuPDc1G5rPhyk+Hb4LRG3dS0m8IASQUOskv93z978L1+Abu9CLP6d6s5p+BzWxhMUqwQXC/CCpTywrkJ0RG", }; - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AntiSamyTest.class); - return suite; - } - /* * Test basic XSS cases. */ - public static void testScriptAttacks() { + @Test + void testScriptAttacks() { assertSanitizedDoesNotContain("test", "script"); assertSanitizedDoesNotContain("test", "script"); @@ -161,7 +139,8 @@ public static void testScriptAttacks() { assertSanitizedDoesNotContain("Google", "alert"); } - public static void testImgAttacks() { + @Test + void testImgAttacks() { assertSanitizedDoesContain("", "", "", "alert"); String s = ""; - if (sanitize(s).length() != 0) { + if (!sanitize(s).isEmpty()) { assertSanitizedDoesContain(s, "&"); } s = ""; - if (sanitize(s).length() != 0) { + if (!sanitize(s).isEmpty()) { assertSanitizedDoesContain(s, "&"); } @@ -198,7 +177,8 @@ public static void testImgAttacks() { assertSanitizedDoesNotContain("", "javascript"); } - public static void testHrefAttacks() { + @Test + void testHrefAttacks() { assertSanitizedDoesNotContain("", "href"); assertSanitizedDoesNotContain("", "href"); @@ -304,7 +284,8 @@ public static void testHrefAttacks() { * Test CSS protections. */ - public static void testCssAttacks() { + @Test + void testCssAttacks() { assertSanitizedDoesNotContain("
", "position"); assertSanitizedDoesNotContain("
", "position"); @@ -323,14 +304,15 @@ public static void testCssAttacks() { * Test a bunch of strings that have tweaked the XML parsing capabilities of * NekoHTML. */ - public static void testIllegalXML() throws Exception { - for (int i = 0; i < BASE64_BAD_XML_STRINGS.length; i++) { - String testStr = new String( - Base64.decodeBase64(BASE64_BAD_XML_STRINGS[i]), - "UTF-8"); - sanitize(testStr); - sanitize(testStr); - } + @Test + void testIllegalXML() { + for (String base64BadXmlString : BASE64_BAD_XML_STRINGS) { + String testStr = new String( + Base64.decodeBase64(base64BadXmlString), + StandardCharsets.UTF_8); + sanitize(testStr); + sanitize(testStr); + } // These fail in AntiSamy due to a bug in NekoHTML assertEquals( @@ -340,10 +322,11 @@ public static void testIllegalXML() throws Exception { "", sanitize("")); - assertTrue(sanitize("", "", "<!--", "-->", "<![CDATA[", "]]>", }; - static final String[] ELEMENT_NAMES = { + private static final String[] ELEMENT_NAMES = { "a", "A", "b", "B", "script", "SCRipT", @@ -80,11 +84,12 @@ public class HtmlPolicyBuilderFuzzerTest extends FuzzyTestCase { "xmp", "XMP", }; - static final String[] ATTR_NAMES = { + private static final String[] ATTR_NAMES = { "href", "id", "class", "onclick", "checked", "style", }; - public final void testFuzzedOutput() throws IOException, SAXException { + @Test + void testFuzzedOutput() throws IOException, SAXException { boolean passed = false; try { for (int i = 1000; --i >= 0;) { @@ -146,9 +151,9 @@ private static void checkSafe(Node node, String html) { if ("title".equals(a.getName())) { // ok } else if ("href".equals(a.getName())) { - assertEquals(html, "a", name); + assertEquals("a", name, html); assertFalse( - html, Strings.toLowerCase(a.getValue()).contains("script:")); + Strings.toLowerCase(a.getValue()).contains("script:"), html); } } break; diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java index 3ac35180..6eda22cf 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java @@ -32,16 +32,17 @@ import java.util.Locale; import java.util.regex.Pattern; -import org.junit.Test; - -import junit.framework.TestCase; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.owasp.shim.Java8Shim.j8; -@SuppressWarnings({"javadoc", "HttpUrlsUsage", "RedundantSuppression", "UnnecessaryUnicodeEscape"}) -public class HtmlPolicyBuilderTest extends TestCase { +@SuppressWarnings({"HttpUrlsUsage", "RedundantSuppression", "UnnecessaryUnicodeEscape"}) +class HtmlPolicyBuilderTest { - static final String EXAMPLE = String.join( + private static final String EXAMPLE = String.join( "\n", "<h1 id='foo'>Header</h1>", "<p onclick='alert(42)'>Paragraph 1<script>evil()</script></p>", @@ -57,7 +58,7 @@ public class HtmlPolicyBuilderTest extends TestCase { ""); @Test - public final void testTextFilter() { + void testTextFilter() { assertEquals( String.join( "\n", @@ -74,7 +75,7 @@ public final void testTextFilter() { } @Test - public final void testCannedFormattingTagFilter() { + void testCannedFormattingTagFilter() { assertEquals( String.join( "\n", @@ -91,7 +92,7 @@ public final void testCannedFormattingTagFilter() { } @Test - public final void testCannedFormattingTagFilterNoItalics() { + void testCannedFormattingTagFilterNoItalics() { assertEquals( String.join( "\n", @@ -109,7 +110,7 @@ public final void testCannedFormattingTagFilterNoItalics() { } @Test - public final void testSimpleTagFilter() { + void testSimpleTagFilter() { assertEquals( String.join( "\n", @@ -126,7 +127,7 @@ public final void testSimpleTagFilter() { } @Test - public final void testLinksAllowed() { + void testLinksAllowed() { assertEquals( String.join( "\n", @@ -145,7 +146,7 @@ public final void testLinksAllowed() { } @Test - public final void testExternalLinksAllowed() { + void testExternalLinksAllowed() { assertEquals( String.join( "\n", @@ -166,7 +167,7 @@ public final void testExternalLinksAllowed() { } @Test - public final void testLinksWithNofollow() { + void testLinksWithNofollow() { assertEquals( String.join( "\n", @@ -186,7 +187,7 @@ public final void testLinksWithNofollow() { } @Test - public final void testLinksWithNofollowAlreadyPresent() { + void testLinksWithNofollowAlreadyPresent() { assertEquals( "html <a href=\"/\" rel=\"nofollow\">link</a>", apply( @@ -198,7 +199,7 @@ public final void testLinksWithNofollowAlreadyPresent() { } @Test - public final void testImagesAllowed() { + void testImagesAllowed() { assertEquals( String.join( "\n", @@ -218,7 +219,7 @@ public final void testImagesAllowed() { } @Test - public final void testStyleFiltering() { + void testStyleFiltering() { assertEquals( String.join( "\n", @@ -240,7 +241,7 @@ public final void testStyleFiltering() { } @Test - public void testSpecificStyleFilterung() { + void testSpecificStyleFilterung() { assertEquals( String.join( "\n", @@ -261,7 +262,7 @@ public void testSpecificStyleFilterung() { } @Test - public void testCustomPropertyStyleFiltering() { + void testCustomPropertyStyleFiltering() { assertEquals( String.join( "\n", @@ -287,7 +288,7 @@ public void testCustomPropertyStyleFiltering() { } @Test - public void testUnionStyleFiltering() { + void testUnionStyleFiltering() { assertEquals( String.join( "\n", @@ -310,7 +311,7 @@ public void testUnionStyleFiltering() { } @Test - public void testCustomPropertyStyleFilteringDisallowed() { + void testCustomPropertyStyleFilteringDisallowed() { assertEquals( String.join( "\n", @@ -336,7 +337,7 @@ public void testCustomPropertyStyleFilteringDisallowed() { } @Test - public final void testElementTransforming() { + void testElementTransforming() { assertEquals( String.join( "\n", @@ -360,7 +361,7 @@ public final void testElementTransforming() { } @Test - public final void testBodyTransforming() { + void testBodyTransforming() { assertEquals( "<div>foo</div>", apply( @@ -371,8 +372,9 @@ public final void testBodyTransforming() { .allowElements("div"), "<body>foo</body>")); } + @Test - public final void testAllowUrlProtocols() { + void testAllowUrlProtocols() { assertEquals( String.join( "\n", @@ -392,7 +394,7 @@ public final void testAllowUrlProtocols() { } @Test - public final void testDisallowUrlProtocols() { + void testDisallowUrlProtocols() { assertEquals( String.join( "\n", @@ -412,7 +414,7 @@ public final void testDisallowUrlProtocols() { } @Test - public final void testPossibleFalloutFromIssue5() { + void testPossibleFalloutFromIssue5() { assertEquals( "Bad", apply( @@ -425,7 +427,7 @@ public final void testPossibleFalloutFromIssue5() { } @Test - public final void testTextInOption() { + void testTextInOption() { assertEquals( "<select><option>1</option><option>2</option></select>", apply( @@ -436,7 +438,7 @@ public final void testTextInOption() { } @Test - public final void testEntities() { + void testEntities() { assertEquals( "(Foo)\u00a0(Bar)\u2666\u2666\u2666\u2666(Baz)" + "&#x14834;&#x14834;&#x14834;(Boo)", @@ -447,7 +449,7 @@ public final void testEntities() { } @Test - public final void testImageTag() { + void testImageTag() { assertEquals( "" + "<img src=\"http://example.com/foo.png\" />" @@ -458,13 +460,7 @@ public final void testImageTag() { new HtmlPolicyBuilder() .allowElements("img") .allowElements( - new ElementPolicy() { - - public String apply(String elementName, List<String> attrs) { - return "img"; - } - - }, "image") + (elementName, attrs) -> "img", "image") .allowAttributes("src").onElements("img", "image") .allowStandardUrlProtocols(), "" @@ -474,7 +470,7 @@ public String apply(String elementName, List<String> attrs) { } @Test - public final void testImgSrcsetSyntax() { + void testImgSrcsetSyntax() { assertEquals( "" + "<img srcset=\"http://example.com/foo.png\" />\n" @@ -534,7 +530,7 @@ public final void testImgSrcsetSyntax() { } @Test - public final void testUrlChecksLayer() { + void testUrlChecksLayer() { assertEquals( "" + "<img src=\"http://example.com/OK.png\" />\n" @@ -557,7 +553,7 @@ public final void testUrlChecksLayer() { } @Test - public final void testDuplicateAttributesDoNotReachElementPolicy() { + void testDuplicateAttributesDoNotReachElementPolicy() { final int[] idCount = new int[1]; assertEquals( // The id that is emitted is the first that passes the attribute @@ -570,24 +566,19 @@ public final void testDuplicateAttributesDoNotReachElementPolicy() { apply( new HtmlPolicyBuilder() .allowElements( - new ElementPolicy() { - public String apply(String elementName, List<String> attrs) { - int nAttrs = attrs.size() / 2; - attrs.add("attr-count"); - attrs.add("" + nAttrs); - attrs.add("id-count"); - attrs.add("" + idCount[0]); - return elementName; - } - }, + (elementName, attrs) -> { + int nAttrs = attrs.size() / 2; + attrs.add("attr-count"); + attrs.add("" + nAttrs); + attrs.add("id-count"); + attrs.add("" + idCount[0]); + return elementName; + }, "a" ) - .allowAttributes("id").matching(new AttributePolicy() { - public String apply( - String elementName, String attributeName, String value) { - ++idCount[0]; - return value.startsWith("b") ? value : null; - } + .allowAttributes("id").matching((elementName, attributeName, value) -> { + ++idCount[0]; + return value.startsWith("b") ? value : null; }).onElements("a") .allowAttributes("href").onElements("a"), "<a href=\"foo\" id='far' id=\"bar\" href=baz id=boo>link</a>") @@ -595,7 +586,7 @@ public String apply( } @Test - public final void testPreprocessors() { + void testPreprocessors() { String input = "<h1 title='foo'>one</h1> <h2>Two!</h2> <h3>three</h3>" + " <h4>Four</h4> <h5>5</h5> <h6>seis</h6>"; @@ -612,51 +603,43 @@ public final void testPreprocessors() { new HtmlPolicyBuilder() .allowElements("h1", "h2", "h3", "h4", "h5", "h6") .allowAttributes("title").globally() - .withPreprocessor(new HtmlStreamEventProcessor() { - public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver r) { - return new HtmlStreamEventReceiverWrapper(r) { - @Override - public void text(String s) { - underlying.text(s.toUpperCase(Locale.ROOT)); - } - @Override - public String toString() { - return "shouty-text"; - } - }; + .withPreprocessor(r -> new HtmlStreamEventReceiverWrapper(r) { + @Override + public void text(String s) { + underlying.text(s.toUpperCase(Locale.ROOT)); + } + @Override + public String toString() { + return "shouty-text"; } }) - .withPreprocessor(new HtmlStreamEventProcessor() { - public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver r) { - return new HtmlStreamEventReceiverWrapper(r) { - @Override - public void openTag(String elementName, List<String> attrs) { - underlying.openTag(incr(elementName), attrs); - } + .withPreprocessor(r -> new HtmlStreamEventReceiverWrapper(r) { + @Override + public void openTag(String elementName, List<String> attrs) { + underlying.openTag(incr(elementName), attrs); + } - @Override - public void closeTag(String elementName) { - underlying.closeTag(incr(elementName)); - } + @Override + public void closeTag(String elementName) { + underlying.closeTag(incr(elementName)); + } - String incr(String en) { - if (en.length() == 2) { - char c0 = en.charAt(0); - char c1 = en.charAt(1); - if ((c0 == 'h' || c0 == 'H') - && '0' <= c1 && c1 <= '6') { - // h1 -> h2, h2 -> h3, etc. - return "h" + (c1 - '0' + 1); - } - } - return en; + String incr(String en) { + if (en.length() == 2) { + char c0 = en.charAt(0); + char c1 = en.charAt(1); + if ((c0 == 'h' || c0 == 'H') + && '0' <= c1 && c1 <= '6') { + // h1 -> h2, h2 -> h3, etc. + return "h" + (c1 - '0' + 1); } + } + return en; + } - @Override - public String toString() { - return "incr-headers"; - } - }; + @Override + public String toString() { + return "incr-headers"; } }), @@ -665,7 +648,7 @@ public String toString() { @Test - public final void testPostprocessors() { + void testPostprocessors() { String input = "<h1 title='foo'>one</h1> <h2>TWO!</h2> <h3>three</h3>" + " <h4>Four</h4> <h5>5</h5> <h6>seis</h6>"; @@ -683,58 +666,50 @@ public final void testPostprocessors() { new HtmlPolicyBuilder() .allowElements("h1", "h2", "h3", "h4", "h5", "h6") .allowAttributes("title").globally() - .withPostprocessor(new HtmlStreamEventProcessor() { - public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver r) { - return new HtmlStreamEventReceiverWrapper(r) { - @Override - public void text(String s) { - if (!s.isEmpty()) { - int cp0 = s.codePointAt(0); - underlying.text( - new StringBuilder(s.length()) - .appendCodePoint(Character.toUpperCase(cp0)) - .append(s, Character.charCount(cp0), s.length()) - .toString()); - } - } - @Override - public String toString() { - return "shouty-text"; - } - }; + .withPostprocessor(r -> new HtmlStreamEventReceiverWrapper(r) { + @Override + public void text(String s) { + if (!s.isEmpty()) { + int cp0 = s.codePointAt(0); + underlying.text( + new StringBuilder(s.length()) + .appendCodePoint(Character.toUpperCase(cp0)) + .append(s, Character.charCount(cp0), s.length()) + .toString()); + } + } + @Override + public String toString() { + return "shouty-text"; } }) - .withPostprocessor(new HtmlStreamEventProcessor() { - public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver r) { - return new HtmlStreamEventReceiverWrapper(r) { - @Override - public void openTag(String elementName, List<String> attrs) { - underlying.openTag(incr(elementName), attrs); - } + .withPostprocessor(r -> new HtmlStreamEventReceiverWrapper(r) { + @Override + public void openTag(String elementName, List<String> attrs) { + underlying.openTag(incr(elementName), attrs); + } - @Override - public void closeTag(String elementName) { - underlying.closeTag(incr(elementName)); - } + @Override + public void closeTag(String elementName) { + underlying.closeTag(incr(elementName)); + } - String incr(String en) { - if (en.length() == 2) { - char c0 = en.charAt(0); - char c1 = en.charAt(1); - if ((c0 == 'h' || c0 == 'H') - && '0' <= c1 && c1 <= '6') { - // h1 -> h2, h2 -> h3, etc. - return "h" + (c1 - '0' + 1); - } - } - return en; + String incr(String en) { + if (en.length() == 2) { + char c0 = en.charAt(0); + char c1 = en.charAt(1); + if ((c0 == 'h' || c0 == 'H') + && '0' <= c1 && c1 <= '6') { + // h1 -> h2, h2 -> h3, etc. + return "h" + (c1 - '0' + 1); } + } + return en; + } - @Override - public String toString() { - return "incr-headers"; - } - }; + @Override + public String toString() { + return "incr-headers"; } }), @@ -743,7 +718,7 @@ public String toString() { } @Test - public final void testBackgroundImageWithUrl() { + void testBackgroundImageWithUrl() { PolicyFactory policy = new HtmlPolicyBuilder() .allowStandardUrlProtocols() .allowStyling() @@ -767,7 +742,7 @@ public final void testBackgroundImageWithUrl() { } @Test - public final void testBackgroundImageWithImageFunction() { + void testBackgroundImageWithImageFunction() { PolicyFactory policy = new HtmlPolicyBuilder() .allowStandardUrlProtocols() .allowStyling() @@ -791,7 +766,7 @@ public final void testBackgroundImageWithImageFunction() { } @Test - public final void testBackgroundWithUrls() { + void testBackgroundWithUrls() { HtmlPolicyBuilder builder = new HtmlPolicyBuilder() .allowStandardUrlProtocols() .allowStyling() @@ -814,7 +789,7 @@ public final void testBackgroundWithUrls() { } @Test - public final void testBackgroundsThatViolateGlobalUrlPolicy() { + void testBackgroundsThatViolateGlobalUrlPolicy() { PolicyFactory policy = new HtmlPolicyBuilder() .allowStandardUrlProtocols() .allowStyling() @@ -831,7 +806,7 @@ public final void testBackgroundsThatViolateGlobalUrlPolicy() { } @Test - public final void testSpanTagFilter() { + void testSpanTagFilter() { PolicyFactory policy = new HtmlPolicyBuilder() .allowElements("span") .allowWithoutAttributes("span") @@ -845,7 +820,7 @@ public final void testSpanTagFilter() { } @Test - public final void testLinkRels() { + void testLinkRels() { HtmlPolicyBuilder b = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a") @@ -894,7 +869,7 @@ public final void testLinkRels() { } @Test - public final void testLinkRelsWhenRelPresent() { + void testLinkRelsWhenRelPresent() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a") @@ -923,7 +898,7 @@ public final void testLinkRelsWhenRelPresent() { } @Test - public final void testRelLinksWhenRelIsPartOfData() { + void testRelLinksWhenRelIsPartOfData() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a") @@ -936,7 +911,7 @@ public final void testRelLinksWhenRelIsPartOfData() { } @Test - public final void testRelLinksWithDuplicateRels() { + void testRelLinksWithDuplicateRels() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a") @@ -948,7 +923,7 @@ public final void testRelLinksWithDuplicateRels() { } @Test - public final void testRelLinksWithDuplicateRelsRequired() { + void testRelLinksWithDuplicateRelsRequired() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a") @@ -961,7 +936,7 @@ public final void testRelLinksWithDuplicateRelsRequired() { } @Test - public final void testFailFastOnSpaceSeparatedStrings() { + void testFailFastOnSpaceSeparatedStrings() { boolean failed; try { // Should be ("nofollow", "noreferrer") @@ -981,7 +956,7 @@ public final void testFailFastOnSpaceSeparatedStrings() { } @Test - public final void testEmptyDefaultLinkRelsSet() { + void testEmptyDefaultLinkRelsSet() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href", "target").onElements("a") @@ -995,7 +970,7 @@ public final void testEmptyDefaultLinkRelsSet() { } @Test - public final void testRequireAndSkipRels() { + void testRequireAndSkipRels() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href", "target").onElements("a") @@ -1018,7 +993,7 @@ public final void testRequireAndSkipRels() { } @Test - public final void testSkipAndRequireRels() { + void testSkipAndRequireRels() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href", "target").onElements("a") @@ -1041,7 +1016,7 @@ public final void testSkipAndRequireRels() { } @Test - public final void testOverflowWrap() { + void testOverflowWrap() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("span") .allowStyling(CssSchema.union(CssSchema.DEFAULT, CssSchema.withProperties(j8().listOf("overflow-wrap")))) @@ -1061,7 +1036,7 @@ public final void testOverflowWrap() { } @Test - public final void testOverflowWrapNotAllowed() { + void testOverflowWrapNotAllowed() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("span") .allowStyling() @@ -1073,7 +1048,7 @@ public final void testOverflowWrapNotAllowed() { } @Test - public final void testExplicitRelsSkip() { + void testExplicitRelsSkip() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href", "target", "rel").onElements("a") @@ -1099,7 +1074,7 @@ public final void testExplicitRelsSkip() { } @Test - public final void testScopingExitInNoContent() { + void testScopingExitInNoContent() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("table", "tr", "td", "noscript") .toFactory(); @@ -1111,7 +1086,7 @@ public final void testScopingExitInNoContent() { } @Test - public final void testIssue80() { + void testIssue80() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("table", "tr", "td", "tbody") .toFactory(); @@ -1128,7 +1103,7 @@ public final void testIssue80() { } @Test - public final void testDirLi() { + void testDirLi() { assertEquals( "<dir compact=\"compact\"><li>something</li></dir>", apply( @@ -1139,7 +1114,7 @@ public final void testDirLi() { } @Test - public void testDisallowTextIn() { + void testDisallowTextIn() { HtmlPolicyBuilder sharedPolicyBuilder = new HtmlPolicyBuilder() .allowElements("div") .allowAttributes("style").onElements("div"); @@ -1156,7 +1131,7 @@ public void testDisallowTextIn() { } @Test - public void testDisallowAttribute() { + void testDisallowAttribute() { HtmlPolicyBuilder sharedPolicyBuilder = new HtmlPolicyBuilder() .allowElements("div", "p") .allowAttributes("style").onElements("div", "p"); @@ -1175,7 +1150,7 @@ public void testDisallowAttribute() { } @Test - public void testCreativeCSSStyling() { + void testCreativeCSSStyling() { PolicyFactory policy = new HtmlPolicyBuilder() .allowElements("p") .allowAttributes("style").onElements("p").allowStyling().toFactory(); @@ -1197,7 +1172,7 @@ public void testCreativeCSSStyling() { } @Test - public final void testScriptTagWithCommentBlockContainingHtmlCommentEnd() { + void testScriptTagWithCommentBlockContainingHtmlCommentEnd() { PolicyFactory scriptSanitizer = new HtmlPolicyBuilder() // allow scripts of type application/json .allowElements( @@ -1236,7 +1211,7 @@ public final void testScriptTagWithCommentBlockContainingHtmlCommentEnd() { } @Test - public final void testNoscriptInAttribute() { + void testNoscriptInAttribute() { PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("img", "p", "noscript") .allowAttributes("title").globally() @@ -1253,7 +1228,7 @@ public final void testNoscriptInAttribute() { } @Test - public final void testTableStructure() { + void testTableStructure() { String input = "<TABLE>" + "<TR><TD>Foo<TD>Bar" @@ -1270,7 +1245,7 @@ public final void testTableStructure() { } @Test - public final void testSvgNames() { + void testSvgNames() { PolicyFactory policyFactory = new HtmlPolicyBuilder() .allowElements("svg", "animateColor") .allowAttributes("viewBox").onElements("svg") @@ -1280,7 +1255,7 @@ public final void testSvgNames() { } @Test - public final void testTextareaIsNotTextArea() { + void testTextareaIsNotTextArea() { String input = "<textarea>x</textarea><textArea>y</textArea>"; PolicyFactory textareaPolicy = new HtmlPolicyBuilder().allowElements("textarea").toFactory(); PolicyFactory textAreaPolicy = new HtmlPolicyBuilder().allowElements("textArea").toFactory(); @@ -1289,13 +1264,13 @@ public final void testTextareaIsNotTextArea() { } @Test - public final void testHtmlPolicyBuilderDefinitionWithNoAttributesDefinedGlobally() { + void testHtmlPolicyBuilderDefinitionWithNoAttributesDefinedGlobally() { // Does not crash with a runtime exception new HtmlPolicyBuilder().allowElements().allowAttributes().globally().toFactory(); } @Test - public final void testCSSFontSize() { + void testCSSFontSize() { HtmlPolicyBuilder builder = new HtmlPolicyBuilder(); PolicyFactory factory = builder.allowElements("span") .allowAttributes("style").onElements("span").allowStyling() @@ -1308,7 +1283,7 @@ public final void testCSSFontSize() { } @Test - public final void testCSSChildCombinator() { + void testCSSChildCombinator() { HtmlPolicyBuilder builder = new HtmlPolicyBuilder(); PolicyFactory factory = builder.allowElements("span","style","h1").allowTextIn("style","h1") @@ -1349,6 +1324,6 @@ private static String apply(HtmlPolicyBuilder b) { private static String apply(HtmlPolicyBuilder b, String src) { return b.toFactory().sanitize( src, null, - (Handler<String>) TestCase::fail); + (Handler<String>) Assertions::fail); } } diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerFuzzerTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerFuzzerTest.java index 17d4c15a..40c4a211 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerFuzzerTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerFuzzerTest.java @@ -28,6 +28,8 @@ package org.owasp.html; +import org.junit.jupiter.api.Test; + import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -38,6 +40,8 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Throws malformed inputs at the HTML sanitizer to try and crash it. * This test is stochastic -- not guaranteed to pass or fail consistently. @@ -46,10 +50,9 @@ * * @author Mike Samuel (mikesamuel@gmail.com) */ -@SuppressWarnings("javadoc") -public class HtmlSanitizerFuzzerTest extends FuzzyTestCase { +class HtmlSanitizerFuzzerTest extends FuzzyTestCase { - static final HtmlSanitizer.Policy DO_NOTHING_POLICY + private static final HtmlSanitizer.Policy DO_NOTHING_POLICY = new HtmlSanitizer.Policy() { public void openDocument() { /* do nothing */ } public void closeDocument() { /* do nothing */ } @@ -60,7 +63,8 @@ public void closeTag(String elementName) { /* do nothing */ } public void text(String textChunk) { /* do nothing */ } }; - public final void testFuzzHtmlParser() throws Exception { + @Test + void testFuzzHtmlParser() throws Exception { String html; try (InputStream resourceStream = getClass().getClassLoader() .getResourceAsStream("benchmark-data/Yahoo!.html")) { @@ -136,22 +140,20 @@ public final void testFuzzHtmlParser() throws Exception { fuzzyHtml1 = swap; } final String fuzzyHtml = new String(fuzzyHtml0); - executor.execute(new Runnable() { - public void run() { - try { - HtmlSanitizer.sanitize(fuzzyHtml, DO_NOTHING_POLICY); - } catch (Exception ex) { - System.err.println( - "Using seed " + seed + "L\n" - + "Failed on <<<" + fuzzyHtml + ">>>"); - failures.add(ex); - } + executor.execute(() -> { + try { + HtmlSanitizer.sanitize(fuzzyHtml, DO_NOTHING_POLICY); + } catch (Exception ex) { + System.err.println( + "Using seed " + seed + "L\n" + + "Failed on <<<" + fuzzyHtml + ">>>"); + failures.add(ex); } }); } executor.shutdown(); executor.awaitTermination(runCount * 4, TimeUnit.SECONDS); - assertTrue("seed=" + seed, executor.isTerminated()); + assertTrue(executor.isTerminated(), "seed=" + seed); Throwable failure = failures.poll(); if (failure != null) { if (failure instanceof RuntimeException) { diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerTest.java index 003e52c8..881224fa 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerTest.java @@ -28,75 +28,77 @@ package org.owasp.html; -import junit.framework.TestCase; - import java.util.Arrays; import javax.annotation.Nullable; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -@SuppressWarnings("javadoc") -public class HtmlSanitizerTest extends TestCase { +class HtmlSanitizerTest { @Test - public static final void testEmpty() { + void testEmpty() { assertEquals("", sanitize("")); assertEquals("", sanitize(null)); } @Test - public static final void testSimpleText() { + void testSimpleText() { assertEquals("hello world", sanitize("hello world")); } @Test - public static final void testEntities1() { + void testEntities1() { assertEquals("&lt;hello world&gt;", sanitize("&lt;hello world&gt;")); } @Test - public static final void testEntities2() { + void testEntities2() { assertEquals("<b>hello <i>world</i></b>", sanitize("<b>hello <i>world</i></b>")); } @Test - public static final void testUnknownTagsRemoved() { + void testUnknownTagsRemoved() { assertEquals("<b>hello <i>world</i></b>", sanitize("<b>hello <bogus></bogus><i>world</i></b>")); } @Test - public static final void testUnsafeTagsRemoved() { + void testUnsafeTagsRemoved() { assertEquals("<b>hello <i>world</i></b>", sanitize("<b>hello <i>world</i>" + "<script src=foo.js></script></b>")); } @Test - public static final void testUnsafeAttributesRemoved() { + void testUnsafeAttributesRemoved() { assertEquals( "<b>hello <i>world</i></b>", sanitize("<b>hello <i onclick=\"takeOverWorld(this)\">world</i></b>")); } @Test - public static final void testCruftEscaped() { + void testCruftEscaped() { assertEquals("<b>hello <i>world&lt;</i></b> &amp; tomorrow the universe", sanitize( "<b>hello <i>world<</i></b> & tomorrow the universe")); } @Test - public static final void testTagCruftRemoved() { + void testTagCruftRemoved() { assertEquals("<b id=\"p-foo\">hello <i>world&lt;</i></b>", sanitize("<b id=\"foo\" / -->hello <i>world<</i></b>")); } @Test - public static final void testIdsAndClassesPrefixed() { + void testIdsAndClassesPrefixed() { assertEquals( "<b id=\"p-foo\" class=\"p-boo p-bar p-baz\">" + "hello <i>world&lt;</i></b>", @@ -105,26 +107,26 @@ public static final void testIdsAndClassesPrefixed() { } @Test - public static final void testSpecialCharsInAttributes() { + void testSpecialCharsInAttributes() { assertEquals( "<b title=\"a&lt;b &amp;&amp; c&gt;b\">bar</b>", sanitize("<b title=\"a<b && c>b\">bar</b>")); } @Test - public static final void testUnclosedTags() { + void testUnclosedTags() { assertEquals("<div id=\"p-foo\">Bar<br />Baz</div>", sanitize("<div id=\"foo\">Bar<br>Baz")); } @Test - public static final void testUnopenedTags() { + void testUnopenedTags() { assertEquals("Foo<b>Bar</b>Baz", sanitize("Foo<b></select>Bar</b></b>Baz</select>")); } @Test - public static final void testUnsafeEndTags() { + void testUnsafeEndTags() { assertEquals( "", sanitize( @@ -133,26 +135,26 @@ public static final void testUnsafeEndTags() { } @Test - public static final void testEmptyEndTags() { + void testEmptyEndTags() { assertEquals("<input />", sanitize("<input></input>")); } @Test - public static final void testOnLoadStripped() { + void testOnLoadStripped() { assertEquals( "<img />", sanitize("<img src=http://foo.com/bar ONLOAD=alert(1)>")); } @Test - public static final void testClosingTagParameters() { + void testClosingTagParameters() { assertEquals( "<p>Hello world</p>", sanitize("<p>Hello world</b style=\"width:expression(alert(1))\">")); } @Test - public static final void testOptionalEndTags() { + void testOptionalEndTags() { // Should not be // "<ol> <li>A</li> <li>B<li>C </li></li></ol>" // The difference is significant because in the first, the item contains no @@ -163,7 +165,7 @@ public static final void testOptionalEndTags() { } @Test - public static final void testFoldingOfHtmlAndBodyTags() { + void testFoldingOfHtmlAndBodyTags() { assertEquals( "<p>P 1</p>", sanitize("<html><head><title>Foo</title></head>" @@ -189,14 +191,14 @@ public static final void testFoldingOfHtmlAndBodyTags() { } @Test - public static final void testEmptyAndValuelessAttributes() { + void testEmptyAndValuelessAttributes() { assertEquals( "<input checked=\"checked\" type=\"checkbox\" id=\"\" class=\"\" />", sanitize("<input checked type=checkbox id=\"\" class=>")); } @Test - public static final void testSgmlShortTags() { + void testSgmlShortTags() { // We make no attempt to correctly handle SGML short tags since they are // not implemented consistently across browsers, and have been removed from // HTML 5. @@ -221,7 +223,7 @@ public static final void testSgmlShortTags() { } @Test - public static final void testNul() { + void testNul() { assertEquals( "<a title=" + "\"harmless SCRIPT&#61;javascript:alert(1) ignored&#61;ignored\">" @@ -233,7 +235,7 @@ public static final void testNul() { } @Test - public static final void testDigitsInAttrNames() { + void testDigitsInAttrNames() { // See bug 614 for details. assertEquals( "<div>Hello</div>", @@ -243,7 +245,7 @@ public static final void testDigitsInAttrNames() { } @Test - public static final void testSupplementaryCodepointEncoding() + void testSupplementaryCodepointEncoding() { // &#xd87e;&#xdc1a; is not appropriate. // &#x2f81a; is appropriate as is the unencoded form. @@ -253,10 +255,10 @@ public static final void testSupplementaryCodepointEncoding() } @Test - public static final void testDeeplyNestedTagsDoS() { + void testDeeplyNestedTagsDoS() { String sanitized = sanitize(stringRepeatedTimes("<div>", 20000)); int n = sanitized.length() / "<div></div>".length(); - assertTrue("" + n, 50 <= n && n <= 1000); + assertTrue(50 <= n && n <= 1000, "" + n); int middle = n * "<div>".length(); assertEquals(sanitized.substring(0, middle), stringRepeatedTimes("<div>", n)); @@ -265,7 +267,7 @@ public static final void testDeeplyNestedTagsDoS() { } @Test - public static final void testInnerHTMLIE8() { + void testInnerHTMLIE8() { // Apparently, in quirks mode, IE8 does a poor job producing innerHTML // values. Given // <div attr="``foo=bar"> @@ -285,7 +287,7 @@ public static final void testInnerHTMLIE8() { } @Test - public static final void testNabobsOfNegativism() { + void testNabobsOfNegativism() { // Treating <noscript> as raw-text gains us nothing security-wise // and we don't want to push tag content outside. assertEquals("<noscript></noscript>", @@ -306,7 +308,7 @@ public static final void testNabobsOfNegativism() { } @Test - public static final void testNULs() { + void testNULs() { assertEquals("<b>Hello, </b>", sanitize("<b>Hello, \u0000</b>")); assertEquals("<b>Hello, </b>", sanitize("<b>Hello, \u0000")); assertEquals("", sanitize("\u0000")); @@ -315,7 +317,7 @@ public static final void testNULs() { } @Test - public static final void testQMarkMeta() { + void testQMarkMeta() { assertEquals( "Hello, <b>World</b>!", sanitize( @@ -335,7 +337,7 @@ public static final void testQMarkMeta() { } @Test - public static final void testScriptInIframe() { + void testScriptInIframe() { assertEquals( "<iframe></iframe>", sanitize( @@ -345,7 +347,7 @@ public static final void testScriptInIframe() { } @Test - public static final void testBalancingOfEmptyTags() { + void testBalancingOfEmptyTags() { assertEquals( "<span style=\"color:rgb( 72 , 72 , 72 );font-family:&#39;helveticaneue&#39;\">" + " " @@ -361,14 +363,14 @@ public static final void testBalancingOfEmptyTags() { } @Test - public static final void testDuplicateAttributes() { + void testDuplicateAttributes() { assertEquals( sanitize("<br id=\"foo\">"), sanitize("<br id=foo id=bar>")); } @Test - public static final void testNbsps() { + void testNbsps() { String input = "test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bob"; @@ -381,19 +383,15 @@ public static final void testNbsps() { codeUnits[i] = got.charAt(i); } - assertTrue( - Arrays.toString(codeUnits), - Arrays.equals( - new int[] { - 116, 101, 115, 116, - 160, 160, 160, 160, 160, 160, 160, 160, - 98, 111, 98, - }, - codeUnits)); + assertArrayEquals(new int[]{ + 116, 101, 115, 116, + 160, 160, 160, 160, 160, 160, 160, 160, + 98, 111, 98, + }, codeUnits, Arrays.toString(codeUnits)); } @Test - public static final void testMacOSAndIOSQueryOfDeath() { + void testMacOSAndIOSQueryOfDeath() { // https://manishearth.github.io/blog/2018/02/15/picking-apart-the-crashing-ios-string/ String[][] tests = { { @@ -436,19 +434,19 @@ public static final void testMacOSAndIOSQueryOfDeath() { for (int i = 0, n = tests.length; i < n; ++i) { String[] test = tests[i]; - assertEquals(i + " : " + test[0], test[1], sanitize(test[0])); + assertEquals(test[1], sanitize(test[0]), i + " : " + test[0]); } } @Test - public static final void testIssue254SemicolonlessNamedCharactersInUrls() { + void testIssue254SemicolonlessNamedCharactersInUrls() { String input = "<a href=\"/test/?param1=valueOne&param2=valueTwo\">click me</a>"; String want = "<a href=\"/test/?param1&#61;valueOne&amp;param2&#61;valueTwo\">click me</a>"; assertEquals(want, sanitize(input)); } @Test - public static final void testStylingCornerCase() { + void testStylingCornerCase() { String input = "<a style=\\006-\\000038"; String want = ""; assertEquals(want, sanitize(input)); @@ -470,7 +468,7 @@ public static final void testStylingCornerCase() { * and only allowed content (CSS and allowed elements) remain. */ @Test - public static final void testCVE202566021_1() { + void testCVE202566021_1() { // Arrange: Attempt to inject a <div> inside <style>. Only 'style' and 'noscript' are allowed. String actualPayload = "<noscript><style>/* user content */.x { font-size: 12px; }<div id=\"evil\">XSS?</div></style></noscript>"; String expectedPayload = "<noscript><style>/* user content */.x { font-size: 12px; }</style></noscript>"; @@ -494,7 +492,7 @@ public static final void testCVE202566021_1() { * even when they appear inside allowed <style> tags. */ @Test - public static final void testCVE202566021_2() { + void testCVE202566021_2() { // Arrange: Attempt to inject a <script> inside <style>. Only 'style' and 'noscript' are allowed. String actualPayload = "<noscript><style>/* user content */.x { font-size: 12px; }<script>alert('XSS Attack!')</script></style></noscript>"; String expectedPayload = "<noscript><style>/* user content */.x { font-size: 12px; }</style></noscript>"; @@ -518,7 +516,7 @@ public static final void testCVE202566021_2() { * is retained by the sanitizer (since it is now in the policy). */ @Test - public static final void testCVE202566021_3() { + void testCVE202566021_3() { // Arrange: <div> is now allowed, so it should survive sanitization inside <style>. String actualPayload = "<noscript><style>/* user content */.x { font-size: 12px; }<div id=\"good\">ALLOWED?</div></style></noscript>"; String expectedPayload = "<noscript><style>/* user content */.x { font-size: 12px; }<div id=\"good\">ALLOWED?</div></style></noscript>"; @@ -542,7 +540,7 @@ public static final void testCVE202566021_3() { * does not allow the injected script. Sanitizer closes elements properly and only emits allowed tags. */ @Test - public static final void testCVE202566021_4() { + void testCVE202566021_4() { // Arrange: Try to break out of <style> and <noscript>, then add a script. Only style/noscript/p allowed. String actualPayload = "<noscript><style></noscript><script>alert(1)</script>"; String expectedPayload = "<noscript><style></noscript></style></noscript>"; @@ -566,7 +564,7 @@ public static final void testCVE202566021_4() { * and strips the injected script tag completely. */ @Test - public static final void testCVE202566021_5() { + void testCVE202566021_5() { // Arrange: Try to break out of <style> through <p>, then add a script. Only style/noscript/p allowed. String actualPayload = "<p><style></p><script>alert(1)</script>"; String expectedPayload = "<p><style></p></style></p>"; @@ -588,7 +586,7 @@ public static final void testCVE202566021_5() { * Test that <script> tags with space < script> are sanitized correctly. */ @Test - public static final void testCVE202566021_6() { + void testCVE202566021_6() { // Arrange: Attempt to inject a <script> inside <style>. Only 'style' and 'noscript' elements are allowed. String actualPayload = "<noscript><style>/* user content */.x { font-size: 12px; }< script>alert('XSS Attack!')</script></style></noscript>"; String expectedPayload = "<noscript><style>/* user content */.x { font-size: 12px; }</style></noscript>"; @@ -610,11 +608,7 @@ private static String sanitize(@Nullable String html) { StringBuilder sb = new StringBuilder(); HtmlStreamRenderer renderer = HtmlStreamRenderer.create( sb, - new Handler<String>() { - public void handle(String errorMessage) { - fail(errorMessage); - } - }); + Assertions::fail); HtmlSanitizer.Policy policy = new HtmlPolicyBuilder() // Allow these tags. @@ -629,14 +623,9 @@ public void handle(String errorMessage) { // name-space. .allowAttributes("id", "class") .matching( - new AttributePolicy() { - public String apply( - String elementName, String attributeName, String value) { - return value.replaceAll("(?:^|\\s)([a-zA-Z])", " p-$1") - .replaceAll("\\s+", " ") - .trim(); - } - }) + (elementName, attributeName, value) -> value.replaceAll("(?:^|\\s)([a-zA-Z])", " p-$1") + .replaceAll("\\s+", " ") + .trim()) .globally() .allowStyling() // Don't throw out useless <img> and <input> elements to ease debugging. @@ -648,7 +637,7 @@ public String apply( return sb.toString(); } - private static final String stringRepeatedTimes(String s, int n) { + private static String stringRepeatedTimes(String s, int n) { StringBuilder sb = new StringBuilder(s.length() * n); for (int nToAppend = n; --nToAppend >= 0;) { sb.append(s); diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlStreamRendererTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlStreamRendererTest.java index 949f68cd..7177b8dd 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlStreamRendererTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlStreamRendererTest.java @@ -29,53 +29,54 @@ package org.owasp.html; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import junit.framework.TestCase; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.owasp.shim.Java8Shim.j8; -@SuppressWarnings("javadoc") -public class HtmlStreamRendererTest extends TestCase { +class HtmlStreamRendererTest { - private final List<String> errors = new ArrayList<>(); + private final List<String> errors = new ArrayList<>(); private final StringBuilder rendered = new StringBuilder(); private final HtmlStreamRenderer renderer = HtmlStreamRenderer.create( - rendered, new Handler<String>() { - public void handle(String errorMessage) { - @SuppressWarnings({"hiding", "synthetic-access"}) - List<String> errors = HtmlStreamRendererTest.this.errors; - errors.add(errorMessage); - } + rendered, errorMessage -> { + @SuppressWarnings({"synthetic-access"}) + List<String> errors = HtmlStreamRendererTest.this.errors; + errors.add(errorMessage); }); - @Override - protected void setUp() throws Exception { - super.setUp(); + @BeforeEach + void setUp() { errors.clear(); rendered.setLength(0); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); - assertTrue(errors.toString(), errors.isEmpty()); // Catch any tests that don't check errors. + @AfterEach + void tearDown() { + assertTrue(errors.isEmpty(), errors.toString()); // Catch any tests that don't check errors. } - public final void testEmptyDocument() throws Exception { + @Test + void testEmptyDocument() { assertNormalized("", ""); } - public final void testElementNamesNormalized() throws Exception { + @Test + void testElementNamesNormalized() { assertNormalized("<br />", "<br>"); assertNormalized("<br />", "<BR>"); assertNormalized("<br />", "<Br />"); assertNormalized("<br />", "<br\n>"); } - public final void testAttributeNamesNormalized() throws Exception { + @Test + void testAttributeNamesNormalized() { assertNormalized("<input id=\"foo\" />", "<input id=foo>"); assertNormalized("<input id=\"foo\" />", "<input id=\"foo\">"); assertNormalized("<input id=\"foo\" />", "<input ID='foo'>"); @@ -83,23 +84,27 @@ public final void testAttributeNamesNormalized() throws Exception { assertNormalized("<input id=\"foo\" />", "<input\nid=foo'>"); } - public final void testAttributeValuesEscaped() throws Exception { + @Test + void testAttributeValuesEscaped() { assertNormalized("<div title=\"a&lt;b\"></div>", "<div title=a<b></div>"); } - public final void testRcdataEscaped() throws Exception { + @Test + void testRcdataEscaped() { assertNormalized( "<title>I &lt;3 PONIES, OMG!!!</title>", "<TITLE>I <3 PONIES, OMG!!!</TITLE>"); } - public final void testCdataNotEscaped() throws Exception { + @Test + void testCdataNotEscaped() { assertNormalized( "<script>I <3\n!!!PONIES, OMG</script>", "<script>I <3\n!!!PONIES, OMG</script>"); } - public final void testIllegalElementName() throws Exception { + @Test + void testIllegalElementName() { renderer.openDocument(); renderer.openTag(":svg", j8().listOf()); renderer.openTag("svg:", j8().listOf()); @@ -109,20 +114,20 @@ public final void testIllegalElementName() throws Exception { renderer.closeDocument(); String output = rendered.toString(); - assertFalse(output, output.contains("<")); + assertFalse(output.contains("<"), output); assertEquals( - Arrays.stream(new String[] { - "Invalid element name : :svg", - "Invalid element name : svg:", - "Invalid element name : -1", - "Invalid element name : svg::svg", - "Invalid element name : a@b"}).collect(Collectors.joining("\n")), - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", "Invalid element name : :svg", + "Invalid element name : svg:", + "Invalid element name : -1", + "Invalid element name : svg::svg", + "Invalid element name : a@b"), + String.join("\n", errors)); errors.clear(); } - public final void testIllegalAttributeName() throws Exception { + @Test + void testIllegalAttributeName() { renderer.openDocument(); renderer.openTag("div", j8().listOf(":svg", "x")); renderer.openTag("div", j8().listOf("svg:", "x")); @@ -132,20 +137,20 @@ public final void testIllegalAttributeName() throws Exception { renderer.closeDocument(); String output = rendered.toString(); - assertFalse(output, output.contains("=")); + assertFalse(output.contains("="), output); assertEquals( - Arrays.stream(new String[] { - "Invalid attr name : :svg", - "Invalid attr name : svg:", - "Invalid attr name : -1", - "Invalid attr name : svg::svg", - "Invalid attr name : a@b"}).collect(Collectors.joining("\n")), - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", "Invalid attr name : :svg", + "Invalid attr name : svg:", + "Invalid attr name : -1", + "Invalid attr name : svg::svg", + "Invalid attr name : a@b"), + String.join("\n", errors)); errors.clear(); } - public final void testCdataContainsEndTag1() throws Exception { + @Test + void testCdataContainsEndTag1() { renderer.openDocument(); renderer.openTag("script", j8().listOf("type", "text/javascript")); renderer.text("document.write('<SCRIPT>alert(42)</SCRIPT>')"); @@ -156,11 +161,12 @@ public final void testCdataContainsEndTag1() throws Exception { "<script type=\"text/javascript\"></script>", rendered.toString()); assertEquals( "Invalid CDATA text content : </SCRIPT>'", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testCdataContainsEndTag2() throws Exception { + @Test + void testCdataContainsEndTag2() { renderer.openDocument(); renderer.openTag("style", j8().listOf("type", "text/css")); renderer.text("/* </St"); @@ -173,11 +179,12 @@ public final void testCdataContainsEndTag2() throws Exception { "<style type=\"text/css\"></style>", rendered.toString()); assertEquals( "Invalid CDATA text content : </Style> *", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testRcdataContainsEndTag() throws Exception { + @Test + void testRcdataContainsEndTag() { renderer.openDocument(); renderer.openTag("textarea", j8().listOf()); renderer.text("<textarea></textarea>"); @@ -189,19 +196,21 @@ public final void testRcdataContainsEndTag() throws Exception { rendered.toString()); } - public final void testEndTagInsideScriptBodyInner() throws Exception { + @Test + void testEndTagInsideScriptBodyInner() { assertNormalized( "<script></script>&#39;)--&gt;", "<script><!--document.write('<SCRIPT>alert(42)</SCRIPT>')--></script>"); assertEquals( "Invalid CDATA text content : <SCRIPT>al", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } // Testcases from // www.w3.org/TR/html51/semantics-scripting.html#restrictions-for-contents-of-script-elements - public final void testHtml51SemanticsScriptingExample5Part1() throws Exception { + @Test + void testHtml51SemanticsScriptingExample5Part1() { String js = " var example = 'Consider this string: <!-- <script>';\n" + " console.log(example);\n"; @@ -216,11 +225,12 @@ public final void testHtml51SemanticsScriptingExample5Part1() throws Exception { rendered.toString()); assertEquals( "Invalid CDATA text content : <script>';", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testHtml51SemanticsScriptingExample5Part2() throws Exception { + @Test + void testHtml51SemanticsScriptingExample5Part2() { String js = "if (x<!--y) { ... }\n"; renderer.openDocument(); @@ -234,11 +244,12 @@ public final void testHtml51SemanticsScriptingExample5Part2() throws Exception { rendered.toString()); assertEquals( "Invalid CDATA text content : <!--y) { .", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testMoreUnbalancedHtmlCommentsInScripts() throws Exception { + @Test + void testMoreUnbalancedHtmlCommentsInScripts() { String js = "if (x-->y) { ... }\n"; renderer.openDocument(); @@ -253,11 +264,12 @@ public final void testMoreUnbalancedHtmlCommentsInScripts() throws Exception { rendered.toString()); assertEquals( "Invalid CDATA text content : -->y) { ..", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testShortHtmlCommentInScript() throws Exception { + @Test + void testShortHtmlCommentInScript() { String js = "// <!----> <!--->"; renderer.openDocument(); @@ -272,11 +284,12 @@ public final void testShortHtmlCommentInScript() throws Exception { rendered.toString()); assertEquals( "Invalid CDATA text content : <!--->", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testHtml51SemanticsScriptingExample5Part3() throws Exception { + @Test + void testHtml51SemanticsScriptingExample5Part3() { String js = "<!-- if ( player<script ) { ... } -->"; renderer.openDocument(); @@ -290,11 +303,12 @@ public final void testHtml51SemanticsScriptingExample5Part3() throws Exception { rendered.toString()); assertEquals( "Invalid CDATA text content : <script ) ", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testHtml51SemanticsScriptingExample5Part4() throws Exception { + @Test + void testHtml51SemanticsScriptingExample5Part4() { String js = "<!--\n" + "if (x < !--y) { ... }\n" + "if (!--y > x) { ... }\n" @@ -320,7 +334,8 @@ public final void testHtml51SemanticsScriptingExample5Part4() throws Exception { rendered.toString()); } - public final void testHtmlCommentInRcdata() throws Exception { + @Test + void testHtmlCommentInRcdata() { String str = "// <!----> <!---> <!--"; renderer.openDocument(); @@ -338,7 +353,8 @@ public final void testHtmlCommentInRcdata() throws Exception { rendered.toString()); } - public final void testTagInCdata() throws Exception { + @Test + void testTagInCdata() { renderer.openDocument(); renderer.openTag("script", j8().listOf()); renderer.text("alert('"); @@ -352,14 +368,14 @@ public final void testTagInCdata() throws Exception { assertEquals( "<script>alert('foo')</script>", rendered.toString()); assertEquals( - Arrays.stream(new String[] { - "Tag content cannot appear inside CDATA element : b", - "Tag content cannot appear inside CDATA element : b"}).collect(Collectors.joining("\n")), - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", "Tag content cannot appear inside CDATA element : b", + "Tag content cannot appear inside CDATA element : b"), + String.join("\n", errors)); errors.clear(); } - public final void testUnclosedEscapingTextSpan() throws Exception { + @Test + void testUnclosedEscapingTextSpan() { renderer.openDocument(); renderer.openTag("script", j8().listOf()); renderer.text("<!--alert('</script>')"); @@ -369,11 +385,12 @@ public final void testUnclosedEscapingTextSpan() throws Exception { assertEquals("<script></script>", rendered.toString()); assertEquals( "Invalid CDATA text content : </script>'", - errors.stream().collect(Collectors.joining("\n"))); + String.join("\n", errors)); errors.clear(); } - public final void testAlmostCompleteEndTag() throws Exception { + @Test + void testAlmostCompleteEndTag() { renderer.openDocument(); renderer.openTag("script", j8().listOf()); renderer.text("//</scrip"); @@ -383,7 +400,8 @@ public final void testAlmostCompleteEndTag() throws Exception { assertEquals("<script>//</scrip</script>", rendered.toString()); } - public final void testBalancedCommentInNoscript() throws Exception { + @Test + void testBalancedCommentInNoscript() { renderer.openDocument(); renderer.openTag("noscript", j8().listOf()); renderer.text("<!--<script>foo</script>-->"); @@ -395,7 +413,8 @@ public final void testBalancedCommentInNoscript() throws Exception { rendered.toString()); } - public final void testUnbalancedCommentInNoscript() throws Exception { + @Test + void testUnbalancedCommentInNoscript() { renderer.openDocument(); renderer.openTag("noscript", j8().listOf()); renderer.text("<!--<script>foo</script>--"); @@ -411,7 +430,8 @@ public final void testUnbalancedCommentInNoscript() throws Exception { rendered.toString()); } - public final void testSupplementaryCodepoints() throws Exception { + @Test + void testSupplementaryCodepoints() { renderer.openDocument(); renderer.text("\uD87E\uDC1A"); // Supplementary codepoint U+2F81A renderer.closeDocument(); @@ -422,7 +442,8 @@ public final void testSupplementaryCodepoints() throws Exception { // Test that policies that naively allow <xmp>, <listing>, or <plaintext> // on XHTML don't shoot themselves in the foot. - public final void testPreSubstitutes1() throws Exception { + @Test + void testPreSubstitutes1() { renderer.openDocument(); renderer.openTag("Xmp", j8().listOf()); renderer.text("<form>Hello, World</form>"); @@ -433,7 +454,8 @@ public final void testPreSubstitutes1() throws Exception { rendered.toString()); } - public final void testPreSubstitutes2() throws Exception { + @Test + void testPreSubstitutes2() { renderer.openDocument(); renderer.openTag("xmp", j8().listOf()); renderer.text("<form>Hello, World</form>"); @@ -444,7 +466,8 @@ public final void testPreSubstitutes2() throws Exception { rendered.toString()); } - public final void testPreSubstitutes3() throws Exception { + @Test + void testPreSubstitutes3() { renderer.openDocument(); renderer.openTag("LISTING", j8().listOf()); renderer.text("<form>Hello, World</form>"); @@ -455,7 +478,8 @@ public final void testPreSubstitutes3() throws Exception { rendered.toString()); } - public final void testPreSubstitutes4() throws Exception { + @Test + void testPreSubstitutes4() { renderer.openDocument(); renderer.openTag("plaintext", j8().listOf()); renderer.text("<form>Hello, World</form>"); @@ -465,8 +489,7 @@ public final void testPreSubstitutes4() throws Exception { rendered.toString()); } - private void assertNormalized(String golden, String htmlInput) - throws Exception { + private void assertNormalized(String golden, String htmlInput) { assertEquals(golden, normalize(htmlInput)); // Check that normalization is idempotent. @@ -476,7 +499,6 @@ private void assertNormalized(String golden, String htmlInput) } private String normalize(String htmlInput) { - @SuppressWarnings("hiding") final HtmlStreamRenderer renderer = this.renderer; // Use a permissive sanitizer to generate the events. HtmlSanitizer.sanitize(htmlInput, new HtmlSanitizer.Policy() { diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/IntVectorTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/IntVectorTest.java index 3c07a8bc..08adb3e8 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/IntVectorTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/IntVectorTest.java @@ -3,15 +3,15 @@ import java.util.LinkedList; import java.util.Random; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import junit.framework.TestCase; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -@SuppressWarnings("javadoc") -public final class IntVectorTest extends TestCase { +class IntVectorTest { @Test - public static void testIntVector() { + void testIntVector() { Random r = new Random(0xA03B79241106C82FL); IntVector iv = new IntVector(); @@ -51,7 +51,7 @@ public static void testIntVector() { } @Test - public static void testLastIndexOf() { + void testLastIndexOf() { IntVector v = new IntVector(); for (int i = 0; i < 30; ++i) { v.add(i); diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/PolicyFactoryTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/PolicyFactoryTest.java index a497668f..98db75e1 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/PolicyFactoryTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/PolicyFactoryTest.java @@ -32,17 +32,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import junit.framework.TestCase; +import static org.junit.jupiter.api.Assertions.assertEquals; -@SuppressWarnings({ "javadoc" }) -public final class PolicyFactoryTest extends TestCase { +class PolicyFactoryTest { @Test - public static void testAnd() { + void testAnd() { // Filters srcset to only contain URLs with the substring "foo" PolicyFactory f = new HtmlPolicyBuilder() .allowElements("img") @@ -141,21 +139,11 @@ public void discardedAttributes( }; - Handler<IOException> ioHandler = new Handler<IOException>() { - - public void handle(IOException x) { - log.append("Handled IOException " + x.getMessage() + "\n"); - } - - }; + Handler<IOException> ioHandler = x -> log.append("Handled IOException " + x.getMessage() + "\n"); // Should not be called. - Handler<String> badHtmlHandler = new Handler<String>() { - - public void handle(String x) { - throw new AssertionError(x); - } - + Handler<String> badHtmlHandler = x -> { + throw new AssertionError(x); }; // Wraps out to throw when a '!' is written to test the ioHandler. @@ -193,10 +181,9 @@ public Appendable append(char c) throws IOException { HtmlSanitizer.sanitize(html, policy); assertEquals( - "i:" + i, - - "Out:\n" + expectedOutput + "\n\nLog:\n" + expectedLog, - "Out:\n" + out + "\n\nLog:\n" + log); + "Out:\n" + expectedOutput + "\n\nLog:\n" + expectedLog, + "Out:\n" + out + "\n\nLog:\n" + log, + "i:" + i); } } @@ -204,7 +191,7 @@ public Appendable append(char c) throws IOException { // beforePolicy : X // afterPolicy : X @Test - public void testHtmlTagSkipPolicy1() { + void testHtmlTagSkipPolicy1() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .toFactory(); @@ -225,7 +212,7 @@ public void testHtmlTagSkipPolicy1() { // beforePolicy : X // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy2() { + void testHtmlTagSkipPolicy2() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .toFactory(); @@ -247,7 +234,7 @@ public void testHtmlTagSkipPolicy2() { // beforePolicy : X // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy3() { + void testHtmlTagSkipPolicy3() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .toFactory(); @@ -269,7 +256,7 @@ public void testHtmlTagSkipPolicy3() { // beforePolicy : allow // afterPolicy : X @Test - public void testHtmlTagSkipPolicy4() { + void testHtmlTagSkipPolicy4() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .allowWithoutAttributes("span") @@ -291,7 +278,7 @@ public void testHtmlTagSkipPolicy4() { // beforePolicy : allow // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy5() { + void testHtmlTagSkipPolicy5() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .allowWithoutAttributes("span") @@ -314,7 +301,7 @@ public void testHtmlTagSkipPolicy5() { // beforePolicy : allow // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy6() { + void testHtmlTagSkipPolicy6() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .allowWithoutAttributes("span") @@ -337,7 +324,7 @@ public void testHtmlTagSkipPolicy6() { // beforePolicy : disallow // afterPolicy : X @Test - public void testHtmlTagSkipPolicy7() { + void testHtmlTagSkipPolicy7() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .disallowWithoutAttributes("span") @@ -359,7 +346,7 @@ public void testHtmlTagSkipPolicy7() { // beforePolicy : disallow // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy8() { + void testHtmlTagSkipPolicy8() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .disallowWithoutAttributes("span") @@ -382,7 +369,7 @@ public void testHtmlTagSkipPolicy8() { // beforePolicy : disallow // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy9() { + void testHtmlTagSkipPolicy9() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("span") .disallowWithoutAttributes("span") @@ -405,7 +392,7 @@ public void testHtmlTagSkipPolicy9() { // beforePolicy : X // afterPolicy : X @Test - public void testHtmlTagSkipPolicy10() { + void testHtmlTagSkipPolicy10() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .toFactory(); @@ -426,7 +413,7 @@ public void testHtmlTagSkipPolicy10() { // beforePolicy : X // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy11() { + void testHtmlTagSkipPolicy11() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .toFactory(); @@ -448,7 +435,7 @@ public void testHtmlTagSkipPolicy11() { // beforePolicy : X // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy12() { + void testHtmlTagSkipPolicy12() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .toFactory(); @@ -470,7 +457,7 @@ public void testHtmlTagSkipPolicy12() { // beforePolicy : allow // afterPolicy : X @Test - public void testHtmlTagSkipPolicy13() { + void testHtmlTagSkipPolicy13() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .allowWithoutAttributes("p") @@ -492,7 +479,7 @@ public void testHtmlTagSkipPolicy13() { // beforePolicy : allow // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy14() { + void testHtmlTagSkipPolicy14() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .allowWithoutAttributes("p") @@ -515,7 +502,7 @@ public void testHtmlTagSkipPolicy14() { // beforePolicy : allow // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy15() { + void testHtmlTagSkipPolicy15() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .allowWithoutAttributes("p") @@ -538,7 +525,7 @@ public void testHtmlTagSkipPolicy15() { // beforePolicy : disallow // afterPolicy : X @Test - public void testHtmlTagSkipPolicy16() { + void testHtmlTagSkipPolicy16() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .disallowWithoutAttributes("p") @@ -560,7 +547,7 @@ public void testHtmlTagSkipPolicy16() { // beforePolicy : disallow // afterPolicy : allow @Test - public void testHtmlTagSkipPolicy17() { + void testHtmlTagSkipPolicy17() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .disallowWithoutAttributes("p") @@ -583,7 +570,7 @@ public void testHtmlTagSkipPolicy17() { // beforePolicy : disallow // afterPolicy : disallow @Test - public void testHtmlTagSkipPolicy18() { + void testHtmlTagSkipPolicy18() { PolicyFactory beforePolicy = new HtmlPolicyBuilder() .allowElements("p") .disallowWithoutAttributes("p") @@ -618,7 +605,7 @@ public String apply( outParts.add(part); } } - return outParts.stream().collect(Collectors.joining(" , ")); + return String.join(" , ", outParts); } } } \ No newline at end of file diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/SanitizersTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/SanitizersTest.java index 5ad6f501..6c235b33 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/SanitizersTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/SanitizersTest.java @@ -28,8 +28,6 @@ package org.owasp.html; -import org.junit.Test; - import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; @@ -38,13 +36,14 @@ import java.util.List; import java.util.NoSuchElementException; -import junit.framework.TestCase; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; -@SuppressWarnings("javadoc") -public class SanitizersTest extends TestCase { +class SanitizersTest { @Test - public static final void testFormatting() { + void testFormatting() { assertEquals("", Sanitizers.FORMATTING.sanitize(null)); assertEquals("", Sanitizers.FORMATTING.sanitize("")); assertEquals( @@ -60,7 +59,7 @@ public static final void testFormatting() { } @Test - public static final void testBlockElements() { + void testBlockElements() { assertEquals("", Sanitizers.BLOCKS.sanitize(null)); assertEquals( "Hello, World!", @@ -75,7 +74,7 @@ public static final void testBlockElements() { } @Test - public static final void testBlockAndFormattingElements() { + void testBlockAndFormattingElements() { PolicyFactory s = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING); PolicyFactory r1 = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING) .and(Sanitizers.BLOCKS); @@ -92,7 +91,7 @@ public static final void testBlockAndFormattingElements() { } @Test - public static final void testStylesAndFormatting() { + void testStylesAndFormatting() { PolicyFactory sanitizer = Sanitizers.FORMATTING .and(Sanitizers.BLOCKS).and(Sanitizers.STYLES).and(Sanitizers.LINKS); String input = "<span style=\"font-weight:bold;" @@ -104,7 +103,7 @@ public static final void testStylesAndFormatting() { } @Test - public static final void testAndIntersects() { + void testAndIntersects() { PolicyFactory restrictedLink = new HtmlPolicyBuilder() .allowElements("a") .allowUrlProtocols("https") @@ -117,28 +116,28 @@ public static final void testAndIntersects() { PolicyFactory and1 = restrictedLink.and(inline); PolicyFactory and2 = inline.and(restrictedLink); assertEquals( - "https-only links", "Hello, World<a title=\"!\" href=\"https://foo.com/#!\">!</a>", - restrictedLink.sanitize(inputHtml)); + restrictedLink.sanitize(inputHtml), + "https-only links"); assertEquals( - "inline els", "<a href=\"http://foo.com/\" rel=\"nofollow\">Hello, <b>World</b></a>" + "<a href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", - inline.sanitize(inputHtml)); + inline.sanitize(inputHtml), + "inline els"); assertEquals( - "https-only links and inline els", "Hello, <b>World</b>" + "<a title=\"!\" href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", - and1.sanitize(inputHtml)); + and1.sanitize(inputHtml), + "https-only links and inline els"); assertEquals( - "inline els and https-only links", "Hello, <b>World</b>" + "<a title=\"!\" href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", - and2.sanitize(inputHtml)); + and2.sanitize(inputHtml), + "inline els and https-only links"); } @Test - public static final void testImages() { + void testImages() { PolicyFactory s = Sanitizers.IMAGES; assertEquals( "foo", s.sanitize("<a href=\"javascript:alert(1337)\">foo</a>")); @@ -159,7 +158,7 @@ public static final void testImages() { } @Test - public static final void testIntegerAttributePolicy() { + void testIntegerAttributePolicy() { PolicyFactory s = Sanitizers.IMAGES; assertEquals( "<img src=\"x.png\" alt=\"y\" height=\"0\" border=\"0\" />", @@ -211,7 +210,7 @@ public static final void testIntegerAttributePolicy() { } @Test - public static final void testLinks() { + void testLinks() { PolicyFactory s = Sanitizers.LINKS; assertEquals( "<a href=\"foo.html\" rel=\"nofollow\">Link text</a>", @@ -253,7 +252,7 @@ public static final void testLinks() { } @Test - public static final void testExplicitlyAllowedProtocolsAreCaseInsensitive() { + void testExplicitlyAllowedProtocolsAreCaseInsensitive() { // Issue 24. PolicyFactory s = new HtmlPolicyBuilder() .allowElements("a") @@ -275,7 +274,7 @@ public static final void testExplicitlyAllowedProtocolsAreCaseInsensitive() { } @Test - public static final void testIssue9StylesInTables() { + void testIssue9StylesInTables() { String input = "" + "<table style=\"color: rgb(0, 0, 0);" + " font-family: Arial, Geneva, sans-serif;\">" @@ -323,7 +322,7 @@ public static final void testIssue9StylesInTables() { } @Test - public static final void testSkipIfEmptyUnionsProperly() { + void testSkipIfEmptyUnionsProperly() { // Issue 23 PolicyFactory extras = new HtmlPolicyBuilder() .allowWithoutAttributes("span", "div") @@ -347,18 +346,18 @@ public static final void testSkipIfEmptyUnionsProperly() { } @Test - public static final void testIssue30() { + void testIssue30() { String test = "&nbsp;&gt;"; PolicyFactory policy = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS) .and(Sanitizers.STYLES); String safeHTML = policy.sanitize(test); - assertEquals(test, "\u00a0&gt;", safeHTML); + assertEquals("\u00a0&gt;", safeHTML, test); } @Test - public static final void testScriptInTable() { + void testScriptInTable() { String input = "<table>Hallo\r\n<script>SCRIPT</script>\nEnde\n\r"; PolicyFactory pf = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING) .and(Sanitizers.LINKS) @@ -369,7 +368,7 @@ public static final void testScriptInTable() { } @Test - public static final void testAndOrdering() { + void testAndOrdering() { String input = "" + "xss<a href=\"http://www.google.de\" style=\"color:red\"" + " onmouseover=alert(1) onmousemove=\"alert(2)\" onclick=alert(3)>" @@ -393,12 +392,12 @@ public static final void testAndOrdering() { policyFactory = policyFactory.and(p); } String got = policyFactory.sanitize(input); - assertEquals(permutation.toString(), want, got); + assertEquals(want, got, permutation.toString()); } } @Test - public static final void testAngularBindingsInSanitizedCode() { + void testAngularBindingsInSanitizedCode() { PolicyFactory s = new HtmlPolicyBuilder() .allowElements("a", "b", "title") .allowAttributes("href").onElements("a") @@ -436,7 +435,8 @@ public static final void testAngularBindingsInSanitizedCode() { assertEquals(safe, sanitized); } - @Test public static final void testIssue46() { + @Test + void testIssue46() { PolicyFactory s = new HtmlPolicyBuilder() .allowWithoutAttributes("span") .allowElements("span") @@ -452,7 +452,7 @@ public static final void testAngularBindingsInSanitizedCode() { } @Test - public static final void testSpacesAroundURLAttributeValues() { + void testSpacesAroundURLAttributeValues() { PolicyFactory s = new HtmlPolicyBuilder() .allowStandardUrlProtocols() .allowElements("a") @@ -468,7 +468,7 @@ public static final void testSpacesAroundURLAttributeValues() { } @Test - public static final void testStyleTagInTable() { + void testStyleTagInTable() { String input = "" + "<table>" + "<style></style>" @@ -487,7 +487,7 @@ public static final void testStyleTagInTable() { } @Test - public static final void testStyleTagsInAllTheWrongPlaces() { + void testStyleTagsInAllTheWrongPlaces() { String input = "" + "<select><option><style><script>alert(1)</script></style></option></select>" + "<svg><style>.r { color: red }</style></svg>" @@ -510,7 +510,7 @@ public static final void testStyleTagsInAllTheWrongPlaces() { } @Test - public static final void testSelectIsOdd() { + void testSelectIsOdd() { // Special text modes interact badly with select and option String input = "<select><option><xmp><script>alert(1)</script></xmp></option></select>"; PolicyFactory pf = new HtmlPolicyBuilder() @@ -527,7 +527,7 @@ public static final void testSelectIsOdd() { } @Test - public static final void testOptionAllowsText() { + void testOptionAllowsText() { String input = "<select><option><pre>code goes here</pre></option></select>"; PolicyFactory pf = new HtmlPolicyBuilder() .allowElements("option", "select", "pre") @@ -543,7 +543,7 @@ public static final void testOptionAllowsText() { } @Test - public static final void testStyleGlobally() { + void testStyleGlobally() { PolicyFactory policyBuilder = new HtmlPolicyBuilder() .allowAttributes("style").globally() .allowElements("a", "label", "h1", "h2", "h3", "h4", "h5", "h6") @@ -572,14 +572,13 @@ private static class Permutations<T> implements Iterable<List<T>> { /** Permutation size. */ final int k; - Permutations(@SuppressWarnings("unchecked") T... elements) { + Permutations(T... elements) { this(elements.length, elements); } - Permutations(int k, @SuppressWarnings("unchecked") T... elements) { + Permutations(int k, T... elements) { this.k = k; - List<T> builder = new ArrayList<>(); - Arrays.stream(elements).forEach(builder::add); + List<T> builder = new ArrayList<>(Arrays.asList(elements)); this.elements = Collections.unmodifiableList(builder); } diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StringsTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StringsTest.java index 80710807..23e9fae3 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StringsTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StringsTest.java @@ -1,14 +1,13 @@ package org.owasp.html; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import junit.framework.TestCase; +import static org.junit.jupiter.api.Assertions.assertEquals; -@SuppressWarnings({ "javadoc" }) -public final class StringsTest extends TestCase { +class StringsTest { @Test - public static void testValidFloatingPointNumber() { + void testValidFloatingPointNumber() { assertEquals( -1, Strings.skipValidFloatingPointNumber("", 0)); diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StylingPolicyTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StylingPolicyTest.java index f9e5e4b2..b1f3d8ec 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StylingPolicyTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/StylingPolicyTest.java @@ -28,18 +28,16 @@ package org.owasp.html; -import java.util.function.Function; - import javax.annotation.Nullable; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; -import junit.framework.TestCase; +class StylingPolicyTest { -@SuppressWarnings("javadoc") -public class StylingPolicyTest extends TestCase { @Test - public static final void testNothingToOutput() { + void testNothingToOutput() { assertSanitizedCss(null, ""); assertSanitizedCss(null, "/** no CSS here */"); assertSanitizedCss(null, "/* props: disabled; font-weight: bold */"); @@ -49,7 +47,7 @@ public static final void testNothingToOutput() { } @Test - public static final void testColors() { + void testColors() { assertSanitizedCss("color:red", "color: red"); assertSanitizedCss("background-color:#f00", "background-color: #f00"); assertSanitizedCss("background:#f00", "background: #f00"); @@ -76,7 +74,7 @@ public static final void testColors() { } @Test - public static final void testFontWeight() { + void testFontWeight() { assertSanitizedCss( "font-weight:bold", "font-weight: bold"); assertSanitizedCss( @@ -93,7 +91,7 @@ public static final void testFontWeight() { } @Test - public static final void testFontStyle() { + void testFontStyle() { assertSanitizedCss( "font-style:italic", "font-style: Italic"); assertSanitizedCss( @@ -105,7 +103,7 @@ public static final void testFontStyle() { } @Test - public static final void testFontFace() { + void testFontFace() { assertSanitizedCss( "font:'arial' , 'helvetica'", "font: Arial, Helvetica"); assertSanitizedCss( @@ -135,7 +133,7 @@ public static final void testFontFace() { } @Test - public static final void testFont() { + void testFont() { assertSanitizedCss( "font:'arial' 12pt bold oblique", "font: Arial 12pt bold oblique"); @@ -159,7 +157,7 @@ public static final void testFont() { } @Test - public static final void testBidiAndAlignmentAttributes() { + void testBidiAndAlignmentAttributes() { assertSanitizedCss( "text-align:left;unicode-bidi:embed;direction:ltr", "Text-align: left; Unicode-bidi: Embed; Direction: LTR;"); @@ -173,7 +171,7 @@ public static final void testBidiAndAlignmentAttributes() { } @Test - public static final void testTextDecoration() { + void testTextDecoration() { assertSanitizedCss( "text-decoration:underline", "Text-Decoration: Underline"); @@ -189,7 +187,7 @@ public static final void testTextDecoration() { } @Test - public static final void testBoxProperties() { + void testBoxProperties() { // http://www.w3.org/TR/CSS2/box.html assertSanitizedCss("height:0", "height:0"); assertSanitizedCss("width:0", "width:0"); @@ -220,7 +218,7 @@ public static final void testBoxProperties() { } @Test - public static final void testLongUrls() { + void testLongUrls() { // Test that a long URL does not blow out the stack or consume quadratic // amounts of processor as when the CSS lexer was implemented as a bunch of // regular expressions. @@ -301,7 +299,7 @@ public static final void testLongUrls() { } @Test - public static final void testUrls() { + void testUrls() { assertSanitizedCss( "background-image:url('foo.gif#sanitized')", "background-image: \"foo.gif\""); @@ -323,7 +321,7 @@ public static final void testUrls() { } @Test - public static final void testImportant() { + void testImportant() { assertSanitizedCss( "color:blue !important", "color:blue !important"); @@ -336,7 +334,7 @@ public static final void testImportant() { } @Test - public static final void testCdoCdc() { + void testCdoCdc() { // No <!-- or --> in output. assertSanitizedCss("font-family:'a--' 'b'", "font-family: a--\\>b"); assertSanitizedCss("font-family:'a' '--b'", "font-family: a<\\!--b"); @@ -348,16 +346,14 @@ private static void assertSanitizedCss( @Nullable String expectedCss, String css) { StylingPolicy stylingPolicy = new StylingPolicy( CssSchema.DEFAULT, - new Function<String, String>() { - public String apply(String url) { - String safeUrl = - StandardUrlAttributePolicy.INSTANCE.apply("img", "src", url); - if (safeUrl != null) { - return safeUrl + "#sanitized"; - } - return null; - } - }); + url -> { + String safeUrl = + StandardUrlAttributePolicy.INSTANCE.apply("img", "src", url); + if (safeUrl != null) { + return safeUrl + "#sanitized"; + } + return null; + }); assertEquals(expectedCss, stylingPolicy.sanitizeCssProperties(css)); } } diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java index 53c05bc1..360cec5b 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java @@ -28,38 +28,35 @@ package org.owasp.html; -import static org.owasp.html.TagBalancingHtmlStreamEventReceiver - .isInterElementWhitespace; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.owasp.html.TagBalancingHtmlStreamEventReceiver.isInterElementWhitespace; import java.util.List; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; -import junit.framework.TestCase; import static org.owasp.shim.Java8Shim.j8; -@SuppressWarnings("javadoc") -public class TagBalancingHtmlStreamRendererTest extends TestCase { +class TagBalancingHtmlStreamRendererTest { - StringBuilder htmlOutputBuffer; - TagBalancingHtmlStreamEventReceiver balancer; + private StringBuilder htmlOutputBuffer; + private TagBalancingHtmlStreamEventReceiver balancer; - @Before @Override public void setUp() throws Exception { - super.setUp(); + @BeforeEach + void setUp() { htmlOutputBuffer = new StringBuilder(); balancer = new TagBalancingHtmlStreamEventReceiver( - HtmlStreamRenderer.create(htmlOutputBuffer, new Handler<String>() { - public void handle(String x) { - fail("An unexpected error was raised during the testcase"); - } - })); + HtmlStreamRenderer.create(htmlOutputBuffer, x -> fail("An unexpected error was raised during the testcase"))); } @Test - public final void testTagBalancing() { + void testTagBalancing() { balancer.openDocument(); balancer.openTag("html", j8().listOf()); balancer.openTag("head", j8().listOf()); @@ -84,7 +81,7 @@ public final void testTagBalancing() { } @Test - public final void testTagSoupIronedOut() { + void testTagSoupIronedOut() { balancer.openDocument(); balancer.openTag("i", j8().listOf()); balancer.text("x"); @@ -100,7 +97,7 @@ public final void testTagSoupIronedOut() { } @Test - public final void testListInListDirectly() { + void testListInListDirectly() { balancer.openDocument(); balancer.openTag("ul", j8().listOf()); balancer.openTag("li", j8().listOf()); @@ -120,7 +117,7 @@ public final void testListInListDirectly() { } @Test - public final void testTextContent() { + void testTextContent() { balancer.openDocument(); balancer.openTag("title", j8().listOf()); balancer.text("Hello, World!"); @@ -169,7 +166,7 @@ public final void testTextContent() { } @Test - public final void testMismatchedHeaders() { + void testMismatchedHeaders() { balancer.openDocument(); balancer.openTag("H1", j8().listOf()); balancer.text("header"); @@ -200,7 +197,7 @@ public final void testMismatchedHeaders() { } @Test - public final void testListNesting() { + void testListNesting() { balancer.openDocument(); balancer.openTag("ul", j8().listOf()); balancer.openTag("li", j8().listOf()); @@ -224,7 +221,7 @@ public final void testListNesting() { } @Test - public final void testTableNesting() { + void testTableNesting() { balancer.openDocument(); balancer.openTag("table", j8().listOf()); balancer.openTag("tbody", j8().listOf()); @@ -251,7 +248,7 @@ public final void testTableNesting() { } @Test - public final void testNestingLimits() { + void testNestingLimits() { // Some browsers can be DoSed by deeply nested structures. // See Issue 3, "Deeply nested elements crash FF 8, Chrome 11" // @ https://github.com/OWASP/java-html-sanitizer/issues/3 @@ -271,7 +268,7 @@ public final void testNestingLimits() { } @Test - public final void testTablesGuarded() { + void testTablesGuarded() { // Derived from issue 12. balancer.openDocument(); balancer.openTag("html", j8().listOf()); @@ -331,7 +328,7 @@ public final void testTablesGuarded() { } @Test - public final void testIsInterElementWhitespace() { + void testIsInterElementWhitespace() { assertFalse(isInterElementWhitespace("foo")); assertTrue(isInterElementWhitespace("")); assertTrue(isInterElementWhitespace(" ")); @@ -348,7 +345,7 @@ public final void testIsInterElementWhitespace() { } @Test - public final void testAnchorTransparentToBlock() { + void testAnchorTransparentToBlock() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("div", j8().listOf()); @@ -367,7 +364,7 @@ public final void testAnchorTransparentToBlock() { @Test - public final void testAnchorTransparentToSpans() { + void testAnchorTransparentToSpans() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("span", j8().listOf()); @@ -386,7 +383,7 @@ public final void testAnchorTransparentToSpans() { @Test - public final void testAnchorWithInlineInBlock() { + void testAnchorWithInlineInBlock() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("div", j8().listOf()); @@ -404,7 +401,7 @@ public final void testAnchorWithInlineInBlock() { } @Test - public final void testDirectlyNestedAnchor() { + void testDirectlyNestedAnchor() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("span", j8().listOf()); @@ -423,7 +420,7 @@ public final void testDirectlyNestedAnchor() { @Test - public final void testAnchorClosedWhenBlockInInline() { + void testAnchorClosedWhenBlockInInline() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("span", j8().listOf()); @@ -445,8 +442,8 @@ public final void testAnchorClosedWhenBlockInInline() { // TODO: Double check this test and handle nested anchors properly. @Test - @Ignore - public final void failingtestAnchorInAnchorIndirectly() { + @Disabled + void failingtestAnchorInAnchorIndirectly() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("div", j8().listOf()); @@ -466,7 +463,7 @@ public final void failingtestAnchorInAnchorIndirectly() { } @Test - public final void testInteractiveInAnchorIndirectly() { + void testInteractiveInAnchorIndirectly() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("div", j8().listOf()); @@ -484,7 +481,7 @@ public final void testInteractiveInAnchorIndirectly() { } @Test - public final void testAnchorWithBlockAtTopLevel() { + void testAnchorWithBlockAtTopLevel() { List<String> hrefOnly = j8().listOf("href", ""); balancer.openDocument(); balancer.openTag("a", hrefOnly); @@ -499,7 +496,7 @@ public final void testAnchorWithBlockAtTopLevel() { } @Test - public final void testResumedElementsAllowedWhereResumed() { + void testResumedElementsAllowedWhereResumed() { balancer.openDocument(); balancer.openTag("a", j8().listOf()); balancer.openTag("b", j8().listOf()); @@ -518,7 +515,7 @@ public final void testResumedElementsAllowedWhereResumed() { } @Test - public final void testMenuItemNesting() { + void testMenuItemNesting() { // issue 96 balancer.openDocument(); balancer.openTag("div", j8().listOf()); diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/UrlTextExampleTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/UrlTextExampleTest.java index 00a10a6c..1f733140 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/UrlTextExampleTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/UrlTextExampleTest.java @@ -30,16 +30,15 @@ import java.io.IOException; -import junit.framework.TestCase; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.owasp.html.examples.UrlTextExample; -@SuppressWarnings("javadoc") -public final class UrlTextExampleTest extends TestCase { +import static org.junit.jupiter.api.Assertions.assertEquals; + +class UrlTextExampleTest { @Test - public static void testExample() throws IOException { + void testExample() throws IOException { StringBuilder out = new StringBuilder(); UrlTextExample.run( out, diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/VerboseTestRunner.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/VerboseTestRunner.java deleted file mode 100644 index a8d4841b..00000000 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/VerboseTestRunner.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2013, Mike Samuel -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// Neither the name of the OWASP nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -package org.owasp.html; - -import java.io.PrintStream; - -import junit.framework.Test; -import junit.framework.TestResult; -import junit.textui.ResultPrinter; -import junit.textui.TestRunner; - -/** - * A test runner that dumps the names of tests as they start and finish to - * make debugging hanging tests easier. - */ -public class VerboseTestRunner extends TestRunner { - final PrintStream out; - - /** */ - public VerboseTestRunner() { - out = System.out; - setPrinter(new VerboseResultPrinter(out)); - } - - private final class VerboseResultPrinter extends ResultPrinter { - - VerboseResultPrinter(PrintStream out) { - super(out); - } - - @Override - public void startTest(Test test) { - out.println("Started " + test); - out.flush(); - super.startTest(test); - } - - @Override - public void endTest(Test test) { - super.endTest(test); - out.println("ended " + test); - out.flush(); - } - } - - public static void main(String[] argv) { - VerboseTestRunner runner = new VerboseTestRunner(); - try { - TestResult result = runner.start(argv); - if (!result.wasSuccessful()) { - System.exit(FAILURE_EXIT); - } - System.exit(SUCCESS_EXIT); - } catch (Exception ex) { - ex.printStackTrace(); - System.exit(EXCEPTION_EXIT); - } - } -} diff --git a/pom.xml b/pom.xml index 6d9896d4..206364e3 100644 --- a/pom.xml +++ b/pom.xml @@ -293,9 +293,10 @@ application while protecting against XSS. <scope>provided</scope> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.13.1</version> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <!-- 6.x requires Java 17 --> + <version>5.13.4</version> <scope>test</scope> </dependency> </dependencies> From b55ae17321e49875bcf2ff4c0857f2bf19ef2bab Mon Sep 17 00:00:00 2001 From: strangelookingnerd <49242855+strangelookingnerd@users.noreply.github.com> Date: Fri, 16 Jan 2026 14:28:58 +0100 Subject: [PATCH 2/2] Migrate tests to JUnit Jupiter * Migrate annotations and imports * Migrate assertions * Remove public visibility for test classes and methods * Minor code cleanup --- .../src/test/java/org/owasp/html/OptgroupBugTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/OptgroupBugTest.java b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/OptgroupBugTest.java index 5e99c0ec..dd296478 100644 --- a/owasp-java-html-sanitizer/src/test/java/org/owasp/html/OptgroupBugTest.java +++ b/owasp-java-html-sanitizer/src/test/java/org/owasp/html/OptgroupBugTest.java @@ -1,9 +1,10 @@ package org.owasp.html; -import org.junit.Test; -import static org.junit.Assert.assertEquals; +import org.junit.jupiter.api.Test; -public class OptgroupBugTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OptgroupBugTest { /** * Test that optgroup elements inside select are not corrupted with extra select tags. @@ -12,7 +13,7 @@ public class OptgroupBugTest { * After fix: <select><optgroup><option></option></optgroup></select> */ @Test - public void testOptgroupInsideSelectDoesNotAddExtraSelectTags() { + void testOptgroupInsideSelectDoesNotAddExtraSelectTags() { PolicyFactory factory = new HtmlPolicyBuilder() .allowElements("select", "optgroup", "option") .allowAttributes("label").globally()