Skip to content

Make canContain return true for <table>, <thead>, <tbody>, <tfoot> an… #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/main/java/org/owasp/html/HtmlElementTables.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public final class HtmlElementTables {
/** {@code <noscript>}, {@code <noframes>}, etc. */
private final DenseElementSet nofeatureElements;

private final DenseElementSet tableElements;

/** */
public HtmlElementTables(
Expand Down Expand Up @@ -186,16 +187,26 @@ public HtmlElementTables(
nofeatureBits[indexForName("noframes")] =
nofeatureBits[indexForName("noembed")] = true;
this.nofeatureElements = new DenseElementSet(nofeatureBits);

boolean[] tableElements = new boolean[this.nElementTypes()];
tableElements[indexForName("table")] =
tableElements[indexForName("thead")] =
tableElements[indexForName("tbody")] =
tableElements[indexForName("tfoot")] =
tableElements[indexForName("tr")] = true;
this.tableElements = new DenseElementSet(tableElements);
}


/** True if parent can directly contain child. */
public boolean canContain(int parent, int child) {
if (nofeatureElements.get(parent)) {
if (nofeatureElements.get(parent) || tableElements.get(parent)) {
// It's hard to interrogate a browser about the behavior of
// <noscript> in scriptless mode using JavaScript, and the
// behavior of <noscript> is more dangerous when in that mode,
// so we hardcode that mode here as a worst case assumption.
// Return true for <table>, <thead>, <tbody>, <tfoot> and <tr> elements,
// so that it will not close the open table elements and break table layout.
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/owasp/html/SanitizersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public static final void testScriptInTable() {
.and(Sanitizers.STYLES)
.and(Sanitizers.IMAGES)
.and(Sanitizers.TABLES);
assertEquals("<table></table>Hallo\r\n\nEnde\n\r", pf.sanitize(input));
assertEquals("<table>Hallo\r\n\nEnde\n\r</table>", pf.sanitize(input));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a better behavior?

}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ public final void testTableNesting() {
balancer.openTag("td", ImmutableList.<String>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.<String>of());
balancer.openTag("tbody", ImmutableList.<String>of());
balancer.openTag("tr", ImmutableList.<String>of());
Expand All @@ -241,8 +239,8 @@ public final void testTableNesting() {
balancer.closeDocument();

assertEquals(
"<table><tbody><tr><td>foo</td></tr></tbody></table>"
+ "<table><tbody><tr><th>bar</th></tr></tbody></table>",
"<table><tbody><tr><td>foo</td><table><tbody><tr><th>bar</th>"
+ "</tr></tbody></table></tr></tbody></table>",

htmlOutputBuffer.toString());
}
Expand Down