From 93a7cf5a2395cb9857a86e8c1ead5241b4afd6af Mon Sep 17 00:00:00 2001 From: Claudio Weiler Date: Fri, 2 Sep 2022 17:53:33 -0300 Subject: [PATCH] Remove Guava dependency and update to Java 9 --- parent/pom.xml | 16 +- pom.xml | 9 +- .../java/org/owasp/html/AttributePolicy.java | 9 +- src/main/java/org/owasp/html/CssSchema.java | 298 +++++++++--------- src/main/java/org/owasp/html/CssTokens.java | 59 ++-- .../html/ElementAndAttributePolicies.java | 18 +- ...ndAttributePolicyBasedSanitizerPolicy.java | 25 +- .../java/org/owasp/html/ElementPolicy.java | 15 +- .../FilterUrlByProtocolAttributePolicy.java | 11 +- .../org/owasp/html/HtmlElementTables.java | 52 +-- .../java/org/owasp/html/HtmlEntities.java | 7 +- src/main/java/org/owasp/html/HtmlLexer.java | 10 +- .../org/owasp/html/HtmlPolicyBuilder.java | 163 +++++----- .../java/org/owasp/html/HtmlSanitizer.java | 4 +- .../org/owasp/html/HtmlStreamRenderer.java | 8 +- .../org/owasp/html/HtmlTextEscapingMode.java | 61 ++-- src/main/java/org/owasp/html/IntVector.java | 10 +- src/main/java/org/owasp/html/Joinable.java | 20 +- .../org/owasp/html/JoinedAttributePolicy.java | 11 +- .../java/org/owasp/html/PolicyFactory.java | 46 +-- .../java/org/owasp/html/StylingPolicy.java | 15 +- .../TagBalancingHtmlStreamEventReceiver.java | 12 +- .../html/examples/EbayPolicyExample.java | 14 +- .../html/examples/SlashdotPolicyExample.java | 14 +- .../owasp/html/examples/UrlTextExample.java | 8 +- src/test/java/org/owasp/html/Benchmark.java | 7 +- .../java/org/owasp/html/CssFuzzerTest.java | 4 +- .../java/org/owasp/html/CssGrammarTest.java | 18 +- .../java/org/owasp/html/CssTokensTest.java | 28 +- .../org/owasp/html/ElementPolicyTest.java | 12 +- .../java/org/owasp/html/HtmlLexerTest.java | 20 +- .../html/HtmlPolicyBuilderFuzzerTest.java | 7 +- .../org/owasp/html/HtmlPolicyBuilderTest.java | 60 ++-- .../owasp/html/HtmlSanitizerFuzzerTest.java | 12 +- .../owasp/html/HtmlStreamRendererTest.java | 109 ++++--- .../org/owasp/html/PolicyFactoryTest.java | 5 +- .../java/org/owasp/html/SanitizersTest.java | 13 +- .../org/owasp/html/StylingPolicyTest.java | 4 +- .../TagBalancingHtmlStreamRendererTest.java | 184 +++++------ 39 files changed, 700 insertions(+), 698 deletions(-) diff --git a/parent/pom.xml b/parent/pom.xml index ec4f2631..ceaac711 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -88,9 +88,12 @@ application while protecting against XSS. UTF-8 UTF-8 - 30.1-jre + 9 + 9 + 9 + @@ -184,8 +187,8 @@ application while protecting against XSS. maven-compiler-plugin 3.3 - 6 - 6 + 9 + 9 @@ -234,15 +237,10 @@ application while protecting against XSS. - - com.google.guava - guava - ${guava.version} - commons-codec commons-codec - [1.4,) + [1.15,) com.google.code.findbugs diff --git a/pom.xml b/pom.xml index ed9b523f..78532102 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,11 @@ org.apache.felix maven-bundle-plugin + + + org.owasp.html + + org.apache.maven.plugins @@ -81,10 +86,6 @@ - - com.google.guava - guava - commons-codec commons-codec diff --git a/src/main/java/org/owasp/html/AttributePolicy.java b/src/main/java/org/owasp/html/AttributePolicy.java index 7f279db5..56668f87 100644 --- a/src/main/java/org/owasp/html/AttributePolicy.java +++ b/src/main/java/org/owasp/html/AttributePolicy.java @@ -28,9 +28,8 @@ package org.owasp.html; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; - +import java.util.List; +import java.util.Optional; import java.util.Set; import javax.annotation.CheckReturnValue; @@ -91,11 +90,11 @@ static final class AttributePolicyJoiner } @Override - Optional> split(AttributePolicy x) { + Optional> split(AttributePolicy x) { if (x instanceof JoinedAttributePolicy) { return Optional.of(((JoinedAttributePolicy) x).policies); } else { - return Optional.absent(); + return Optional.empty(); } } diff --git a/src/main/java/org/owasp/html/CssSchema.java b/src/main/java/org/owasp/html/CssSchema.java index d344f23d..b9c6ae64 100644 --- a/src/main/java/org/owasp/html/CssSchema.java +++ b/src/main/java/org/owasp/html/CssSchema.java @@ -28,18 +28,18 @@ package org.owasp.html; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.SortedSet; +import java.util.TreeSet; import javax.annotation.Nullable; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - /** Describes the kinds of tokens a CSS property's value can safely contain. */ @TCB public final class CssSchema { @@ -54,11 +54,11 @@ public static final class Property { /** A bitfield of BIT_* constants describing groups of allowed tokens. */ final int bits; /** Specific allowed values. */ - final ImmutableSet literals; + final Set literals; /** * Maps lower-case function tokens to the schema key for their parameters. */ - final ImmutableMap fnKeys; + final Map fnKeys; /** * @param bits A bitfield of BIT_* constants describing groups of allowed tokens. @@ -66,11 +66,11 @@ public static final class Property { * @param fnKeys Maps lower-case function tokens to the schema key for their parameters. */ public Property( - int bits, ImmutableSet literals, - ImmutableMap fnKeys) { + int bits, Set literals, + Map fnKeys) { this.bits = bits; - this.literals = literals; - this.fnKeys = fnKeys; + this.literals = Set.copyOf(literals); + this.fnKeys = Map.copyOf(fnKeys); } @Override @@ -125,11 +125,11 @@ public boolean equals(Object obj) { static final int BIT_UNICODE_RANGE = 128; static final Property DISALLOWED = new Property( - 0, ImmutableSet.of(), ImmutableMap.of()); + 0, Collections.emptySet(), Collections.emptyMap()); - private final ImmutableMap properties; + private final Map properties; - private CssSchema(ImmutableMap properties) { + private CssSchema(Map properties) { if (properties == null) { throw new NullPointerException(); } this.properties = properties; } @@ -144,14 +144,14 @@ private CssSchema(ImmutableMap properties) { */ public static CssSchema withProperties( Iterable propertyNames) { - ImmutableMap.Builder propertiesBuilder = - ImmutableMap.builder(); + Map propertiesBuilder = + new HashMap<>(); for (String propertyName : propertyNames) { Property prop = DEFINITIONS.get(propertyName); if (prop == null) { throw new IllegalArgumentException(propertyName); } propertiesBuilder.put(propertyName, prop); } - return new CssSchema(propertiesBuilder.build()); + return new CssSchema(Map.copyOf(propertiesBuilder)); } /** @@ -161,8 +161,8 @@ public static CssSchema withProperties( */ public static CssSchema withProperties( Map properties) { - ImmutableMap propertyMap = - ImmutableMap.copyOf(properties); + Map propertyMap = + new HashMap<>(); // check that all fnKeys are defined in properties. for (Map.Entry e : propertyMap.entrySet()) { Property property = e.getValue(); @@ -174,7 +174,7 @@ public static CssSchema withProperties( } } } - return new CssSchema(propertyMap); + return new CssSchema(Map.copyOf(propertyMap)); } /** @@ -187,13 +187,17 @@ public static CssSchema withProperties( */ public static CssSchema union(CssSchema... cssSchemas) { if (cssSchemas.length == 1) { return cssSchemas[0]; } - Map properties = Maps.newLinkedHashMap(); + Map properties = new LinkedHashMap<>(); for (CssSchema cssSchema : cssSchemas) { for (Map.Entry e : cssSchema.properties.entrySet()) { String name = e.getKey(); Property newProp = e.getValue(); - Preconditions.checkNotNull(name); - Preconditions.checkNotNull(newProp); + if (Objects.isNull(name)) { + throw new NullPointerException("An entry was returned with null key from cssSchema.properties"); + } + if (Objects.isNull(newProp)) { + throw new NullPointerException("An entry was returned with null value from cssSchema.properties"); + } Property oldProp = properties.put(name, newProp); if (oldProp != null && !oldProp.equals(newProp)) { throw new IllegalArgumentException( @@ -201,7 +205,7 @@ public static CssSchema union(CssSchema... cssSchemas) { } } } - return new CssSchema(ImmutableMap.copyOf(properties)); + return new CssSchema(Map.copyOf(properties)); } /** @@ -221,6 +225,7 @@ Property forKey(String propertyName) { int n = propertyNameCanon.length(); if (n != 0 && propertyNameCanon.charAt(0) == '-') { String barePropertyNameCanon = stripVendorPrefix(propertyNameCanon); + if (barePropertyNameCanon == null) { return DISALLOWED; } property = properties.get(barePropertyNameCanon); if (property != null) { return property; } } @@ -252,14 +257,13 @@ Property forKey(String propertyName) { } /** Maps lower-cased CSS property names to information about them. */ - static final ImmutableMap DEFINITIONS; + static final Map DEFINITIONS; static { - ImmutableMap zeroFns = ImmutableMap.of(); - ImmutableMap.Builder builder - = ImmutableMap.builder(); - ImmutableSet mozBorderRadiusLiterals0 = ImmutableSet.of("/"); - ImmutableSet mozOpacityLiterals0 = ImmutableSet.of("inherit"); - ImmutableSet mozOutlineLiterals0 = ImmutableSet.of( + Map zeroFns = Collections.emptyMap(); + Map builder = new HashMap<>(); + Set mozBorderRadiusLiterals0 = Set.of("/"); + Set mozOpacityLiterals0 = Set.of("inherit"); + Set mozOutlineLiterals0 = Set.of( "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", @@ -287,122 +291,121 @@ Property forKey(String propertyName) { "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"); - ImmutableSet mozOutlineLiterals1 = ImmutableSet.of( + Set mozOutlineLiterals1 = Set.of( "dashed", "dotted", "double", "groove", "outset", "ridge", "solid"); - ImmutableSet mozOutlineLiterals2 = ImmutableSet.of("thick", "thin"); - ImmutableSet mozOutlineLiterals3 = ImmutableSet.of( + Set mozOutlineLiterals2 = Set.of("thick", "thin"); + Set mozOutlineLiterals3 = Set.of( "hidden", "inherit", "inset", "invert", "medium", "none"); - ImmutableMap mozOutlineFunctions = - ImmutableMap.of( + Map mozOutlineFunctions = + Map.of( "rgb(", "rgb()", "rgba(", "rgba()", "hsl(", "hsl()", "hsla(", "hsla()"); - ImmutableSet mozOutlineColorLiterals0 = - ImmutableSet.of("inherit", "invert"); - ImmutableSet mozOutlineStyleLiterals0 = - ImmutableSet.of("hidden", "inherit", "inset", "none"); - ImmutableSet mozOutlineWidthLiterals0 = - ImmutableSet.of("inherit", "medium"); - ImmutableSet oTextOverflowLiterals0 = - ImmutableSet.of("clip", "ellipsis"); - ImmutableSet azimuthLiterals0 = ImmutableSet.of( + Set mozOutlineColorLiterals0 = + Set.of("inherit", "invert"); + Set mozOutlineStyleLiterals0 = + Set.of("hidden", "inherit", "inset", "none"); + Set mozOutlineWidthLiterals0 = + Set.of("inherit", "medium"); + Set oTextOverflowLiterals0 = + Set.of("clip", "ellipsis"); + Set azimuthLiterals0 = Set.of( "behind", "center-left", "center-right", "far-left", "far-right", "left-side", "leftwards", "right-side", "rightwards"); - ImmutableSet azimuthLiterals1 = ImmutableSet.of("left", "right"); - ImmutableSet azimuthLiterals2 = - ImmutableSet.of("center", "inherit"); - ImmutableSet backgroundLiterals0 = ImmutableSet.of( + Set azimuthLiterals1 = Set.of("left", "right"); + Set azimuthLiterals2 = + Set.of("center", "inherit"); + Set backgroundLiterals0 = Set.of( "border-box", "contain", "content-box", "cover", "padding-box"); - ImmutableSet backgroundLiterals1 = - ImmutableSet.of("no-repeat", "repeat-x", "repeat-y", "round", "space"); - ImmutableSet backgroundLiterals2 = ImmutableSet.of("bottom", "top"); - ImmutableSet backgroundLiterals3 = ImmutableSet.of( + Set backgroundLiterals1 = + Set.of("no-repeat", "repeat-x", "repeat-y", "round", "space"); + Set backgroundLiterals2 = Set.of("bottom", "top"); + Set backgroundLiterals3 = Set.of( ",", "/", "auto", "center", "fixed", "inherit", "local", "none", "repeat", "scroll", "transparent"); - ImmutableMap backgroundFunctions = - ImmutableMap.builder() - .put("image(", "image()") - .put("linear-gradient(", "linear-gradient()") - .put("radial-gradient(", "radial-gradient()") - .put("repeating-linear-gradient(", "repeating-linear-gradient()") - .put("repeating-radial-gradient(", "repeating-radial-gradient()") - .put("rgb(", "rgb()").put("rgba(", "rgba()") - .put("hsl(", "hsl()").put("hsla(", "hsla()") - .build(); - ImmutableSet backgroundAttachmentLiterals0 = - ImmutableSet.of(",", "fixed", "local", "scroll"); - ImmutableSet backgroundColorLiterals0 = - ImmutableSet.of("inherit", "transparent"); - ImmutableSet backgroundImageLiterals0 = - ImmutableSet.of(",", "none"); - ImmutableMap backgroundImageFunctions = - ImmutableMap.of( + Map backgroundFunctions = + Map.of( + "image(", "image()", + "linear-gradient(", "linear-gradient()", + "radial-gradient(", "radial-gradient()", + "repeating-linear-gradient(", "repeating-linear-gradient()", + "repeating-radial-gradient(", "repeating-radial-gradient()", + "rgb(", "rgb()", "rgba(", "rgba()", + "hsl(", "hsl()", "hsla(", "hsla()"); + Set backgroundAttachmentLiterals0 = + Set.of(",", "fixed", "local", "scroll"); + Set backgroundColorLiterals0 = + Set.of("inherit", "transparent"); + Set backgroundImageLiterals0 = + Set.of(",", "none"); + Map backgroundImageFunctions = + Map.of( "image(", "image()", "linear-gradient(", "linear-gradient()", "radial-gradient(", "radial-gradient()", "repeating-linear-gradient(", "repeating-linear-gradient()", "repeating-radial-gradient(", "repeating-radial-gradient()"); - ImmutableSet backgroundPositionLiterals0 = ImmutableSet.of( + Set backgroundPositionLiterals0 = Set.of( ",", "center"); - ImmutableSet backgroundRepeatLiterals0 = ImmutableSet.of( + Set backgroundRepeatLiterals0 = Set.of( ",", "repeat"); - ImmutableSet borderLiterals0 = ImmutableSet.of( + Set borderLiterals0 = Set.of( "hidden", "inherit", "inset", "medium", "none", "transparent"); - ImmutableSet borderCollapseLiterals0 = ImmutableSet.of( + Set borderCollapseLiterals0 = Set.of( "collapse", "inherit", "separate"); - ImmutableSet bottomLiterals0 = ImmutableSet.of("auto", "inherit"); - ImmutableSet boxShadowLiterals0 = ImmutableSet.of( + Set bottomLiterals0 = Set.of("auto", "inherit"); + Set boxShadowLiterals0 = Set.of( ",", "inset", "none"); - ImmutableSet clearLiterals0 = ImmutableSet.of( + Set clearLiterals0 = Set.of( "both", "inherit", "none"); - ImmutableMap clipFunctions = - ImmutableMap.of("rect(", "rect()"); - ImmutableSet contentLiterals0 = ImmutableSet.of("none", "normal"); - ImmutableSet cueLiterals0 = ImmutableSet.of("inherit", "none"); - ImmutableSet cursorLiterals0 = ImmutableSet.of( + Map clipFunctions = + Map.of("rect(", "rect()"); + Set contentLiterals0 = Set.of("none", "normal"); + Set cueLiterals0 = Set.of("inherit", "none"); + Set cursorLiterals0 = Set.of( "all-scroll", "col-resize", "crosshair", "default", "e-resize", "hand", "help", "move", "n-resize", "ne-resize", "no-drop", "not-allowed", "nw-resize", "pointer", "progress", "row-resize", "s-resize", "se-resize", "sw-resize", "text", "vertical-text", "w-resize", "wait"); - ImmutableSet cursorLiterals1 = ImmutableSet.of( + Set cursorLiterals1 = Set.of( ",", "auto", "inherit"); - ImmutableSet directionLiterals0 = ImmutableSet.of("ltr", "rtl"); - ImmutableSet displayLiterals0 = ImmutableSet.of( + Set directionLiterals0 = Set.of("ltr", "rtl"); + Set displayLiterals0 = Set.of( "-moz-inline-box", "-moz-inline-stack", "block", "inline", "inline-block", "inline-table", "list-item", "run-in", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group"); - ImmutableSet elevationLiterals0 = ImmutableSet.of( + Set elevationLiterals0 = Set.of( "above", "below", "higher", "level", "lower"); - ImmutableSet emptyCellsLiterals0 = ImmutableSet.of("hide", "show"); - //ImmutableMap filterFunctions = - // ImmutableMap.of("alpha(", "alpha()"); - ImmutableSet fontLiterals0 = ImmutableSet.of( + Set emptyCellsLiterals0 = Set.of("hide", "show"); + //Map filterFunctions = + // Map.of("alpha(", "alpha()"); + Set fontLiterals0 = Set.of( "100", "200", "300", "400", "500", "600", "700", "800", "900", "bold", "bolder", "lighter"); - ImmutableSet fontLiterals1 = ImmutableSet.of( + Set fontLiterals1 = Set.of( "large", "larger", "small", "smaller", "x-large", "x-small", "xx-large", "xx-small", "xxx-large", "medium"); - ImmutableSet fontLiterals2 = ImmutableSet.of( + Set fontLiterals2 = Set.of( "caption", "icon", "menu", "message-box", "small-caption", "status-bar"); - ImmutableSet fontLiterals3 = ImmutableSet.of( + Set fontLiterals3 = Set.of( "cursive", "fantasy", "monospace", "sans-serif", "serif"); - ImmutableSet fontLiterals4 = ImmutableSet.of("italic", "oblique"); - ImmutableSet fontLiterals5 = ImmutableSet.of( + Set fontLiterals4 = Set.of("italic", "oblique"); + Set fontLiterals5 = Set.of( ",", "/", "inherit", "medium", "normal", "small-caps"); - ImmutableSet fontFamilyLiterals0 = ImmutableSet.of(",", "inherit"); - ImmutableSet fontStretchLiterals0 = ImmutableSet.of( + Set fontFamilyLiterals0 = Set.of(",", "inherit"); + Set fontStretchLiterals0 = Set.of( "condensed", "expanded", "extra-condensed", "extra-expanded", "narrower", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "wider"); - ImmutableSet fontStretchLiterals1 = ImmutableSet.of("normal"); - ImmutableSet fontStyleLiterals0 = ImmutableSet.of( + Set fontStretchLiterals1 = Set.of("normal"); + Set fontStyleLiterals0 = Set.of( "inherit", "normal"); - ImmutableSet fontVariantLiterals0 = ImmutableSet.of( + Set fontVariantLiterals0 = Set.of( "inherit", "normal", "small-caps"); - ImmutableSet listStyleLiterals0 = ImmutableSet.of( + Set listStyleLiterals0 = Set.of( "armenian", "cjk-decimal", "decimal", "decimal-leading-zero", "disc", "disclosure-closed", "disclosure-open", "ethiopic-numeric", "georgian", "hebrew", "hiragana", "hiragana-iroha", "japanese-formal", @@ -412,78 +415,78 @@ Property forKey(String propertyName) { "lower-roman", "simp-chinese-formal", "simp-chinese-informal", "square", "trad-chinese-formal", "trad-chinese-informal", "upper-alpha", "upper-latin", "upper-roman"); - ImmutableSet listStyleLiterals1 = ImmutableSet.of( + Set listStyleLiterals1 = Set.of( "inside", "outside"); - ImmutableSet listStyleLiterals2 = ImmutableSet.of( + Set listStyleLiterals2 = Set.of( "circle", "inherit", "none"); - ImmutableSet maxHeightLiterals0 = ImmutableSet.of( + Set maxHeightLiterals0 = Set.of( "auto", "inherit", "none"); - ImmutableSet overflowLiterals0 = ImmutableSet.of( + Set overflowLiterals0 = Set.of( "auto", "hidden", "inherit", "scroll", "visible"); - ImmutableSet overflowXLiterals0 = ImmutableSet.of( + Set overflowXLiterals0 = Set.of( "no-content", "no-display"); - ImmutableSet overflowXLiterals1 = ImmutableSet.of( + Set overflowXLiterals1 = Set.of( "auto", "hidden", "scroll", "visible"); - ImmutableSet pageBreakAfterLiterals0 = ImmutableSet.of( + Set pageBreakAfterLiterals0 = Set.of( "always", "auto", "avoid", "inherit"); - ImmutableSet pageBreakInsideLiterals0 = ImmutableSet.of( + Set pageBreakInsideLiterals0 = Set.of( "auto", "avoid", "inherit"); - ImmutableSet pitchLiterals0 = ImmutableSet.of( + Set pitchLiterals0 = Set.of( "high", "low", "x-high", "x-low"); - ImmutableSet playDuringLiterals0 = ImmutableSet.of( + Set playDuringLiterals0 = Set.of( "auto", "inherit", "mix", "none", "repeat"); - ImmutableSet positionLiterals0 = ImmutableSet.of( + Set positionLiterals0 = Set.of( "absolute", "relative", "static"); - ImmutableSet speakLiterals0 = ImmutableSet.of( + Set speakLiterals0 = Set.of( "inherit", "none", "normal", "spell-out"); - ImmutableSet speakHeaderLiterals0 = ImmutableSet.of( + Set speakHeaderLiterals0 = Set.of( "always", "inherit", "once"); - ImmutableSet speakNumeralLiterals0 = ImmutableSet.of( + Set speakNumeralLiterals0 = Set.of( "continuous", "digits"); - ImmutableSet speakPunctuationLiterals0 = ImmutableSet.of( + Set speakPunctuationLiterals0 = Set.of( "code", "inherit", "none"); - ImmutableSet speechRateLiterals0 = ImmutableSet.of( + Set speechRateLiterals0 = Set.of( "fast", "faster", "slow", "slower", "x-fast", "x-slow"); - ImmutableSet tableLayoutLiterals0 = ImmutableSet.of( + Set tableLayoutLiterals0 = Set.of( "auto", "fixed", "inherit"); - ImmutableSet textAlignLiterals0 = ImmutableSet.of( + Set textAlignLiterals0 = Set.of( "center", "inherit", "justify"); - ImmutableSet textDecorationLiterals0 = ImmutableSet.of( + Set textDecorationLiterals0 = Set.of( "blink", "line-through", "overline", "underline"); - ImmutableSet textTransformLiterals0 = ImmutableSet.of( + Set textTransformLiterals0 = Set.of( "capitalize", "lowercase", "uppercase"); - ImmutableSet textWrapLiterals0 = ImmutableSet.of( + Set textWrapLiterals0 = Set.of( "suppress", "unrestricted"); - ImmutableSet unicodeBidiLiterals0 = ImmutableSet.of( + Set unicodeBidiLiterals0 = Set.of( "bidi-override", "embed"); - ImmutableSet verticalAlignLiterals0 = ImmutableSet.of( + Set verticalAlignLiterals0 = Set.of( "baseline", "middle", "sub", "super", "text-bottom", "text-top"); - ImmutableSet visibilityLiterals0 = ImmutableSet.of( + Set visibilityLiterals0 = Set.of( "collapse", "hidden", "inherit", "visible"); - ImmutableSet voiceFamilyLiterals0 = ImmutableSet.of( + Set voiceFamilyLiterals0 = Set.of( "child", "female", "male"); - ImmutableSet volumeLiterals0 = ImmutableSet.of( + Set volumeLiterals0 = Set.of( "loud", "silent", "soft", "x-loud", "x-soft"); - ImmutableSet whiteSpaceLiterals0 = ImmutableSet.of( + Set whiteSpaceLiterals0 = Set.of( "-moz-pre-wrap", "-o-pre-wrap", "-pre-wrap", "nowrap", "pre", "pre-line", "pre-wrap"); - ImmutableSet wordWrapLiterals0 = ImmutableSet.of( + Set wordWrapLiterals0 = Set.of( "break-word", "normal"); - ImmutableSet rgb$FunLiterals0 = ImmutableSet.of(","); - ImmutableSet linearGradient$FunLiterals0 = ImmutableSet.of( + Set rgb$FunLiterals0 = Set.of(","); + Set linearGradient$FunLiterals0 = Set.of( ",", "to"); - ImmutableSet radialGradient$FunLiterals0 = ImmutableSet.of( + Set radialGradient$FunLiterals0 = Set.of( "at", "closest-corner", "closest-side", "ellipse", "farthest-corner", "farthest-side"); - ImmutableSet radialGradient$FunLiterals1 = ImmutableSet.of( + Set radialGradient$FunLiterals1 = Set.of( ",", "center", "circle"); - ImmutableSet rect$FunLiterals0 = ImmutableSet.of(",", "auto"); - //ImmutableSet alpha$FunLiterals0 = ImmutableSet.of("=", "opacity"); + Set rect$FunLiterals0 = Set.of(",", "auto"); + //Set alpha$FunLiterals0 = Set.of("=", "opacity"); Property mozBorderRadius = new Property(5, mozBorderRadiusLiterals0, zeroFns); builder.put("-moz-border-radius", mozBorderRadius); Property mozBorderRadiusBottomleft = - new Property(5, ImmutableSet.of(), zeroFns); + new Property(5, Set.of(), zeroFns); builder.put("-moz-border-radius-bottomleft", mozBorderRadiusBottomleft); Property mozOpacity = new Property(1, mozOpacityLiterals0, zeroFns); builder.put("-moz-opacity", mozOpacity); @@ -843,19 +846,18 @@ Property forKey(String propertyName) { builder.put("z-index", bottom); builder.put("repeating-linear-gradient()", linearGradient$Fun); builder.put("repeating-radial-gradient()", radialGradient$Fun); - DEFINITIONS = builder.build(); + DEFINITIONS = Map.copyOf(builder); } - private static ImmutableSet union( - @SuppressWarnings("unchecked") ImmutableSet... subsets) { - ImmutableSet.Builder all = ImmutableSet.builder(); - for (ImmutableSet subset : subsets) { + private static Set union(Set... subsets) { + Set all = new HashSet<>(); + for (Set subset : subsets) { all.addAll(subset); } - return all.build(); + return Set.copyOf(all); } - static final ImmutableSet DEFAULT_WHITELIST = ImmutableSet.of( + static final Set DEFAULT_WHITELIST = Set.of( "-moz-border-radius", "-moz-border-radius-bottomleft", "-moz-border-radius-bottomright", @@ -1002,10 +1004,10 @@ private static ImmutableSet union( /** Dumps key and literal list to stdout for easy examination. */ public static void main(String... argv) { - SortedSet keys = Sets.newTreeSet(); - SortedSet literals = Sets.newTreeSet(); + SortedSet keys = new TreeSet<>(); + SortedSet literals = new TreeSet<>(); - for (ImmutableMap.Entry e : DEFINITIONS.entrySet()) { + for (Map.Entry e : DEFINITIONS.entrySet()) { keys.add(e.getKey()); literals.addAll(e.getValue().literals); } diff --git a/src/main/java/org/owasp/html/CssTokens.java b/src/main/java/org/owasp/html/CssTokens.java index 7fd44904..626ecb29 100644 --- a/src/main/java/org/owasp/html/CssTokens.java +++ b/src/main/java/org/owasp/html/CssTokens.java @@ -31,12 +31,11 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; import javax.annotation.Nullable; -import com.google.common.collect.ImmutableMap; - /** * Given a string of CSS, produces a string of normalized CSS with certain * useful properties detailed below. @@ -1464,34 +1463,34 @@ private static int[] truncateOrShare(int[] arr, int limit) { * See http://dev.w3.org/csswg/css-values/#lengths and * http://dev.w3.org/csswg/css-values/#other-units */ - private static final Trie UNIT_TRIE = new Trie( - ImmutableMap.builder() - .put("em", LENGTH_UNIT_TYPE) - .put("ex", LENGTH_UNIT_TYPE) - .put("ch", LENGTH_UNIT_TYPE) // Width of zero character - .put("rem", LENGTH_UNIT_TYPE) // Root element font-size - .put("vh", LENGTH_UNIT_TYPE) - .put("vw", LENGTH_UNIT_TYPE) - .put("vmin", LENGTH_UNIT_TYPE) - .put("vmax", LENGTH_UNIT_TYPE) - .put("px", LENGTH_UNIT_TYPE) - .put("mm", LENGTH_UNIT_TYPE) - .put("cm", LENGTH_UNIT_TYPE) - .put("in", LENGTH_UNIT_TYPE) - .put("pt", LENGTH_UNIT_TYPE) - .put("pc", LENGTH_UNIT_TYPE) - .put("deg", ANGLE_UNIT_TYPE) - .put("rad", ANGLE_UNIT_TYPE) - .put("grad", ANGLE_UNIT_TYPE) - .put("turn", ANGLE_UNIT_TYPE) - .put("s", TIME_UNIT_TYPE) - .put("ms", TIME_UNIT_TYPE) - .put("hz", FREQUENCY_UNIT_TYPE) - .put("khz", FREQUENCY_UNIT_TYPE) - .put("dpi", RESOLUTION_UNIT_TYPE) - .put("dpcm", RESOLUTION_UNIT_TYPE) - .put("dppx", RESOLUTION_UNIT_TYPE) - .build()); + private static final Trie UNIT_TRIE = new Trie<>( + Map.ofEntries( + Map.entry("em", LENGTH_UNIT_TYPE), + Map.entry("ex", LENGTH_UNIT_TYPE), + Map.entry("ch", LENGTH_UNIT_TYPE), // Width of zero character + Map.entry("rem", LENGTH_UNIT_TYPE), // Root element font-size + Map.entry("vh", LENGTH_UNIT_TYPE), + Map.entry("vw", LENGTH_UNIT_TYPE), + Map.entry("vmin", LENGTH_UNIT_TYPE), + Map.entry("vmax", LENGTH_UNIT_TYPE), + Map.entry("px", LENGTH_UNIT_TYPE), + Map.entry("mm", LENGTH_UNIT_TYPE), + Map.entry("cm", LENGTH_UNIT_TYPE), + Map.entry("in", LENGTH_UNIT_TYPE), + Map.entry("pt", LENGTH_UNIT_TYPE), + Map.entry("pc", LENGTH_UNIT_TYPE), + Map.entry("deg", ANGLE_UNIT_TYPE), + Map.entry("rad", ANGLE_UNIT_TYPE), + Map.entry("grad", ANGLE_UNIT_TYPE), + Map.entry("turn", ANGLE_UNIT_TYPE), + Map.entry("s", TIME_UNIT_TYPE), + Map.entry("ms", TIME_UNIT_TYPE), + Map.entry("hz", FREQUENCY_UNIT_TYPE), + Map.entry("khz", FREQUENCY_UNIT_TYPE), + Map.entry("dpi", RESOLUTION_UNIT_TYPE), + Map.entry("dpcm", RESOLUTION_UNIT_TYPE), + Map.entry("dppx", RESOLUTION_UNIT_TYPE)) + ); static boolean isWellKnownUnit(CharSequence s, int start, int end) { if (start == end) { return false; } diff --git a/src/main/java/org/owasp/html/ElementAndAttributePolicies.java b/src/main/java/org/owasp/html/ElementAndAttributePolicies.java index 8f2cdca6..1097a572 100644 --- a/src/main/java/org/owasp/html/ElementAndAttributePolicies.java +++ b/src/main/java/org/owasp/html/ElementAndAttributePolicies.java @@ -28,9 +28,9 @@ package org.owasp.html; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import javax.annotation.concurrent.Immutable; /** @@ -42,7 +42,7 @@ final class ElementAndAttributePolicies { final String elementName; final ElementPolicy elPolicy; - final ImmutableMap attrPolicies; + final Map attrPolicies; final HtmlTagSkipType htmlTagSkipType; ElementAndAttributePolicies( @@ -53,15 +53,15 @@ final class ElementAndAttributePolicies { HtmlTagSkipType htmlTagSkipType) { this.elementName = elementName; this.elPolicy = elPolicy; - this.attrPolicies = ImmutableMap.copyOf(attrPolicies); + this.attrPolicies = Map.copyOf(attrPolicies); this.htmlTagSkipType = htmlTagSkipType; } ElementAndAttributePolicies and(ElementAndAttributePolicies p) { assert elementName.equals(p.elementName): elementName + " != " + p.elementName; - ImmutableMap.Builder joinedAttrPolicies - = ImmutableMap.builder(); + Map joinedAttrPolicies + = new HashMap<>(); for (Map.Entry e : this.attrPolicies.entrySet()) { String attrName = e.getKey(); AttributePolicy a = e.getValue(); @@ -81,7 +81,7 @@ ElementAndAttributePolicies and(ElementAndAttributePolicies p) { return new ElementAndAttributePolicies( elementName, ElementPolicy.Util.join(elPolicy, p.elPolicy), - joinedAttrPolicies.build(), + Map.copyOf(joinedAttrPolicies), this.htmlTagSkipType.and(p.htmlTagSkipType)); } @@ -98,7 +98,7 @@ ElementAndAttributePolicies andGlobals( attrPolicy, globalAttrPolicy); if (!joined.equals(attrPolicy)) { if (anded == null) { - anded = Maps.newLinkedHashMap(); + anded = new LinkedHashMap<>(); anded.putAll(this.attrPolicies); } anded.put(attrName, joined); @@ -109,7 +109,7 @@ ElementAndAttributePolicies andGlobals( String attrName = e.getKey(); if (!this.attrPolicies.containsKey(attrName)) { if (anded == null) { - anded = Maps.newLinkedHashMap(); + anded = new LinkedHashMap<>(); anded.putAll(this.attrPolicies); } anded.put(attrName, e.getValue()); diff --git a/src/main/java/org/owasp/html/ElementAndAttributePolicyBasedSanitizerPolicy.java b/src/main/java/org/owasp/html/ElementAndAttributePolicyBasedSanitizerPolicy.java index c8da4617..4f78e2c8 100644 --- a/src/main/java/org/owasp/html/ElementAndAttributePolicyBasedSanitizerPolicy.java +++ b/src/main/java/org/owasp/html/ElementAndAttributePolicyBasedSanitizerPolicy.java @@ -28,16 +28,15 @@ package org.owasp.html; +import java.util.ArrayList; import java.util.List; import java.util.ListIterator; +import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; - /** * A sanitizer policy that applies element and attribute policies to tags. */ @@ -45,8 +44,8 @@ @NotThreadSafe class ElementAndAttributePolicyBasedSanitizerPolicy implements HtmlSanitizer.Policy { - final ImmutableMap elAndAttrPolicies; - final ImmutableSet allowedTextContainers; + final Map elAndAttrPolicies; + final Set allowedTextContainers; private final HtmlStreamEventReceiver out; /** * True to skip textual content. Used to ignore the content of embedded CDATA @@ -57,19 +56,19 @@ class ElementAndAttributePolicyBasedSanitizerPolicy * Alternating input names and adjusted names of elements opened by the * caller. */ - private final List openElementStack = Lists.newArrayList(); + private final List openElementStack = new ArrayList<>(); ElementAndAttributePolicyBasedSanitizerPolicy( HtmlStreamEventReceiver out, - ImmutableMap elAndAttrPolicies, - ImmutableSet allowedTextContainers) { + Map elAndAttrPolicies, + Set allowedTextContainers) { this.out = out; - this.elAndAttrPolicies = elAndAttrPolicies; - this.allowedTextContainers = allowedTextContainers; + this.elAndAttrPolicies = Map.copyOf(elAndAttrPolicies); + this.allowedTextContainers = Set.copyOf(allowedTextContainers); } - static final ImmutableSet SKIPPABLE_ELEMENT_CONTENT - = ImmutableSet.of( + static final Set SKIPPABLE_ELEMENT_CONTENT + = Set.of( "script", "style", "noscript", "nostyle", "noembed", "noframes", "iframe", "object", "frame", "frameset", "title"); diff --git a/src/main/java/org/owasp/html/ElementPolicy.java b/src/main/java/org/owasp/html/ElementPolicy.java index 689dec6b..38817621 100644 --- a/src/main/java/org/owasp/html/ElementPolicy.java +++ b/src/main/java/org/owasp/html/ElementPolicy.java @@ -28,7 +28,9 @@ package org.owasp.html; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; @@ -36,9 +38,6 @@ import org.owasp.html.Joinable.JoinHelper; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; - /** * A policy that can be applied to an element to decide whether or not to * allow it in the output, possibly after transforming attributes. @@ -90,11 +89,11 @@ static final class PolicyJoiner } @Override - Optional> split(ElementPolicy x) { + Optional> split(ElementPolicy x) { if (x instanceof JoinedElementPolicy) { return Optional.of(((JoinedElementPolicy) x).policies); } - return Optional.absent(); + return Optional.empty(); } @Override @@ -129,10 +128,12 @@ static interface JoinableElementPolicy @Immutable final class JoinedElementPolicy implements ElementPolicy { - final ImmutableList policies; + final List policies; JoinedElementPolicy(Iterable policies) { - this.policies = ImmutableList.copyOf(policies); + List builder = new ArrayList<>(); + policies.forEach(builder::add); + this.policies = List.copyOf(builder); } public @Nullable String apply(String elementName, List attrs) { diff --git a/src/main/java/org/owasp/html/FilterUrlByProtocolAttributePolicy.java b/src/main/java/org/owasp/html/FilterUrlByProtocolAttributePolicy.java index 54dd10ae..1e64ee2c 100644 --- a/src/main/java/org/owasp/html/FilterUrlByProtocolAttributePolicy.java +++ b/src/main/java/org/owasp/html/FilterUrlByProtocolAttributePolicy.java @@ -28,9 +28,10 @@ package org.owasp.html; -import javax.annotation.Nullable; +import java.util.HashSet; +import java.util.Set; -import com.google.common.collect.ImmutableSet; +import javax.annotation.Nullable; /** * An attribute policy for attributes whose values are URLs that requires that @@ -56,14 +57,16 @@ */ @TCB public class FilterUrlByProtocolAttributePolicy implements AttributePolicy { - private final ImmutableSet protocols; + private final Set protocols; /** * @param protocols lower-case protocol names without any trailing colon (":") */ public FilterUrlByProtocolAttributePolicy( Iterable protocols) { - this.protocols = ImmutableSet.copyOf(protocols); + Set builder = new HashSet<>(); + protocols.forEach(builder::add); + this.protocols = Set.copyOf(builder); } public @Nullable String apply( diff --git a/src/main/java/org/owasp/html/HtmlElementTables.java b/src/main/java/org/owasp/html/HtmlElementTables.java index 1ff74e46..8bb5cd14 100644 --- a/src/main/java/org/owasp/html/HtmlElementTables.java +++ b/src/main/java/org/owasp/html/HtmlElementTables.java @@ -2,11 +2,9 @@ import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; import java.util.List; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; +import java.util.Map; /** * Metadata about HTML elements. @@ -124,7 +122,7 @@ public HtmlElementTables( COLGROUP_TAG = indexForName("colgroup"); IFRAME_TAG = indexForName("iframe"); - ImmutableList freeWrappers = ImmutableList.of( + List freeWrappers = List.of( new FreeWrapper( LI_TAG, // LI_TAG is allowed here since an LI can appear when an LI is on @@ -396,18 +394,18 @@ public static final class HtmlElementNames { /** * Canonical element names by element index. */ - public final ImmutableList canonNames; - private transient ImmutableMap canonNameToIndex; + public final List canonNames; + private transient Map canonNameToIndex; private transient int customElementIndex; /** */ public HtmlElementNames(List canonNames) { - this.canonNames = ImmutableList.copyOf(canonNames); + this.canonNames = List.copyOf(canonNames); } /** */ HtmlElementNames(String... canonNames) { - this.canonNames = ImmutableList.copyOf(canonNames); + this.canonNames = List.of(canonNames); } /** @@ -416,13 +414,16 @@ public HtmlElementNames(List canonNames) { */ public int getElementNameIndex(String canonName) { if (canonNameToIndex == null) { - ImmutableMap.Builder b = ImmutableMap.builder(); + Map builder = new HashMap<>(); for (int i = 0, n = this.canonNames.size(); i < n; ++i) { - b.put(this.canonNames.get(i), i); + builder.put(this.canonNames.get(i), i); } - canonNameToIndex = b.build(); + canonNameToIndex = Map.copyOf(builder); this.customElementIndex = canonNames.indexOf(CUSTOM_ELEMENT_NAME); - Preconditions.checkState(this.customElementIndex >= 0); + if (this.customElementIndex < 0) { + throw new IllegalStateException("Negative element index"); + } + } Integer index = canonNameToIndex.get(canonName); return index != null ? index.intValue() : customElementIndex; @@ -438,7 +439,9 @@ static final class DenseElementBinaryMatrix { /** */ public DenseElementBinaryMatrix(boolean[] bits, int matrixLength) { - Preconditions.checkArgument(bits.length == matrixLength * matrixLength); + if (bits.length != matrixLength * matrixLength) { + throw new IllegalArgumentException("Invalid matrix size"); + } this.matrixLength = matrixLength; this.bits = bits.clone(); } @@ -448,8 +451,12 @@ public DenseElementBinaryMatrix(boolean[] bits, int matrixLength) { * @param b the second element name index. */ public boolean get(int a, int b) { - Preconditions.checkElementIndex(a, matrixLength); - Preconditions.checkElementIndex(b, matrixLength); + if (a < 0 || a >= matrixLength) { + throw new IndexOutOfBoundsException("Invalid index for first element"); + } + if (b < 0 && b >= matrixLength) { + throw new IndexOutOfBoundsException("Invalid index for second element"); + } return bits[a * matrixLength + b]; } @@ -504,12 +511,16 @@ public SparseElementToElements(int[][] arrs) { int last = -1; for (int i = 0, n = this.arrs.length; i < n; ++i) { int[] arr = arrs[i] = arrs[i].clone(); - Preconditions.checkArgument(last < arr[0]); + if (last >= arr[0]) { + throw new IllegalArgumentException("Non sorted array"); + } last = arr[0]; int lastVal = -1; for (int j = 1, m = arr.length; j < m; ++j) { int val = arr[j]; - Preconditions.checkArgument(val > lastVal, arr); + if (val <= lastVal) { + throw new IllegalArgumentException("Non sorted array"); + } lastVal = val; } } @@ -570,8 +581,9 @@ public SparseElementMultitable(int[][][] arrs) { int[][] arrEl = this.arrs[j] = this.arrs[j].clone(); for (int i = 0, m = arrEl.length; i < m; ++i) { int[] row = arrEl[i] = arrEl[i].clone(); - Preconditions.checkState( - i == 0 || row[0] > arrEl[i - 1][0]); + if (i != 0 && row[0] <= arrEl[i - 1][0]) { + throw new IllegalStateException("Illegal array state"); + } } } } diff --git a/src/main/java/org/owasp/html/HtmlEntities.java b/src/main/java/org/owasp/html/HtmlEntities.java index 774108cf..ca7a2248 100644 --- a/src/main/java/org/owasp/html/HtmlEntities.java +++ b/src/main/java/org/owasp/html/HtmlEntities.java @@ -28,10 +28,9 @@ package org.owasp.html; +import java.util.HashMap; import java.util.Map; -import com.google.common.collect.ImmutableMap; - /** * Utilities for decoding HTML entities, e.g., {@code &}. */ @@ -2279,7 +2278,7 @@ final class HtmlEntities { "zwnj;", "\u200c", }; - final ImmutableMap.Builder builder = ImmutableMap.builder(); + final Map builder = new HashMap<>(); int longestEntityName = 0; for (int i = 0, n = pairs.length; i < n; i += 2) { @@ -2291,7 +2290,7 @@ final class HtmlEntities { } } - final Map entityNameToCodePointMap = builder.build(); + final Map entityNameToCodePointMap = Map.copyOf(builder); ENTITY_TRIE = new Trie(entityNameToCodePointMap); LONGEST_ENTITY_NAME = longestEntityName; diff --git a/src/main/java/org/owasp/html/HtmlLexer.java b/src/main/java/org/owasp/html/HtmlLexer.java index 00fcc7dc..cc6d2bbf 100644 --- a/src/main/java/org/owasp/html/HtmlLexer.java +++ b/src/main/java/org/owasp/html/HtmlLexer.java @@ -28,8 +28,6 @@ package org.owasp.html; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Set; @@ -235,7 +233,7 @@ private static HtmlToken join(HtmlToken a, HtmlToken b) { return HtmlToken.instance(a.start, b.end, a.type); } - private final LinkedList lookahead = Lists.newLinkedList(); + private final LinkedList lookahead = new LinkedList<>(); private HtmlToken readToken() { if (!lookahead.isEmpty()) { return lookahead.remove(); @@ -263,12 +261,12 @@ private static boolean isValuelessAttribute(String attribName) { } // From http://issues.apache.org/jira/browse/XALANC-519 - private static final Set VALUELESS_ATTRIB_NAMES = ImmutableSet.of( + private static final Set VALUELESS_ATTRIB_NAMES = Set.of( "checked", "compact", "declare", "defer", "disabled", "ismap", "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly", "selected"); - private static final ImmutableSet mixedCaseForeignAttributeNames = ImmutableSet.of( + private static final Set mixedCaseForeignAttributeNames = Set.of( "attributeName", "attributeType", "baseFrequency", @@ -349,7 +347,7 @@ private static boolean isValuelessAttribute(String attribName) { "zoomAndPan" ); - private static final ImmutableSet mixedCaseForeignElementNames = ImmutableSet.of( + private static final Set mixedCaseForeignElementNames = Set.of( "animateColor", "animateMotion", "animateTransform", diff --git a/src/main/java/org/owasp/html/HtmlPolicyBuilder.java b/src/main/java/org/owasp/html/HtmlPolicyBuilder.java index c43bfb86..fa1a30ef 100644 --- a/src/main/java/org/owasp/html/HtmlPolicyBuilder.java +++ b/src/main/java/org/owasp/html/HtmlPolicyBuilder.java @@ -28,27 +28,24 @@ package org.owasp.html; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; import org.owasp.html.ElementPolicy.JoinableElementPolicy; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - - /** * Conveniences for configuring policies for the {@link HtmlSanitizer}. * @@ -165,16 +162,16 @@ public class HtmlPolicyBuilder { * and it has no other attributes that would warrant it appearing in the * output. */ - public static final ImmutableSet DEFAULT_SKIP_IF_EMPTY - = ImmutableSet.of("a", "font", "img", "input", "span"); + public static final Set DEFAULT_SKIP_IF_EMPTY + = Set.of("a", "font", "img", "input", "span"); - static final ImmutableMap DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR; + static final Map DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR; static { - ImmutableMap.Builder b = ImmutableMap.builder(); + Map builder = new HashMap<>(); for (String elementName : DEFAULT_SKIP_IF_EMPTY) { - b.put(elementName, HtmlTagSkipType.SKIP_BY_DEFAULT); + builder.put(elementName, HtmlTagSkipType.SKIP_BY_DEFAULT); } - DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR = b.build(); + DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR = Map.copyOf(builder); } /** @@ -187,20 +184,20 @@ public class HtmlPolicyBuilder { * @see About rel=noopener */ - public static final ImmutableSet DEFAULT_RELS_ON_TARGETTED_LINKS - = ImmutableSet.of("noopener", "noreferrer"); + public static final List DEFAULT_RELS_ON_TARGETTED_LINKS + = List.of("noopener", "noreferrer"); static final String DEFAULT_RELS_ON_TARGETTED_LINKS_STR - = Joiner.on(' ').join(DEFAULT_RELS_ON_TARGETTED_LINKS); + = DEFAULT_RELS_ON_TARGETTED_LINKS.stream().collect(Collectors.joining(" ")); - private final Map elPolicies = Maps.newLinkedHashMap(); + private final Map elPolicies = new LinkedHashMap<>(); private final Map> attrPolicies - = Maps.newLinkedHashMap(); + = new LinkedHashMap<>(); private final Map globalAttrPolicies - = Maps.newLinkedHashMap(); - private final Set allowedProtocols = Sets.newLinkedHashSet(); - private final Map skipIssueTagMap = Maps.newLinkedHashMap(DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR); - private final Map textContainers = Maps.newLinkedHashMap(); + = new LinkedHashMap<>(); + private final Set allowedProtocols = new HashSet<>(); + private final Map skipIssueTagMap = new LinkedHashMap<>(DEFAULT_SKIP_TAG_MAP_IF_EMPTY_ATTR); + private final Map textContainers = new LinkedHashMap<>(); private HtmlStreamEventProcessor postprocessor = HtmlStreamEventProcessor.Processors.IDENTITY; private HtmlStreamEventProcessor preprocessor = @@ -347,11 +344,11 @@ public HtmlPolicyBuilder disallowWithoutAttributes(String... elementNames) { * attributes, and allow them globally or on specific elements. */ public AttributeBuilder allowAttributes(String... attributeNames) { - ImmutableList.Builder b = ImmutableList.builder(); + List builder = new ArrayList<>(); for (String attributeName : attributeNames) { - b.add(HtmlLexer.canonicalAttributeName(attributeName)); + builder.add(HtmlLexer.canonicalAttributeName(attributeName)); } - return new AttributeBuilder(b.build()); + return new AttributeBuilder(List.copyOf(builder)); } /** @@ -392,7 +389,7 @@ private HtmlPolicyBuilder allowAttributesOnElements( for (String elementName : elementNames) { Map policies = attrPolicies.get(elementName); if (policies == null) { - policies = Maps.newLinkedHashMap(); + policies = new LinkedHashMap<>(); attrPolicies.put(elementName, policies); } for (String attributeName : attributeNames) { @@ -429,13 +426,13 @@ public HtmlPolicyBuilder requireRelNofollowOnLinks() { public HtmlPolicyBuilder requireRelsOnLinks(String... linkValues) { this.invalidateCompiledState(); if (this.extraRelsForLinks == null) { - this.extraRelsForLinks = Sets.newLinkedHashSet(); + this.extraRelsForLinks = new HashSet<>(); } for (String linkValue : linkValues) { linkValue = HtmlLexer.canonicalKeywordAttributeValue(linkValue); - Preconditions.checkArgument( - !Strings.containsHtmlSpace(linkValue), - "spaces in input. use f(\"foo\", \"bar\") not f(\"foo bar\")"); + if (Strings.containsHtmlSpace(linkValue)) { + throw new IllegalArgumentException("spaces in input. use f(\"foo\", \"bar\") not f(\"foo bar\")"); + } this.extraRelsForLinks.add(linkValue); } if (this.skipRelsForLinks != null) { @@ -453,13 +450,13 @@ public HtmlPolicyBuilder requireRelsOnLinks(String... linkValues) { public HtmlPolicyBuilder skipRelsOnLinks(String... linkValues) { this.invalidateCompiledState(); if (this.skipRelsForLinks == null) { - this.skipRelsForLinks = Sets.newLinkedHashSet(); + this.skipRelsForLinks = new HashSet<>(); } for (String linkValue : linkValues) { linkValue = HtmlLexer.canonicalKeywordAttributeValue(linkValue); - Preconditions.checkArgument( - !Strings.containsHtmlSpace(linkValue), - "spaces in input. use f(\"foo\", \"bar\") not f(\"foo bar\")"); + if (Strings.containsHtmlSpace(linkValue)) { + throw new IllegalArgumentException("spaces in input. use f(\"foo\", \"bar\") not f(\"foo bar\")"); + } this.skipRelsForLinks.add(linkValue); } if (this.extraRelsForLinks != null) { @@ -542,7 +539,7 @@ public HtmlPolicyBuilder allowStyling(CssSchema whitelist) { // still not allowing styles when allowStyling is followed by a call to // disallowAttributesGlobally("style"). this.allowAttributesGlobally( - AttributePolicy.IDENTITY_ATTRIBUTE_POLICY, ImmutableList.of("style")); + AttributePolicy.IDENTITY_ATTRIBUTE_POLICY, List.of("style")); return this; } @@ -607,8 +604,8 @@ public HtmlPolicyBuilder withPostprocessor(HtmlStreamEventProcessor pp) { // allowing the attribute "href" globally with the identity policy but // not white-listing any protocols, effectively disallows the "href" // attribute globally. - ImmutableMap.Builder b = - ImmutableMap.builder(); + Map builder = + new HashMap<>(); AttributeGuardMaker identityGuard = new AttributeGuardMaker() { @Override AttributePolicy makeGuard(AttributeGuardIntermediates intermediates) { @@ -620,9 +617,9 @@ AttributePolicy makeGuard(AttributeGuardIntermediates intermediates) { "dsync", "formaction", "href", "icon", "longdesc", "manifest", "poster", "profile", "src", "usemap", }) { - b.put(urlAttributeName, identityGuard); + builder.put(urlAttributeName, identityGuard); } - b.put("style", new AttributeGuardMaker() { + builder.put("style", new AttributeGuardMaker() { @Override AttributePolicy makeGuard(AttributeGuardIntermediates intermediates) { @@ -643,7 +640,7 @@ public String apply(String url) { } }); - b.put("srcset", new AttributeGuardMaker() { + builder.put("srcset", new AttributeGuardMaker() { @Override AttributePolicy makeGuard(AttributeGuardIntermediates intermediates) { @@ -651,7 +648,7 @@ AttributePolicy makeGuard(AttributeGuardIntermediates intermediates) { } }); - ATTRIBUTE_GUARDS = b.build(); + ATTRIBUTE_GUARDS = Map.copyOf(builder); } /** @@ -690,7 +687,7 @@ public HtmlSanitizer.Policy build( * each backed by a different output channel. */ public PolicyFactory toFactory() { - ImmutableSet.Builder textContainerSet = ImmutableSet.builder(); + Set textContainerSet = new HashSet<>(); for (Map.Entry textContainer : this.textContainers.entrySet()) { if (Boolean.TRUE.equals(textContainer.getValue())) { @@ -700,8 +697,8 @@ public PolicyFactory toFactory() { CompiledState compiled = compilePolicies(); return new PolicyFactory( - compiled.compiledPolicies, textContainerSet.build(), - ImmutableMap.copyOf(compiled.globalAttrPolicies), + compiled.compiledPolicies, Set.copyOf(textContainerSet), + Map.copyOf(compiled.globalAttrPolicies), preprocessor, postprocessor); } @@ -710,11 +707,11 @@ public PolicyFactory toFactory() { private static final class CompiledState { final Map globalAttrPolicies; - final ImmutableMap compiledPolicies; + final Map compiledPolicies; CompiledState( Map globalAttrPolicies, - ImmutableMap compiledPolicies) { + Map compiledPolicies) { this.globalAttrPolicies = globalAttrPolicies; this.compiledPolicies = compiledPolicies; } @@ -731,19 +728,19 @@ private CompiledState compilePolicies() { // Copy maps before normalizing in case builder is reused. @SuppressWarnings("hiding") Map elPolicies - = Maps.newLinkedHashMap(this.elPolicies); + = new LinkedHashMap<>(this.elPolicies); @SuppressWarnings("hiding") Map> attrPolicies - = Maps.newLinkedHashMap(this.attrPolicies); + = new LinkedHashMap<>(this.attrPolicies); for (Map.Entry> e : attrPolicies.entrySet()) { - e.setValue(Maps.newLinkedHashMap(e.getValue())); + e.setValue(new LinkedHashMap<>(e.getValue())); } @SuppressWarnings("hiding") Map globalAttrPolicies - = Maps.newLinkedHashMap(this.globalAttrPolicies); + = new LinkedHashMap<>(this.globalAttrPolicies); @SuppressWarnings("hiding") - Set allowedProtocols = ImmutableSet.copyOf(this.allowedProtocols); + Set allowedProtocols = Set.copyOf(this.allowedProtocols); // Implement requireRelsOnLinks & skip... { @@ -751,9 +748,9 @@ private CompiledState compilePolicies() { if (linkPolicy != null) { RelsOnLinksPolicy relsOnLinksPolicy = RelsOnLinksPolicy.create( this.extraRelsForLinks != null - ? this.extraRelsForLinks : ImmutableSet.of(), + ? this.extraRelsForLinks : Set.of(), this.skipRelsForLinks != null - ? this.skipRelsForLinks : ImmutableSet.of()); + ? this.skipRelsForLinks : Set.of()); elPolicies.put( "a", ElementPolicy.Util.join(linkPolicy, relsOnLinksPolicy)); @@ -773,7 +770,7 @@ private CompiledState compilePolicies() { allowedProtocols); } - Set toGuard = Sets.newLinkedHashSet(ATTRIBUTE_GUARDS.keySet()); + Set toGuard = new HashSet<>(ATTRIBUTE_GUARDS.keySet()); AttributeGuardIntermediates intermediates = new AttributeGuardIntermediates( urlAttributePolicy, this.styleUrlPolicy, this.stylingPolicySchema); for (Map.Entry e : ATTRIBUTE_GUARDS.entrySet()) { @@ -801,8 +798,8 @@ private CompiledState compilePolicies() { } } - ImmutableMap.Builder policiesBuilder - = ImmutableMap.builder(); + Map policiesBuilder + = new HashMap<>(); for (Map.Entry e : elPolicies.entrySet()) { String elementName = e.getKey(); ElementPolicy elPolicy = e.getValue(); @@ -813,16 +810,16 @@ private CompiledState compilePolicies() { Map elAttrPolicies = attrPolicies.get(elementName); if (elAttrPolicies == null) { - elAttrPolicies = ImmutableMap.of(); + elAttrPolicies = Map.of(); } - ImmutableMap.Builder attrs - = ImmutableMap.builder(); + Map attrs + = new HashMap<>(); for (Map.Entry ape : elAttrPolicies.entrySet()) { String attributeName = ape.getKey(); // Handle below so we don't end up putting the same key into the map - // twice. ImmutableMap.Builder hates that. + // twice. Map.Builder hates that. if (globalAttrPolicies.containsKey(attributeName)) { continue; } AttributePolicy policy = ape.getValue(); if (!AttributePolicy.REJECT_ALL_ATTRIBUTE_POLICY.equals(policy)) { @@ -843,13 +840,13 @@ private CompiledState compilePolicies() { elementName, new ElementAndAttributePolicies( elementName, - elPolicy, attrs.build(), + elPolicy, Map.copyOf(attrs), getHtmlTagSkipType(elementName) ) ); } compiledState = new CompiledState( - globalAttrPolicies, policiesBuilder.build()); + globalAttrPolicies, Map.copyOf(policiesBuilder)); return compiledState; } @@ -877,7 +874,7 @@ public final class AttributeBuilder { private AttributePolicy policy = AttributePolicy.IDENTITY_ATTRIBUTE_POLICY; AttributeBuilder(List attributeNames) { - this.attributeNames = ImmutableList.copyOf(attributeNames); + this.attributeNames = List.copyOf(attributeNames); } /** @@ -918,7 +915,7 @@ public AttributeBuilder matching( return matching(new AttributePolicy() { public @Nullable String apply( String elementName, String attributeName, String value) { - return filter.apply(value) ? value : null; + return filter.test(value) ? value : null; } }); } @@ -931,7 +928,7 @@ public AttributeBuilder matching( */ public AttributeBuilder matching( boolean ignoreCase, String... allowedValues) { - return matching(ignoreCase, ImmutableSet.copyOf(allowedValues)); + return matching(ignoreCase, Set.of(allowedValues)); } /** @@ -942,7 +939,7 @@ public AttributeBuilder matching( */ public AttributeBuilder matching( final boolean ignoreCase, Set allowedValues) { - final ImmutableSet allowed = ImmutableSet.copyOf(allowedValues); + final Set allowed = Set.copyOf(allowedValues); return matching(new AttributePolicy() { public @Nullable String apply( String elementName, String attributeName, String uncanonValue) { @@ -982,24 +979,24 @@ public HtmlPolicyBuilder globally() { */ @SuppressWarnings("synthetic-access") public HtmlPolicyBuilder onElements(String... elementNames) { - ImmutableList.Builder b = ImmutableList.builder(); + List builder = new ArrayList<>(); for (String elementName : elementNames) { - b.add(HtmlLexer.canonicalElementName(elementName)); + builder.add(HtmlLexer.canonicalElementName(elementName)); } return HtmlPolicyBuilder.this.allowAttributesOnElements( - policy, attributeNames, b.build()); + policy, attributeNames, List.copyOf(builder)); } } private static final class RelsOnLinksPolicy implements ElementPolicy.JoinableElementPolicy { - final ImmutableSet extra; - final ImmutableSet skip; - final ImmutableSet whenTargetPresent; + final Set extra; + final Set skip; + final List whenTargetPresent; static final RelsOnLinksPolicy EMPTY = new RelsOnLinksPolicy( - ImmutableSet.of(), ImmutableSet.of()); + Set.of(), Set.of()); static RelsOnLinksPolicy create( Set extra, @@ -1011,13 +1008,13 @@ static RelsOnLinksPolicy create( RelsOnLinksPolicy( Set extra, Set skip) { - this.extra = ImmutableSet.copyOf(extra); - this.skip = ImmutableSet.copyOf(skip); - Set targetOnly = Sets.newLinkedHashSet(); + this.extra = Set.copyOf(extra); + this.skip = Set.copyOf(skip); + Set targetOnly = new HashSet<>(); targetOnly.addAll(DEFAULT_RELS_ON_TARGETTED_LINKS); targetOnly.removeAll(extra); targetOnly.removeAll(skip); - this.whenTargetPresent = ImmutableSet.copyOf(targetOnly); + this.whenTargetPresent = List.copyOf(targetOnly); } private static int indexOfAttributeValue( @@ -1105,8 +1102,8 @@ static final class JoinRelsOnLinksPolicies public JoinableElementPolicy join( Iterable toJoin) { - Set extra = Sets.newLinkedHashSet(); - Set skip = Sets.newLinkedHashSet(); + Set extra = new HashSet<>(); + Set skip = new HashSet<>(); for (JoinableElementPolicy ep : toJoin) { RelsOnLinksPolicy p = (RelsOnLinksPolicy) ep; extra.addAll(p.extra); diff --git a/src/main/java/org/owasp/html/HtmlSanitizer.java b/src/main/java/org/owasp/html/HtmlSanitizer.java index d5f8750c..2ac4ece5 100644 --- a/src/main/java/org/owasp/html/HtmlSanitizer.java +++ b/src/main/java/org/owasp/html/HtmlSanitizer.java @@ -32,8 +32,6 @@ import java.util.List; import javax.annotation.Nullable; -import com.google.common.collect.Lists; - /** * Consumes an HTML stream, and dispatches events to a policy object which * decides which elements and attributes to allow. @@ -138,7 +136,7 @@ public static void sanitize( HtmlLexer lexer = new HtmlLexer(htmlContent); // Use a linked list so that policies can use Iterator.remove() in an O(1) // way. - LinkedList attrs = Lists.newLinkedList(); + LinkedList attrs = new LinkedList<>(); while (lexer.hasNext()) { HtmlToken token = lexer.next(); switch (token.type) { diff --git a/src/main/java/org/owasp/html/HtmlStreamRenderer.java b/src/main/java/org/owasp/html/HtmlStreamRenderer.java index 9c079d1c..ffb33071 100644 --- a/src/main/java/org/owasp/html/HtmlStreamRenderer.java +++ b/src/main/java/org/owasp/html/HtmlStreamRenderer.java @@ -28,16 +28,12 @@ package org.owasp.html; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; - import java.io.Closeable; import java.io.Flushable; import java.io.IOException; -import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Set; + import javax.annotation.WillCloseWhenClosed; import javax.annotation.concurrent.NotThreadSafe; @@ -355,7 +351,7 @@ private static int checkHtmlCdataCloseable( return innerStart; } - @VisibleForTesting + // only visible for testing static boolean isValidHtmlName(String name) { int n = name.length(); if (n == 0) { return false; } diff --git a/src/main/java/org/owasp/html/HtmlTextEscapingMode.java b/src/main/java/org/owasp/html/HtmlTextEscapingMode.java index 0d47910f..3ccb5c8d 100644 --- a/src/main/java/org/owasp/html/HtmlTextEscapingMode.java +++ b/src/main/java/org/owasp/html/HtmlTextEscapingMode.java @@ -28,7 +28,7 @@ package org.owasp.html; -import com.google.common.collect.ImmutableMap; +import java.util.Map; /** * From section 8.1.2.6 of http://www.whatwg.org/specs/web-apps/current-work/ @@ -82,15 +82,15 @@ public enum HtmlTextEscapingMode { VOID, ; - private static final ImmutableMap ESCAPING_MODES - = ImmutableMap.builder() - .put("iframe", CDATA) + private static final Map ESCAPING_MODES + = Map.ofEntries( + Map.entry("iframe", CDATA), // HTML5 does not treat listing as CDATA and treats XMP as deprecated, // but HTML2 does at // http://www.w3.org/MarkUp/1995-archive/NonStandard.html // Listing is not supported by browsers. - .put("listing", CDATA_SOMETIMES) - .put("xmp", CDATA) + Map.entry("listing", CDATA_SOMETIMES), + Map.entry("xmp", CDATA), // Technically, noembed, noscript and noframes are CDATA_SOMETIMES but // we can only be hurt by allowing tag content that looks like text so @@ -98,41 +98,40 @@ public enum HtmlTextEscapingMode { //.put("noembed", CDATA_SOMETIMES) //.put("noframes", CDATA_SOMETIMES) //.put("noscript", CDATA_SOMETIMES) - .put("comment", CDATA_SOMETIMES) // IE only + Map.entry("comment", CDATA_SOMETIMES), // IE only // Runs till end of file. - .put("plaintext", PLAIN_TEXT) + Map.entry("plaintext", PLAIN_TEXT), - .put("script", CDATA) - .put("style", CDATA) + Map.entry("script", CDATA), + Map.entry("style", CDATA), // Textarea and Title are RCDATA, not CDATA, so decode entity references. - .put("textarea", RCDATA) - .put("title", RCDATA) + Map.entry("textarea", RCDATA), + Map.entry("title", RCDATA), // Nodes that can't contain content. // http://www.w3.org/TR/html-markup/syntax.html#void-elements - .put("area", VOID) - .put("base", VOID) - .put("br", VOID) - .put("col", VOID) - .put("command", VOID) - .put("embed", VOID) - .put("hr", VOID) - .put("img", VOID) - .put("input", VOID) - .put("keygen", VOID) - .put("link", VOID) - .put("meta", VOID) - .put("param", VOID) - .put("source", VOID) - .put("track", VOID) - .put("wbr", VOID) + Map.entry("area", VOID), + Map.entry("base", VOID), + Map.entry("br", VOID), + Map.entry("col", VOID), + Map.entry("command", VOID), + Map.entry("embed", VOID), + Map.entry("hr", VOID), + Map.entry("img", VOID), + Map.entry("input", VOID), + Map.entry("keygen", VOID), + Map.entry("link", VOID), + Map.entry("meta", VOID), + Map.entry("param", VOID), + Map.entry("source", VOID), + Map.entry("track", VOID), + Map.entry("wbr", VOID), // EMPTY per http://www.w3.org/TR/REC-html32#basefont - .put("basefont", VOID) - .put("isindex", VOID) - .build(); + Map.entry("basefont", VOID), + Map.entry("isindex", VOID)); /** diff --git a/src/main/java/org/owasp/html/IntVector.java b/src/main/java/org/owasp/html/IntVector.java index b48bd6f9..9195e403 100644 --- a/src/main/java/org/owasp/html/IntVector.java +++ b/src/main/java/org/owasp/html/IntVector.java @@ -1,7 +1,5 @@ package org.owasp.html; -import com.google.common.base.Preconditions; - final class IntVector { private int[] contents = ZERO_INTS; private int left, size; @@ -39,7 +37,9 @@ public void add(int value) { } public int remove(int i) { - Preconditions.checkArgument(0 <= i && i < size); + if (i < 0 || i >= size) { + throw new IllegalArgumentException("Invalid index"); + } int bufsize = contents.length; int idx = (left + i) % bufsize; int result = contents[idx]; @@ -56,7 +56,9 @@ public int remove(int i) { // They do. int itemShiftedAround = contents[0]; int right = (left + size) % bufsize; - Preconditions.checkState(right <= left); + if (right > left) { + throw new IllegalStateException(); + } System.arraycopy(contents, 1, contents, 0, right); System.arraycopy(contents, idx + 1, contents, idx, bufsize - idx - 1); contents[bufsize - 1] = itemShiftedAround; diff --git a/src/main/java/org/owasp/html/Joinable.java b/src/main/java/org/owasp/html/Joinable.java index 9348376f..1061d65f 100644 --- a/src/main/java/org/owasp/html/Joinable.java +++ b/src/main/java/org/owasp/html/Joinable.java @@ -1,15 +1,13 @@ package org.owasp.html; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.Set; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - /** * Something that can request special joining. * If two or more things have the same (per equals/hashCode) joinStrategy @@ -54,8 +52,8 @@ static abstract class JoinHelper> { T identityValue) { this.baseType = baseType; this.specialJoinableType = specialJoinableType; - this.zeroValue = Preconditions.checkNotNull(zeroValue); - this.identityValue = Preconditions.checkNotNull(identityValue); + this.zeroValue = Objects.requireNonNull(zeroValue); + this.identityValue = Objects.requireNonNull(identityValue); } abstract Optional> split(T x); @@ -76,17 +74,17 @@ void unroll(T x) { JoinStrategy strategy = sj.getJoinStrategy(); if (requireSpecialJoining == null) { - requireSpecialJoining = Maps.newLinkedHashMap(); + requireSpecialJoining = new LinkedHashMap, Set>(); } Set toJoinTogether = requireSpecialJoining.get(strategy); if (toJoinTogether == null) { - toJoinTogether = Sets.newLinkedHashSet(); + toJoinTogether = new LinkedHashSet(); requireSpecialJoining.put(strategy, toJoinTogether); } toJoinTogether.add(sj); } else { - uniq.add(Preconditions.checkNotNull(x)); + uniq.add(Objects.requireNonNull(x)); } } @@ -111,7 +109,7 @@ T join() { ? toJoin.iterator().next() : strategy.join(toJoin); - uniq.add(Preconditions.checkNotNull(baseType.cast(joined))); + uniq.add(Objects.requireNonNull(baseType.cast(joined))); } } diff --git a/src/main/java/org/owasp/html/JoinedAttributePolicy.java b/src/main/java/org/owasp/html/JoinedAttributePolicy.java index fc1b9195..4b55a958 100644 --- a/src/main/java/org/owasp/html/JoinedAttributePolicy.java +++ b/src/main/java/org/owasp/html/JoinedAttributePolicy.java @@ -28,9 +28,10 @@ package org.owasp.html; -import com.google.common.collect.ImmutableList; - import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -38,10 +39,10 @@ @Immutable final class JoinedAttributePolicy implements AttributePolicy { - final ImmutableList policies; + final List policies; - JoinedAttributePolicy(Collection policies) { - this.policies = ImmutableList.copyOf(policies); + JoinedAttributePolicy(Collection policies) { + this.policies = Collections.unmodifiableList(policies.stream().collect(Collectors.toList())); } public @Nullable String apply( diff --git a/src/main/java/org/owasp/html/PolicyFactory.java b/src/main/java/org/owasp/html/PolicyFactory.java index 1f09dba7..897ee778 100644 --- a/src/main/java/org/owasp/html/PolicyFactory.java +++ b/src/main/java/org/owasp/html/PolicyFactory.java @@ -28,17 +28,17 @@ package org.owasp.html; +import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - /** * A factory that can be used to link a sanitizer to an output receiver and that * provides a convenient {@link PolicyFactory#sanitize sanitize} @@ -53,16 +53,16 @@ public final class PolicyFactory implements Function { - private final ImmutableMap policies; - private final ImmutableMap globalAttrPolicies; - private final ImmutableSet textContainers; + private final Map policies; + private final Map globalAttrPolicies; + private final Set textContainers; private final HtmlStreamEventProcessor preprocessor; private final HtmlStreamEventProcessor postprocessor; PolicyFactory( - ImmutableMap policies, - ImmutableSet textContainers, - ImmutableMap globalAttrPolicies, + Map policies, + Set textContainers, + Map globalAttrPolicies, HtmlStreamEventProcessor preprocessor, HtmlStreamEventProcessor postprocessor) { this.policies = policies; @@ -140,8 +140,8 @@ public String sanitize( * name. */ public PolicyFactory and(PolicyFactory f) { - ImmutableMap.Builder b - = ImmutableMap.builder(); + Map builder + = new HashMap<>(); // Merge this and f into a map of element names to attribute policies. for (Map.Entry e : policies.entrySet()) { @@ -154,7 +154,7 @@ public PolicyFactory and(PolicyFactory f) { // Mix in any globals that are not already taken into account in this. p = p.andGlobals(f.globalAttrPolicies); } - b.put(elName, p); + builder.put(elName, p); } // Handle keys that are in f but not in this. for (Map.Entry e @@ -164,27 +164,27 @@ public PolicyFactory and(PolicyFactory f) { ElementAndAttributePolicies p = e.getValue(); // Mix in any globals that are not already taken into account in this. p = p.andGlobals(globalAttrPolicies); - b.put(elName, p); + builder.put(elName, p); } } - ImmutableSet allTextContainers; + Set allTextContainers; if (this.textContainers.containsAll(f.textContainers)) { allTextContainers = this.textContainers; } else if (f.textContainers.containsAll(this.textContainers)) { allTextContainers = f.textContainers; } else { - allTextContainers = ImmutableSet.builder() - .addAll(this.textContainers) - .addAll(f.textContainers) - .build(); + Set containers = new HashSet<>(); + this.textContainers.forEach(containers::add); + f.textContainers.forEach(containers::add); + allTextContainers = Set.copyOf(containers); } - ImmutableMap allGlobalAttrPolicies; + Map allGlobalAttrPolicies; if (f.globalAttrPolicies.isEmpty()) { allGlobalAttrPolicies = this.globalAttrPolicies; } else if (this.globalAttrPolicies.isEmpty()) { allGlobalAttrPolicies = f.globalAttrPolicies; } else { - ImmutableMap.Builder ab = ImmutableMap.builder(); + Map ab = new HashMap<>(); for (Map.Entry e : this.globalAttrPolicies.entrySet()) { String attrName = e.getKey(); @@ -200,7 +200,7 @@ public PolicyFactory and(PolicyFactory f) { ab.put(attrName, e.getValue()); } } - allGlobalAttrPolicies = ab.build(); + allGlobalAttrPolicies = Map.copyOf(ab); } HtmlStreamEventProcessor compositionOfPreprocessors = HtmlStreamEventProcessor.Processors.compose( @@ -209,7 +209,7 @@ public PolicyFactory and(PolicyFactory f) { = HtmlStreamEventProcessor.Processors.compose( this.postprocessor, f.postprocessor); return new PolicyFactory( - b.build(), allTextContainers, allGlobalAttrPolicies, + Map.copyOf(builder), allTextContainers, allGlobalAttrPolicies, compositionOfPreprocessors, compositionOfPostprocessors); } } diff --git a/src/main/java/org/owasp/html/StylingPolicy.java b/src/main/java/org/owasp/html/StylingPolicy.java index 370bf209..8aa5962b 100644 --- a/src/main/java/org/owasp/html/StylingPolicy.java +++ b/src/main/java/org/owasp/html/StylingPolicy.java @@ -28,17 +28,14 @@ package org.owasp.html; +import java.util.ArrayList; import java.util.List; +import java.util.function.Function; import javax.annotation.Nullable; import org.owasp.html.AttributePolicy.JoinableAttributePolicy; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.collect.Lists; - /** * An HTML sanitizer policy that tries to preserve simple CSS by white-listing * property values and splitting combo properties into multiple more specific @@ -67,7 +64,7 @@ final class StylingPolicy implements JoinableAttributePolicy { * * @return A sanitized version of the input. */ - @VisibleForTesting + //only visible for testing String sanitizeCssProperties(String style) { final StringBuilder sanitizedCss = new StringBuilder(); CssGrammar.parsePropertyGroup(style, new CssGrammar.PropertyHandler() { @@ -129,7 +126,7 @@ public void startProperty(String propertyName) { public void startFunction(String uncanonToken) { closeQuotedIdents(); - if (cssProperties == null) { cssProperties = Lists.newArrayList(); } + if (cssProperties == null) { cssProperties = new ArrayList<>(); } cssProperties.add(cssProperty); String token = Strings.toLowerCase(uncanonToken); String key = cssProperty.fnKeys.get(token); @@ -274,7 +271,7 @@ static final class StylingPolicyJoinStrategy public JoinableAttributePolicy join( Iterable toJoin) { - Function identity = Functions.identity(); + Function identity = Function.identity(); CssSchema cssSchema = null; Function urlRewriter = identity; for (JoinableAttributePolicy p : toJoin) { @@ -284,7 +281,7 @@ public JoinableAttributePolicy join( urlRewriter = urlRewriter.equals(identity) || urlRewriter.equals(sp.urlRewriter) ? sp.urlRewriter - : Functions.compose(urlRewriter, sp.urlRewriter); + : urlRewriter.compose(sp.urlRewriter); } return new StylingPolicy(cssSchema, urlRewriter); } diff --git a/src/main/java/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java b/src/main/java/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java index 6df2a286..a437baec 100644 --- a/src/main/java/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java +++ b/src/main/java/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java @@ -28,14 +28,12 @@ package org.owasp.html; +import java.util.ArrayList; import java.util.BitSet; import java.util.List; import org.owasp.html.HtmlElementTables.HtmlElementNames; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; - /** * Wraps an HTML stream event receiver to fill in missing close tags. * If the balancer is given the HTML {@code

1

2}, the wrapped receiver will @@ -125,7 +123,7 @@ private void prepareForContent(int elIndex) { // Open implied elements, such as list-items and table cells & rows. int[] impliedElIndices = METADATA.impliedElements(top, elIndex); if (impliedElIndices.length != 0) { - List attrs = Lists.newArrayList(); + List attrs = new ArrayList<>(); int startPos = 0; for (int i = 0, n = impliedElIndices.length; i < n; ++i) { @@ -183,7 +181,7 @@ && canContain(elIndex, toResume, nOpen)) { if (openElements.size() < nestingLimit) { underlying.openTag( METADATA.canonNameForIndex(toResume), - Lists.newArrayList()); + new ArrayList<>()); } openElements.add(toResume); } else { @@ -216,7 +214,9 @@ && canContain(elIndex, toResume, nOpen)) { */ private boolean canContain( int child, int container, int containerIndexOnStack) { - Preconditions.checkArgument(containerIndexOnStack >= 0); + if (containerIndexOnStack < 0) { + throw new IllegalArgumentException("negative container index"); + } if (child == HtmlElementTables.TEXT_NODE && hasSpecialTextMode(container)) { // If there's a select element on the stack, then we need to be extra careful. int selectElementIndex = METADATA.indexForName("select"); diff --git a/src/main/java/org/owasp/html/examples/EbayPolicyExample.java b/src/main/java/org/owasp/html/examples/EbayPolicyExample.java index fa20eeaf..ce5c266f 100644 --- a/src/main/java/org/owasp/html/examples/EbayPolicyExample.java +++ b/src/main/java/org/owasp/html/examples/EbayPolicyExample.java @@ -28,9 +28,13 @@ package org.owasp.html.examples; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.function.Predicate; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.owasp.html.Handler; import org.owasp.html.HtmlPolicyBuilder; @@ -38,10 +42,6 @@ import org.owasp.html.HtmlStreamRenderer; import org.owasp.html.PolicyFactory; -import com.google.common.base.Charsets; -import com.google.common.base.Predicate; -import com.google.common.io.CharStreams; - /** * Based on the * AntiSamy EBay example. @@ -208,8 +208,10 @@ public static void main(String[] args) throws IOException { } System.err.println("[Reading from STDIN]"); // Fetch the HTML to sanitize. - String html = CharStreams.toString( - new InputStreamReader(System.in, Charsets.UTF_8)); + String html = new BufferedReader( + new InputStreamReader(System.in, StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); // Set up an output channel to receive the sanitized HTML. HtmlStreamRenderer renderer = HtmlStreamRenderer.create( System.out, diff --git a/src/main/java/org/owasp/html/examples/SlashdotPolicyExample.java b/src/main/java/org/owasp/html/examples/SlashdotPolicyExample.java index d2ffd8cc..14106e0f 100644 --- a/src/main/java/org/owasp/html/examples/SlashdotPolicyExample.java +++ b/src/main/java/org/owasp/html/examples/SlashdotPolicyExample.java @@ -28,9 +28,13 @@ package org.owasp.html.examples; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.function.Function; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.owasp.html.Handler; import org.owasp.html.HtmlPolicyBuilder; @@ -38,10 +42,6 @@ import org.owasp.html.HtmlStreamEventReceiver; import org.owasp.html.HtmlStreamRenderer; -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.io.CharStreams; - /** * Based on the * AntiSamy Slashdot example. @@ -99,8 +99,10 @@ public static void main(String[] args) throws IOException { } System.err.println("[Reading from STDIN]"); // Fetch the HTML to sanitize. - String html = CharStreams.toString( - new InputStreamReader(System.in, Charsets.UTF_8)); + String html = new BufferedReader( + new InputStreamReader(System.in, StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); // Set up an output channel to receive the sanitized HTML. HtmlStreamRenderer renderer = HtmlStreamRenderer.create( System.out, diff --git a/src/main/java/org/owasp/html/examples/UrlTextExample.java b/src/main/java/org/owasp/html/examples/UrlTextExample.java index 357667bd..f9347cd0 100644 --- a/src/main/java/org/owasp/html/examples/UrlTextExample.java +++ b/src/main/java/org/owasp/html/examples/UrlTextExample.java @@ -30,16 +30,16 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.owasp.html.HtmlPolicyBuilder; +import org.owasp.html.HtmlStreamEventProcessor; import org.owasp.html.HtmlStreamEventReceiver; import org.owasp.html.HtmlStreamEventReceiverWrapper; import org.owasp.html.HtmlTextEscapingMode; import org.owasp.html.PolicyFactory; -import org.owasp.html.HtmlStreamEventProcessor; - -import com.google.common.base.Joiner; /** * Uses a custom event receiver to emit the domain of a link or inline image @@ -134,7 +134,7 @@ public HtmlStreamEventReceiver wrap(HtmlStreamEventReceiver sink) { } ).toFactory(); - out.append(policyBuilder.sanitize(Joiner.on('\n').join(inputs))); + out.append(policyBuilder.sanitize(Arrays.stream(inputs).collect(Collectors.joining("\n")))); } /** diff --git a/src/test/java/org/owasp/html/Benchmark.java b/src/test/java/org/owasp/html/Benchmark.java index bebc7da0..2a937fc6 100644 --- a/src/test/java/org/owasp/html/Benchmark.java +++ b/src/test/java/org/owasp/html/Benchmark.java @@ -30,15 +30,14 @@ import java.io.File; import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.List; import java.util.ListIterator; import org.w3c.dom.Node; import org.xml.sax.InputSource; -import com.google.common.base.Charsets; -import com.google.common.io.Files; - import nu.validator.htmlparser.dom.HtmlDocumentBuilder; /** @@ -59,7 +58,7 @@ public class Benchmark { * specifies a benchmark to run and unspecified ones are not run. */ public static void main(String[] args) throws Exception { - String html = Files.asCharSource(new File(args[0]), Charsets.UTF_8).read(); + String html = Files.readString(new File(args[0]).toPath(), StandardCharsets.UTF_8); boolean timeLibhtmlparser = true; boolean timeSanitize = true; diff --git a/src/test/java/org/owasp/html/CssFuzzerTest.java b/src/test/java/org/owasp/html/CssFuzzerTest.java index e4e58dba..71808318 100644 --- a/src/test/java/org/owasp/html/CssFuzzerTest.java +++ b/src/test/java/org/owasp/html/CssFuzzerTest.java @@ -36,8 +36,6 @@ import org.junit.Test; import org.owasp.html.CssTokens.TokenType; -import com.google.common.collect.Maps; - @SuppressWarnings("javadoc") public class CssFuzzerTest extends FuzzyTestCase { @@ -171,7 +169,7 @@ public final void testUnderStress() { } private static final EnumMap TOKEN_TYPE_FILTERS - = Maps.newEnumMap(CssTokens.TokenType.class); + = new EnumMap<>(CssTokens.TokenType.class); static { String NUMBER = "-?(?:0|[1-9][0-9]*)(?:\\.[0-9]*[1-9])?(?:e-?[1-9][0-9]*)?"; String IDENT_START = "[a-zA-Z_\\u0080-\udbff\udfff\\-]"; diff --git a/src/test/java/org/owasp/html/CssGrammarTest.java b/src/test/java/org/owasp/html/CssGrammarTest.java index f35482d0..da426cea 100644 --- a/src/test/java/org/owasp/html/CssGrammarTest.java +++ b/src/test/java/org/owasp/html/CssGrammarTest.java @@ -28,20 +28,20 @@ package org.owasp.html; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.junit.Test; -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; - import junit.framework.TestCase; @SuppressWarnings("javadoc") public class CssGrammarTest extends TestCase { @Test public static final void testLex() { - CssTokens tokens = CssTokens.lex(Joiner.on('\n').join( + CssTokens tokens = CssTokens.lex(Arrays.stream(new String[] { "/* A comment */", "words with-dashes #hashes .dots. -and-leading-dashes", "quantities: 3px 4ex -.5pt 12.5%", @@ -50,9 +50,9 @@ public static final void testLex() { "rgb(255, 127, 127)", "'strings' \"oh \\\"my\" 'foo bar'", "color:blue!important", - "")); + ""}).collect(Collectors.joining("\n"))); - List actualTokens = Lists.newArrayList(); + List actualTokens = new ArrayList<>(); for (CssTokens.TokenIterator it = tokens.iterator(); it.hasNext();) { CssTokens.TokenType type = it.type(); String token = it.next(); @@ -62,7 +62,7 @@ public static final void testLex() { } assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { // "/* A comment */", // Comments are elided. "words:IDENT", "with-dashes:IDENT", @@ -103,8 +103,8 @@ public static final void testLex() { "!:DELIM", "important:IDENT", "]:RIGHT_SQUARE" // Manufactured due to unmatched '['. - ), - Joiner.on('\n').join(actualTokens)); + }).collect(Collectors.joining("\n")), + actualTokens.stream().collect(Collectors.joining("\n"))); } @Test diff --git a/src/test/java/org/owasp/html/CssTokensTest.java b/src/test/java/org/owasp/html/CssTokensTest.java index 36e31621..7de9a58f 100644 --- a/src/test/java/org/owasp/html/CssTokensTest.java +++ b/src/test/java/org/owasp/html/CssTokensTest.java @@ -28,17 +28,23 @@ package org.owasp.html; +import static org.owasp.html.CssTokens.TokenType.COLUMN; +import static org.owasp.html.CssTokens.TokenType.IDENT; +import static org.owasp.html.CssTokens.TokenType.LEFT_PAREN; +import static org.owasp.html.CssTokens.TokenType.LEFT_SQUARE; +import static org.owasp.html.CssTokens.TokenType.RIGHT_PAREN; +import static org.owasp.html.CssTokens.TokenType.RIGHT_SQUARE; +import static org.owasp.html.CssTokens.TokenType.STRING; +import static org.owasp.html.CssTokens.TokenType.WHITESPACE; + +import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; - import org.junit.Test; import org.owasp.html.CssTokens.TokenType; -import com.google.common.collect.Lists; - -import static org.owasp.html.CssTokens.TokenType.*; +import junit.framework.TestCase; @SuppressWarnings({ "javadoc" }) public class CssTokensTest extends TestCase { @@ -58,9 +64,9 @@ public static final void testBracketIndices() { CssTokens tokens = lex("([foo[[||]])"); assertEquals("([foo[[||]]])", tokens.normalizedCss); - List tokenTexts = Lists.newArrayList(); - List types = Lists.newArrayList(); - List partners = Lists.newArrayList(); + List tokenTexts = new ArrayList<>(); + List types = new ArrayList<>(); + List partners = new ArrayList<>(); for (CssTokens.TokenIterator it = tokens.iterator(); it.hasNext();) { types.add(it.type()); partners.add(tokens.brackets.partner(it.tokenIndex())); @@ -395,7 +401,7 @@ public static final void testTokenMerging() { } private static final void assertTokens(String css, String... goldens) { - List expected = Lists.newArrayList(); + List expected = new ArrayList<>(); for (String golden : goldens) { if (" ".equals(golden)) { expected.add(" :" + WHITESPACE.name()); @@ -406,7 +412,7 @@ private static final void assertTokens(String css, String... goldens) { + CssTokens.TokenType.valueOf(golden.substring(colon+1)).name()); } } - List actual = Lists.newArrayList(); + List actual = new ArrayList<>(); for (CssTokens.TokenIterator it = lex(css).iterator(); it.hasNext(); it.advance()) { actual.add(it.token() + ":" + it.type()); @@ -419,7 +425,7 @@ private static final void assertTokens(String css, String... goldens) { } private static void assertLexedCss(String input, String... goldens) { - List actual = Lists.newArrayList(); + List actual = new ArrayList<>(); for (String token : lex(input)) { actual.add(token); } diff --git a/src/test/java/org/owasp/html/ElementPolicyTest.java b/src/test/java/org/owasp/html/ElementPolicyTest.java index 2ebe6ad8..00a4aff5 100644 --- a/src/test/java/org/owasp/html/ElementPolicyTest.java +++ b/src/test/java/org/owasp/html/ElementPolicyTest.java @@ -1,5 +1,6 @@ package org.owasp.html; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -9,9 +10,6 @@ import junit.framework.TestCase; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - import static org.owasp.html.ElementPolicy.REJECT_ALL_ELEMENT_POLICY; import static org.owasp.html.ElementPolicy.IDENTITY_ELEMENT_POLICY; import static org.owasp.html.ElementPolicy.Util.join; @@ -39,17 +37,17 @@ public String toString() { } private static void assertPassed(ElementPolicy p, String... expected) { - List attrs = Lists.newArrayList(); - ImmutableList.Builder actual = ImmutableList.builder(); + List attrs = new ArrayList<>(); + List actual = new ArrayList<>(); for (String elName : TEST_EL_NAMES) { if (p.apply(elName, attrs) != null) { actual.add(elName); } } - assertEquals(p.toString(), Arrays.asList(expected), actual.build()); + assertEquals(p.toString(), Arrays.asList(expected), actual); } - private static List TEST_EL_NAMES = ImmutableList.of( + private static List TEST_EL_NAMES = List.of( "abacus", "abracadabra", "bar", "foo", "far", "cadr", "cdr"); @Test diff --git a/src/test/java/org/owasp/html/HtmlLexerTest.java b/src/test/java/org/owasp/html/HtmlLexerTest.java index fedf90d0..d2a680df 100644 --- a/src/test/java/org/owasp/html/HtmlLexerTest.java +++ b/src/test/java/org/owasp/html/HtmlLexerTest.java @@ -28,16 +28,16 @@ package org.owasp.html; -import junit.framework.TestCase; - +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; -import com.google.common.base.Charsets; -import com.google.common.collect.Lists; -import com.google.common.io.Resources; +import junit.framework.TestCase; @SuppressWarnings("javadoc") public class HtmlLexerTest extends TestCase { @@ -45,16 +45,12 @@ public class HtmlLexerTest extends TestCase { @Test public final void testHtmlLexer() throws Exception { // Do the lexing. - String input = Resources.toString( - Resources.getResource(getClass(), "htmllexerinput1.html"), - Charsets.UTF_8); + String input = new String(Files.readString(Paths.get(getClass().getResource("htmllexerinput1.html").toURI()), StandardCharsets.UTF_8)); StringBuilder actual = new StringBuilder(); lex(input, actual); // Get the golden. - String golden = Resources.toString( - Resources.getResource(getClass(), "htmllexergolden1.txt"), - Charsets.UTF_8); + String golden = new String(Files.readString(Paths.get(getClass().getResource("htmllexergolden1.txt").toURI()), StandardCharsets.UTF_8)); // Compare. assertEquals(golden, actual.toString()); @@ -147,7 +143,7 @@ private static void lex(String input, Appendable out) throws Exception { private static void assertTokens(String markup, String... golden) { HtmlLexer lexer = new HtmlLexer(markup); - List actual = Lists.newArrayList(); + List actual = new ArrayList<>(); while (lexer.hasNext()) { HtmlToken t = lexer.next(); actual.add(t.type + ": " + markup.substring(t.start, t.end)); diff --git a/src/test/java/org/owasp/html/HtmlPolicyBuilderFuzzerTest.java b/src/test/java/org/owasp/html/HtmlPolicyBuilderFuzzerTest.java index 87663266..e603a7a4 100644 --- a/src/test/java/org/owasp/html/HtmlPolicyBuilderFuzzerTest.java +++ b/src/test/java/org/owasp/html/HtmlPolicyBuilderFuzzerTest.java @@ -28,13 +28,12 @@ package org.owasp.html; -import com.google.common.base.Function; -import com.google.common.collect.Lists; - import java.io.IOException; import java.io.StringReader; +import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.function.Function; import org.w3c.dom.Attr; import org.w3c.dom.NamedNodeMap; @@ -93,7 +92,7 @@ public final void testFuzzedOutput() throws IOException, SAXException { HtmlSanitizer.Policy policy = policyFactory.apply( HtmlStreamRenderer.create(sb, Handler.DO_NOTHING)); policy.openDocument(); - List attributes = Lists.newArrayList(); + List attributes = new ArrayList<>(); for (int j = 50; --j >= 0;) { int r = rnd.nextInt(3); switch (r) { diff --git a/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java b/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java index b399e80d..f9d4f07b 100644 --- a/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java +++ b/src/test/java/org/owasp/html/HtmlPolicyBuilderTest.java @@ -28,21 +28,21 @@ package org.owasp.html; +import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.junit.Test; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableSet; - import junit.framework.TestCase; @SuppressWarnings("javadoc") public class HtmlPolicyBuilderTest extends TestCase { - static final String EXAMPLE = Joiner.on('\n').join( + static final String EXAMPLE = Arrays.stream(new String[] { "

Header

", "

Paragraph 1

", ("

Click me" @@ -54,12 +54,12 @@ public class HtmlPolicyBuilderTest extends TestCase { " /* direction: ltr */; font-weight: bold'>Stylish Para 1

", "

Stylish Para 2

", - ""); + ""}).collect(Collectors.joining("\n")); @Test public static final void testTextFilter() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -67,14 +67,14 @@ public static final void testTextFilter() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder())); } @Test public static final void testCannedFormattingTagFilter() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -82,7 +82,7 @@ public static final void testCannedFormattingTagFilter() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowCommonInlineFormattingElements())); } @@ -90,7 +90,7 @@ public static final void testCannedFormattingTagFilter() { @Test public static final void testCannedFormattingTagFilterNoItalics() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -98,7 +98,7 @@ public static final void testCannedFormattingTagFilterNoItalics() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowCommonInlineFormattingElements() .disallowElements("I"))); @@ -107,7 +107,7 @@ public static final void testCannedFormattingTagFilterNoItalics() { @Test public static final void testSimpleTagFilter() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "

Header

", "Paragraph 1", "Click me out", @@ -115,7 +115,7 @@ public static final void testSimpleTagFilter() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("h1", "i"))); } @@ -123,7 +123,7 @@ public static final void testSimpleTagFilter() { @Test public static final void testLinksAllowed() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", // We haven't allowed any protocols so only relative URLs are OK. @@ -132,7 +132,7 @@ public static final void testLinksAllowed() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("a") .allowAttributes("href").onElements("a"))); @@ -141,7 +141,7 @@ public static final void testLinksAllowed() { @Test public static final void testExternalLinksAllowed() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me" @@ -150,7 +150,7 @@ public static final void testExternalLinksAllowed() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("a") // Allows http. @@ -161,7 +161,7 @@ public static final void testExternalLinksAllowed() { @Test public static final void testLinksWithNofollow() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -169,7 +169,7 @@ public static final void testLinksWithNofollow() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("a") // Allows http. @@ -192,7 +192,7 @@ public static final void testLinksWithNofollowAlreadyPresent() { @Test public static final void testImagesAllowed() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -201,7 +201,7 @@ public static final void testImagesAllowed() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("img") .allowAttributes("src", "alt").onElements("img") @@ -211,7 +211,7 @@ public static final void testImagesAllowed() { @Test public static final void testStyleFiltering() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "

Header

", "

Paragraph 1

", "

Click me out

", @@ -221,7 +221,7 @@ public static final void testStyleFiltering() { + "Stylish Para 1

"), ("

" + "Stylish Para 2

"), - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowCommonInlineFormattingElements() .allowCommonBlockElements() @@ -232,7 +232,7 @@ public static final void testStyleFiltering() { @Test public static final void testElementTransforming() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "
Header
", "

Paragraph 1

", "

Click me out

", @@ -240,7 +240,7 @@ public static final void testElementTransforming() { "

Fancy with soupy tags.", "

Stylish Para 1

", "

Stylish Para 2

", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("h1", "p", "div") .allowElements( @@ -273,7 +273,7 @@ public String apply(String elementName, List attrs) { @Test public static final void testAllowUrlProtocols() { assertEquals( - Joiner.on('\n').join( + Arrays.stream(new String[] { "Header", "Paragraph 1", "Click me out", @@ -282,7 +282,7 @@ public static final void testAllowUrlProtocols() { "Fancy with soupy tags.", "Stylish Para 1", "Stylish Para 2", - ""), + ""}).collect(Collectors.joining("\n")), apply(new HtmlPolicyBuilder() .allowElements("img") .allowAttributes("src", "alt").onElements("img") @@ -807,14 +807,14 @@ public static final void testFailFastOnSpaceSeparatedStrings() { // Should be ("nofollow", "noreferrer") new HtmlPolicyBuilder().requireRelsOnLinks("nofollow noreferrer"); failed = false; - } catch (@SuppressWarnings("unused") IllegalArgumentException ex) { + } catch (@SuppressWarnings("unused") IllegalArgumentException ex) { failed = true; } assertTrue(failed); try { new HtmlPolicyBuilder().skipRelsOnLinks("nofollow noreferrer"); failed = false; - } catch (@SuppressWarnings("unused") IllegalArgumentException ex) { + } catch (@SuppressWarnings("unused") IllegalArgumentException ex) { failed = true; } assertTrue(failed); @@ -919,7 +919,7 @@ public String apply(String elementName, List attrs) { // allow contents in this script tag .allowTextIn("script") // keep type attribute in application/json script tag - .allowAttributes("type").matching(true, ImmutableSet.of("application/json")).onElements("script") + .allowAttributes("type").matching(true, Set.of("application/json")).onElements("script") .toFactory(); String mismatchedHtmlComments = "')"); renderer.closeTag("script"); renderer.closeDocument(); @@ -155,13 +154,13 @@ public final void testCdataContainsEndTag1() throws Exception { "", rendered.toString()); assertEquals( "Invalid CDATA text content : '", - Joiner.on('\n').join(errors)); + errors.stream().collect(Collectors.joining("\n"))); errors.clear(); } public final void testCdataContainsEndTag2() throws Exception { renderer.openDocument(); - renderer.openTag("style", ImmutableList.of("type", "text/css")); + renderer.openTag("style", List.of("type", "text/css")); renderer.text("/* */"); @@ -172,13 +171,13 @@ public final void testCdataContainsEndTag2() throws Exception { "", rendered.toString()); assertEquals( "Invalid CDATA text content : *", - Joiner.on('\n').join(errors)); + errors.stream().collect(Collectors.joining("\n"))); errors.clear(); } public final void testRcdataContainsEndTag() throws Exception { renderer.openDocument(); - renderer.openTag("textarea", ImmutableList.of()); + renderer.openTag("textarea", List.of()); renderer.text(""); renderer.closeTag("textarea"); renderer.closeDocument(); @@ -194,7 +193,7 @@ public final void testEndTagInsideScriptBodyInner() throws Exception { ""); assertEquals( "Invalid CDATA text content : ')"); renderer.closeTag("script"); renderer.closeDocument(); @@ -368,13 +367,13 @@ public final void testUnclosedEscapingTextSpan() throws Exception { assertEquals("", rendered.toString()); assertEquals( "Invalid CDATA text content : '", - Joiner.on('\n').join(errors)); + errors.stream().collect(Collectors.joining("\n"))); errors.clear(); } public final void testAlmostCompleteEndTag() throws Exception { renderer.openDocument(); - renderer.openTag("script", ImmutableList.of()); + renderer.openTag("script", List.of()); renderer.text("//of()); + renderer.openTag("noscript", List.of()); renderer.text(""); renderer.closeTag("noscript"); renderer.closeDocument(); @@ -396,10 +395,10 @@ public final void testBalancedCommentInNoscript() throws Exception { public final void testUnbalancedCommentInNoscript() throws Exception { renderer.openDocument(); - renderer.openTag("noscript", ImmutableList.of()); + renderer.openTag("noscript", List.of()); renderer.text(""); renderer.closeTag("noscript"); renderer.closeDocument(); @@ -423,7 +422,7 @@ public final void testSupplementaryCodepoints() throws Exception { public final void testPreSubstitutes1() throws Exception { renderer.openDocument(); - renderer.openTag("Xmp", ImmutableList.of()); + renderer.openTag("Xmp", List.of()); renderer.text("
Hello, World
"); renderer.closeTag("Xmp"); renderer.closeDocument(); @@ -434,7 +433,7 @@ public final void testPreSubstitutes1() throws Exception { public final void testPreSubstitutes2() throws Exception { renderer.openDocument(); - renderer.openTag("xmp", ImmutableList.of()); + renderer.openTag("xmp", List.of()); renderer.text("
Hello, World
"); renderer.closeTag("xmp"); renderer.closeDocument(); @@ -445,7 +444,7 @@ public final void testPreSubstitutes2() throws Exception { public final void testPreSubstitutes3() throws Exception { renderer.openDocument(); - renderer.openTag("LISTING", ImmutableList.of()); + renderer.openTag("LISTING", List.of()); renderer.text("
Hello, World
"); renderer.closeTag("LISTING"); renderer.closeDocument(); @@ -456,7 +455,7 @@ public final void testPreSubstitutes3() throws Exception { public final void testPreSubstitutes4() throws Exception { renderer.openDocument(); - renderer.openTag("plaintext", ImmutableList.of()); + renderer.openTag("plaintext", List.of()); renderer.text("
Hello, World
"); renderer.closeDocument(); diff --git a/src/test/java/org/owasp/html/PolicyFactoryTest.java b/src/test/java/org/owasp/html/PolicyFactoryTest.java index 6d4f3e97..b5ab8e5b 100644 --- a/src/test/java/org/owasp/html/PolicyFactoryTest.java +++ b/src/test/java/org/owasp/html/PolicyFactoryTest.java @@ -32,11 +32,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.junit.Test; -import com.google.common.base.Joiner; - import junit.framework.TestCase; @SuppressWarnings({ "javadoc" }) @@ -619,7 +618,7 @@ public String apply( outParts.add(part); } } - return Joiner.on(" , ").join(outParts); + return outParts.stream().collect(Collectors.joining(" , ")); } } } \ No newline at end of file diff --git a/src/test/java/org/owasp/html/SanitizersTest.java b/src/test/java/org/owasp/html/SanitizersTest.java index 4cb7bbca..66f0d661 100644 --- a/src/test/java/org/owasp/html/SanitizersTest.java +++ b/src/test/java/org/owasp/html/SanitizersTest.java @@ -30,6 +30,8 @@ import org.junit.Test; +import java.util.ArrayList; +import java.util.Arrays; import java.util.BitSet; import java.util.Iterator; import java.util.List; @@ -37,9 +39,6 @@ import junit.framework.TestCase; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - @SuppressWarnings("javadoc") public class SanitizersTest extends TestCase { @@ -516,7 +515,7 @@ static int fac(int n) { * elements are assumed distinct. */ private static class Permutations implements Iterable> { - final ImmutableList elements; + final List elements; /** Permutation size. */ final int k; @@ -526,7 +525,9 @@ private static class Permutations implements Iterable> { Permutations(int k, @SuppressWarnings("unchecked") T... elements) { this.k = k; - this.elements = ImmutableList.copyOf(elements); + List builder = new ArrayList<>(); + Arrays.stream(elements).forEach(builder::add); + this.elements = List.copyOf(builder); } public Iterator> iterator() { @@ -559,7 +560,7 @@ public List next() { private void fill() { if (pending != null || i == limit) { return; } - List permutation = Lists.newArrayListWithCapacity(k); + List permutation = new ArrayList<>(k); mask.clear(); for (int j = 0, p = i; j < k; ++j) { diff --git a/src/test/java/org/owasp/html/StylingPolicyTest.java b/src/test/java/org/owasp/html/StylingPolicyTest.java index 89d68f92..f9e5e4b2 100644 --- a/src/test/java/org/owasp/html/StylingPolicyTest.java +++ b/src/test/java/org/owasp/html/StylingPolicyTest.java @@ -28,12 +28,12 @@ package org.owasp.html; +import java.util.function.Function; + import javax.annotation.Nullable; import org.junit.Test; -import com.google.common.base.Function; - import junit.framework.TestCase; @SuppressWarnings("javadoc") diff --git a/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java b/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java index 38a854ef..7a48d6ce 100644 --- a/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java +++ b/src/test/java/org/owasp/html/TagBalancingHtmlStreamRendererTest.java @@ -28,16 +28,16 @@ package org.owasp.html; -import com.google.common.collect.ImmutableList; +import static org.owasp.html.TagBalancingHtmlStreamEventReceiver + .isInterElementWhitespace; -import junit.framework.TestCase; +import java.util.List; -import org.junit.Test; import org.junit.Before; import org.junit.Ignore; +import org.junit.Test; -import static org.owasp.html.TagBalancingHtmlStreamEventReceiver - .isInterElementWhitespace; +import junit.framework.TestCase; @SuppressWarnings("javadoc") @@ -60,17 +60,17 @@ public void handle(String x) { @Test public final void testTagBalancing() { balancer.openDocument(); - balancer.openTag("html", ImmutableList.of()); - balancer.openTag("head", ImmutableList.of()); - balancer.openTag("title", ImmutableList.of()); + balancer.openTag("html", List.of()); + balancer.openTag("head", List.of()); + balancer.openTag("title", List.of()); balancer.text("Hello, <>!"); // TITLE closed with case-sensitively different name. balancer.closeTag("TITLE"); balancer.closeTag("head"); - balancer.openTag("body", ImmutableList.of()); - balancer.openTag("p", ImmutableList.of("id", "p'0")); + balancer.openTag("body", List.of()); + balancer.openTag("p", List.of("id", "p'0")); balancer.text("Hello,"); - balancer.openTag("Br", ImmutableList.of()); + balancer.openTag("Br", List.of()); balancer.text("<>!"); // HTML, P, and BODY unclosed, but BR not. balancer.closeDocument(); @@ -85,9 +85,9 @@ public final void testTagBalancing() { @Test public final void testTagSoupIronedOut() { balancer.openDocument(); - balancer.openTag("i", ImmutableList.of()); + balancer.openTag("i", List.of()); balancer.text("x"); - balancer.openTag("b", ImmutableList.of()); + balancer.openTag("b", List.of()); balancer.text("y"); balancer.closeTag("i"); balancer.text("z"); @@ -101,12 +101,12 @@ public final void testTagSoupIronedOut() { @Test public final void testListInListDirectly() { balancer.openDocument(); - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); balancer.text("foo"); balancer.closeTag("li"); - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); balancer.text("bar"); balancer.closeTag("li"); balancer.closeTag("ul"); @@ -121,28 +121,28 @@ public final void testListInListDirectly() { @Test public final void testTextContent() { balancer.openDocument(); - balancer.openTag("title", ImmutableList.of()); + balancer.openTag("title", List.of()); balancer.text("Hello, World!"); balancer.closeTag("title"); balancer.text("Hello, "); - balancer.openTag("b", ImmutableList.of()); + balancer.openTag("b", List.of()); balancer.text("World!"); balancer.closeTag("b"); - balancer.openTag("p", ImmutableList.of()); + balancer.openTag("p", List.of()); balancer.text("Hello, "); - balancer.openTag("textarea", ImmutableList.of()); + balancer.openTag("textarea", List.of()); balancer.text("World!"); balancer.closeTag("textarea"); balancer.closeTag("p"); - balancer.openTag("h1", ImmutableList.of()); + balancer.openTag("h1", List.of()); balancer.text("Hello"); - balancer.openTag("style", ImmutableList.of("type", "text/css")); + balancer.openTag("style", List.of("type", "text/css")); balancer.text("\n.World {\n color: blue\n}\n"); balancer.closeTag("style"); balancer.closeTag("h1"); - balancer.openTag("ul", ImmutableList.of()); + balancer.openTag("ul", List.of()); balancer.text("\n "); - balancer.openTag("li", ImmutableList.of()); + balancer.openTag("li", List.of()); balancer.text("Hello,"); balancer.closeTag("li"); balancer.text("\n "); @@ -170,20 +170,20 @@ public final void testTextContent() { @Test public final void testMismatchedHeaders() { balancer.openDocument(); - balancer.openTag("H1", ImmutableList.of()); + balancer.openTag("H1", List.of()); balancer.text("header"); balancer.closeTag("h1"); balancer.text("body"); - balancer.openTag("H2", ImmutableList.of()); + balancer.openTag("H2", List.of()); balancer.text("sub-header"); balancer.closeTag("h3"); balancer.text("sub-body"); - balancer.openTag("h3", ImmutableList.of()); + balancer.openTag("h3", List.of()); balancer.text("sub-sub-"); balancer.closeTag("hr"); // hr is not a header tag so does not close an h3. balancer.text("header"); //

is not allowed in h3. - balancer.openTag("h3", ImmutableList.of()); + balancer.openTag("h3", List.of()); balancer.closeTag("h3"); balancer.text("sub-sub-body"); balancer.closeTag("H4"); @@ -201,10 +201,10 @@ public final void testMismatchedHeaders() { @Test public final void testListNesting() { balancer.openDocument(); - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); balancer.text("foo"); balancer.closeTag("li"); // Does not closes the second
    since only and
can close a @@ -212,8 +212,8 @@ public final void testListNesting() { // tree building algo. balancer.closeTag("li"); // This would append inside a list, not an item. We insert an
  • . - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); balancer.text("bar"); balancer.closeDocument(); @@ -225,18 +225,18 @@ public final void testListNesting() { @Test public final void testTableNesting() { balancer.openDocument(); - balancer.openTag("table", ImmutableList.of()); - balancer.openTag("tbody", ImmutableList.of()); - balancer.openTag("tr", ImmutableList.of()); - balancer.openTag("td", ImmutableList.of()); + balancer.openTag("table", List.of()); + balancer.openTag("tbody", List.of()); + balancer.openTag("tr", List.of()); + balancer.openTag("td", List.of()); balancer.text("foo"); balancer.closeTag("td"); // Chrome does not insert a td to contain this mis-nested table. // Instead, it ends one table and starts another. - balancer.openTag("table", ImmutableList.of()); - balancer.openTag("tbody", ImmutableList.of()); - balancer.openTag("tr", ImmutableList.of()); - balancer.openTag("th", ImmutableList.of()); + balancer.openTag("table", List.of()); + balancer.openTag("tbody", List.of()); + balancer.openTag("tr", List.of()); + balancer.openTag("th", List.of()); balancer.text("bar"); balancer.closeTag("table"); balancer.closeTag("table"); @@ -257,7 +257,7 @@ public final void testNestingLimits() { balancer.setNestingLimit(10); balancer.openDocument(); - ImmutableList attrs = ImmutableList.of(); + List attrs = List.of(); for (int i = 20000; --i >= 0;) { balancer.openTag("div", attrs); } @@ -273,29 +273,29 @@ public final void testNestingLimits() { public final void testTablesGuarded() { // Derived from issue 12. balancer.openDocument(); - balancer.openTag("html", ImmutableList.of()); - balancer.openTag("head", ImmutableList.of()); - balancer.openTag("meta", ImmutableList.of()); + balancer.openTag("html", List.of()); + balancer.openTag("head", List.of()); + balancer.openTag("meta", List.of()); balancer.closeTag("head"); - balancer.openTag("body", ImmutableList.of()); - balancer.openTag("p", ImmutableList.of()); + balancer.openTag("body", List.of()); + balancer.openTag("p", List.of()); balancer.text("Hi"); balancer.closeTag("p"); - balancer.openTag("p", ImmutableList.of()); + balancer.openTag("p", List.of()); balancer.text("How are you"); balancer.closeTag("p"); balancer.text("\n"); - balancer.openTag("ul", ImmutableList.of()); - balancer.openTag("li", ImmutableList.of()); - balancer.openTag("table", ImmutableList.of()); - balancer.openTag("tbody", ImmutableList.of()); - balancer.openTag("tr", ImmutableList.of()); + balancer.openTag("ul", List.of()); + balancer.openTag("li", List.of()); + balancer.openTag("table", List.of()); + balancer.openTag("tbody", List.of()); + balancer.openTag("tr", List.of()); for (int i = 2; --i >= 0;) { - balancer.openTag("td", ImmutableList.of()); - balancer.openTag("b", ImmutableList.of()); - balancer.openTag("font", ImmutableList.of()); - balancer.openTag("font", ImmutableList.of()); - balancer.openTag("p", ImmutableList.of()); + balancer.openTag("td", List.of()); + balancer.openTag("b", List.of()); + balancer.openTag("font", List.of()); + balancer.openTag("font", List.of()); + balancer.openTag("p", List.of()); balancer.text("Cell"); balancer.closeTag("p"); balancer.closeTag("font"); @@ -309,7 +309,7 @@ public final void testTablesGuarded() { balancer.closeTag("table"); balancer.closeTag("ul"); balancer.text("\n"); - balancer.openTag("p", ImmutableList.of()); + balancer.openTag("p", List.of()); balancer.text("x"); balancer.closeTag("p"); balancer.closeTag("body"); @@ -348,11 +348,11 @@ public static final void testIsInterElementWhitespace() { @Test public final void testAnchorTransparentToBlock() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.text("..."); balancer.closeTag("div"); balancer.closeTag("a"); @@ -367,11 +367,11 @@ public final void testAnchorTransparentToBlock() { @Test public final void testAnchorTransparentToSpans() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("span", ImmutableList.of()); + balancer.openTag("span", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("span", ImmutableList.of()); + balancer.openTag("span", List.of()); balancer.text("..."); balancer.closeTag("span"); balancer.closeTag("a"); @@ -386,11 +386,11 @@ public final void testAnchorTransparentToSpans() { @Test public final void testAnchorWithInlineInBlock() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("span", ImmutableList.of()); + balancer.openTag("span", List.of()); balancer.text("..."); balancer.closeTag("span"); balancer.closeTag("a"); @@ -404,9 +404,9 @@ public final void testAnchorWithInlineInBlock() { @Test public final void testDirectlyNestedAnchor() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("span", ImmutableList.of()); + balancer.openTag("span", List.of()); balancer.openTag("a", hrefOnly); balancer.openTag("a", hrefOnly); balancer.text("..."); @@ -423,11 +423,11 @@ public final void testDirectlyNestedAnchor() { @Test public final void testAnchorClosedWhenBlockInInline() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("span", ImmutableList.of()); + balancer.openTag("span", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.text("..."); balancer.closeTag("div"); balancer.closeTag("a"); @@ -446,11 +446,11 @@ public final void testAnchorClosedWhenBlockInInline() { @Test @Ignore public final void failingtestAnchorInAnchorIndirectly() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.openTag("a", hrefOnly); balancer.text("..."); balancer.closeTag("a"); @@ -466,12 +466,12 @@ public final void failingtestAnchorInAnchorIndirectly() { @Test public final void testInteractiveInAnchorIndirectly() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.openTag("a", hrefOnly); - balancer.openTag("div", ImmutableList.of()); - balancer.openTag("video", ImmutableList.of()); + balancer.openTag("div", List.of()); + balancer.openTag("video", List.of()); balancer.closeTag("video"); balancer.closeTag("div"); balancer.closeTag("a"); @@ -484,10 +484,10 @@ public final void testInteractiveInAnchorIndirectly() { @Test public final void testAnchorWithBlockAtTopLevel() { - ImmutableList hrefOnly = ImmutableList.of("href", ""); + List hrefOnly = List.of("href", ""); balancer.openDocument(); balancer.openTag("a", hrefOnly); - balancer.openTag("div", ImmutableList.of()); + balancer.openTag("div", List.of()); balancer.text("..."); balancer.closeTag("div"); balancer.closeTag("a"); @@ -500,11 +500,11 @@ public final void testAnchorWithBlockAtTopLevel() { @Test public final void testResumedElementsAllowedWhereResumed() { balancer.openDocument(); - balancer.openTag("a", ImmutableList.of()); - balancer.openTag("b", ImmutableList.of()); + balancer.openTag("a", List.of()); + balancer.openTag("b", List.of()); balancer.text("foo"); - balancer.openTag("i", ImmutableList.of()); - balancer.openTag("a", ImmutableList.of()); + balancer.openTag("i", List.of()); + balancer.openTag("a", List.of()); balancer.text("bar"); balancer.closeTag("a"); balancer.closeTag("i"); @@ -520,11 +520,11 @@ public final void testResumedElementsAllowedWhereResumed() { public final void testMenuItemNesting() { // issue 96 balancer.openDocument(); - balancer.openTag("div", ImmutableList.of()); - balancer.openTag("menu", ImmutableList.of()); - balancer.openTag("menuitem", ImmutableList.of()); + balancer.openTag("div", List.of()); + balancer.openTag("menu", List.of()); + balancer.openTag("menuitem", List.of()); balancer.closeTag("menuitem"); - balancer.openTag("menuitem", ImmutableList.of()); + balancer.openTag("menuitem", List.of()); balancer.closeTag("menuitem"); balancer.closeTag("menu"); balancer.closeTag("div");