Skip to content

Commit

Permalink
Merge branch 'main' into guava-migration-do-less
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesamuel committed Feb 2, 2024
2 parents 67890ce + e8aa0f1 commit cea5a2c
Show file tree
Hide file tree
Showing 16 changed files with 338 additions and 21 deletions.
13 changes: 13 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/COPYING text
/src/test/resources/org/owasp/html/* text eol=lf
.gitattributes text
.gitignore text
*.html text
*.java text
*.js text
*.json text
*.md text
*.sh text
*.txt text
*.xml text
*.yml text
43 changes: 43 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

name: Java CI with Maven

on:
push:
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/maven.yml'
pull_request:
paths-ignore:
- '.github/workflows/*.yml'
- '!.github/workflows/maven.yml'

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
java: [ '11', '17', '21' ]

steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.Java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.Java }}
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn --batch-mode --errors --fail-at-end --show-version --update-snapshots verify
- name: Store artifact
if: ${{ matrix.Java == 11 }}
uses: actions/upload-artifact@v4
with:
name: jar-jdk${{ matrix.Java }}
path: target/*.jar
retention-days: 7
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A fast and easy to configure HTML Sanitizer written in Java which lets
you include HTML authored by third-parties in your web application while
protecting against XSS.

The existing dependencies are on guava and JSR 305. The other jars
The existing dependency is on JSR 305. The other jars
are only needed by the test suite. The JSR 305 dependency is a
compile-only dependency, only needed for annotations.

Expand Down
1 change: 0 additions & 1 deletion RELEASE-checklist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ set -e


# Make sure the build is ok via
mvn -Dguava.version=27.0-jre -f aggregate clean verify javadoc:jar source:jar
mvn -f aggregate clean verify jacoco:report site javadoc:jar source:jar
mvn install
mvn org.sonatype.ossindex.maven:ossindex-maven-plugin:audit -f aggregate
Expand Down
5 changes: 2 additions & 3 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

If you are using Maven then follow the [maven](maven.md) directions to
add a dependency. Otherwise,
[download prebuilt jars](https://search.maven.org/#artifactdetails%7Ccom.googlecode.owasp-java-html-sanitizer%7Cowasp-java-html-sanitizer%7C20180219.1%7Cjar)
[download prebuilt jars](https://search.maven.org/artifact/com.googlecode.owasp-java-html-sanitizer/owasp-java-html-sanitizer/)
or `git clone [email protected]:OWASP/java-html-sanitizer.git` and build
the latest source.

Unless maven is managing your CLASSPATH for you, you need to add both `owasp-java-html-sanitizer.jar` and the
Guava JAR.
Unless maven is managing your CLASSPATH for you, you need to add `owasp-java-html-sanitizer.jar`.

Once you have your CLASSPATH set up correctly with the relevant JARs
you should be able to add
Expand Down
2 changes: 1 addition & 1 deletion parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ application while protecting against XSS.
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.9.1</version>
<version>3.16.3</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/owasp/html/Encoding.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public final class Encoding {
* @return text/plain
* @deprecated specify whether s is in an attribute value
*/
@Deprecated
public static String decodeHtml(String s) {
return decodeHtml(s, false);
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/owasp/html/HtmlEntities.java
Original file line number Diff line number Diff line change
Expand Up @@ -2309,6 +2309,7 @@ final class HtmlEntities {
* @return The offset after the end of the decoded sequence in {@code html}.
* @deprecated specify whether html is in an attribute value.
*/
@Deprecated
public static int appendDecodedEntity(
String html, int offset, int limit, StringBuilder sb) {
return appendDecodedEntity(html, offset, limit, false, sb);
Expand Down
26 changes: 17 additions & 9 deletions src/main/java/org/owasp/html/HtmlPolicyBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
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;
Expand Down Expand Up @@ -966,12 +965,11 @@ public AttributeBuilder matching(
*/
@SuppressWarnings("synthetic-access")
public HtmlPolicyBuilder globally() {
if(attributeNames.get(0).equals("style")) {
return allowStyling();
} else {
return HtmlPolicyBuilder.this.allowAttributesGlobally(
policy, attributeNames);
if (attributeNames.contains("style")) {
allowStyling();
}
return HtmlPolicyBuilder.this.allowAttributesGlobally(
policy, attributeNames);
}

/**
Expand Down Expand Up @@ -1040,6 +1038,7 @@ public String apply(String elementName, List<String> attrs) {
relValue = DEFAULT_RELS_ON_TARGETTED_LINKS_STR;
} else {
StringBuilder sb = new StringBuilder();
Set<String> present = new HashSet<String>();
if (relIndex >= 0) {
// Preserve values that are not explicitly skipped.
String rels = attrs.get(relIndex);
Expand All @@ -1050,25 +1049,34 @@ public String apply(String elementName, List<String> attrs) {
if (skip.isEmpty()
|| !skip.contains(
Strings.toLowerCase(rels.substring(left, i)))) {
sb.append(rels, left, i).append(' ');
String rel = rels.substring(left, i);
present.add(rel);
sb.append(rel).append(' ');
}
}
left = i + 1;
}
}
}
for (String s : extra) {
sb.append(s).append(' ');
if (!present.contains(s)) {
sb.append(s).append(' ');
present.add(s);
}
}
if (hasTarget) {
for (String s : whenTargetPresent) {
sb.append(s).append(' ');
if (!present.contains(s)) {
sb.append(s).append(' ');
present.add(s);
}
}
}
int sblen = sb.length();
if (sblen == 0) {
relValue = "";
} else {
// Trim last space.
relValue = sb.substring(0, sb.length() - 1);
}
}
Expand Down
29 changes: 28 additions & 1 deletion src/main/java/org/owasp/html/HtmlStreamRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.WillCloseWhenClosed;
import javax.annotation.concurrent.NotThreadSafe;
Expand All @@ -57,6 +58,8 @@ public class HtmlStreamRenderer implements HtmlStreamEventReceiver {
private StringBuilder pendingUnescaped;
private HtmlTextEscapingMode escapingMode = HtmlTextEscapingMode.PCDATA;
private boolean open;
/** The count of {@link #foreignContentRootElementNames} opened and not subsequently closed. */
private int foreignContentDepth = 0;

/**
* Factory.
Expand Down Expand Up @@ -168,7 +171,25 @@ private void writeOpenTag(
return;
}

escapingMode = HtmlTextEscapingMode.getModeForTag(elementName);
if (foreignContentRootElementNames.contains(elementName)) {
foreignContentDepth += 1;
}

HtmlTextEscapingMode tentativeEscapingMode = HtmlTextEscapingMode.getModeForTag(elementName);
if (foreignContentDepth == 0) {
escapingMode = tentativeEscapingMode;
} else {
switch (tentativeEscapingMode) {
case PCDATA:
case VOID:
escapingMode = tentativeEscapingMode;
break;
default: // escape special characters but do not allow tags
escapingMode = HtmlTextEscapingMode.RCDATA;
break;
}
}


switch (escapingMode) {
case CDATA_SOMETIMES:
Expand Down Expand Up @@ -240,6 +261,10 @@ private final void writeCloseTag(String uncanonElementName)
return;
}

if (foreignContentDepth != 0 && foreignContentRootElementNames.contains(elementName)) {
foreignContentDepth -= 1;
}

if (pendingUnescaped != null) {
if (!lastTagOpened.equals(elementName)) {
error("Tag content cannot appear inside CDATA element", elementName);
Expand Down Expand Up @@ -436,4 +461,6 @@ public void close() throws IOException {
private static boolean isTagEnd(char ch) {
return ch < 63 && 0 != (TAG_ENDS & (1L << ch));
}

private static final Set<String> foreignContentRootElementNames = Set.of("svg", "math");
}
2 changes: 1 addition & 1 deletion src/test/java/org/owasp/html/Benchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,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.readString(new File(args[0]).toPath(), StandardCharsets.UTF_8);
String html = new String(Files.readAllBytes(new File(args[0]).toPath()), StandardCharsets.UTF_8);

boolean timeLibhtmlparser = true;
boolean timeSanitize = true;
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/org/owasp/html/CssSchemaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public static final void testDangerousProperties() {
// Prefix corner cases.
"-",
"-moz-",
"-ms-",
"-o-",
"-webkit-",
}) {
assertSame(key, CssSchema.DISALLOWED, CssSchema.DEFAULT.forKey(key));
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/owasp/html/HtmlLexerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ public class HtmlLexerTest extends TestCase {
@Test
public final void testHtmlLexer() throws Exception {
// Do the lexing.
String input = new String(Files.readString(Paths.get(getClass().getResource("htmllexerinput1.html").toURI()), StandardCharsets.UTF_8));
String input = new String(Files.readAllBytes(Paths.get(getClass().getResource("htmllexerinput1.html").toURI())), StandardCharsets.UTF_8);
StringBuilder actual = new StringBuilder();
lex(input, actual);

// Get the golden.
String golden = new String(Files.readString(Paths.get(getClass().getResource("htmllexergolden1.txt").toURI()), StandardCharsets.UTF_8));
String golden = new String(Files.readAllBytes(Paths.get(getClass().getResource("htmllexergolden1.txt").toURI())), StandardCharsets.UTF_8);

// Compare.
assertEquals(golden, actual.toString());
Expand Down
Loading

0 comments on commit cea5a2c

Please sign in to comment.