am 550c8d32: Fixed shift underflow bug in interElementWhitespace checking.
* commit '550c8d3230c152db7156b266d089512b72ac0024':
Fixed shift underflow bug in interElementWhitespace checking.
diff --git a/src/main/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java b/src/main/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java
index ba83e9a..1f8f645 100644
--- a/src/main/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java
+++ b/src/main/org/owasp/html/TagBalancingHtmlStreamEventReceiver.java
@@ -212,18 +212,28 @@
}
}
- private static final int HTML_SPACE_CHAR_BITMASK =
- (1 << ' ') | (1 << '\t') | (1 << '\n') | (1 << '\u000c') | (1 << '\r');
+ private static final long HTML_SPACE_CHAR_BITMASK =
+ (1L << ' ')
+ | (1L << '\t')
+ | (1L << '\n')
+ | (1L << '\u000c')
+ | (1L << '\r');
- public void text(String text) {
+ public static boolean isInterElementWhitespace(String text) {
int n = text.length();
for (int i = 0; i < n; ++i) {
int ch = text.charAt(i);
- if (ch > 0x20 || (HTML_SPACE_CHAR_BITMASK & (1 << ch)) == 0) {
- prepareForContent(ElementContainmentRelationships.CHARACTER_DATA_ONLY);
- break;
+ if (ch > 0x20 || (HTML_SPACE_CHAR_BITMASK & (1L << ch)) == 0) {
+ return false;
}
}
+ return true;
+ }
+
+ public void text(String text) {
+ if (!isInterElementWhitespace(text)) {
+ prepareForContent(ElementContainmentRelationships.CHARACTER_DATA_ONLY);
+ }
if (openElements.size() < nestingLimit) {
underlying.text(text);
diff --git a/src/tests/org/owasp/html/TagBalancingHtmlStreamRendererTest.java b/src/tests/org/owasp/html/TagBalancingHtmlStreamRendererTest.java
index ab90ea4..941462d 100644
--- a/src/tests/org/owasp/html/TagBalancingHtmlStreamRendererTest.java
+++ b/src/tests/org/owasp/html/TagBalancingHtmlStreamRendererTest.java
@@ -32,12 +32,19 @@
import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.Before;
+
+import static org.owasp.html.TagBalancingHtmlStreamEventReceiver
+ .isInterElementWhitespace;
+
+
public class TagBalancingHtmlStreamRendererTest extends TestCase {
StringBuilder htmlOutputBuffer;
TagBalancingHtmlStreamEventReceiver balancer;
- @Override protected void setUp() throws Exception {
+ @Before @Override protected void setUp() throws Exception {
super.setUp();
htmlOutputBuffer = new StringBuilder();
balancer = new TagBalancingHtmlStreamEventReceiver(
@@ -48,6 +55,7 @@
}));
}
+ @Test
public final void testTagBalancing() {
balancer.openDocument();
balancer.openTag("html", ImmutableList.<String>of());
@@ -72,6 +80,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testTagSoupIronedOut() {
balancer.openDocument();
balancer.openTag("i", ImmutableList.<String>of());
@@ -87,6 +96,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testListInListDirectly() {
balancer.openDocument();
balancer.openTag("ul", ImmutableList.<String>of());
@@ -106,6 +116,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testTextContent() {
balancer.openDocument();
balancer.openTag("title", ImmutableList.<String>of());
@@ -152,6 +163,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testMismatchedHeaders() {
balancer.openDocument();
balancer.openTag("H1", ImmutableList.<String>of());
@@ -181,6 +193,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testListNesting() {
balancer.openDocument();
balancer.openTag("ul", ImmutableList.<String>of());
@@ -204,6 +217,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testTableNesting() {
balancer.openDocument();
balancer.openTag("table", ImmutableList.<String>of());
@@ -229,6 +243,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testNestingLimits() {
// Some browsers can be DoSed by deeply nested structures.
// See Issue 3, "Deeply nested elements crash FF 8, Chrome 11"
@@ -248,6 +263,7 @@
htmlOutputBuffer.toString());
}
+ @Test
public final void testTablesGuarded() {
// Derived from issue 12.
balancer.openDocument();
@@ -304,4 +320,21 @@
htmlOutputBuffer.toString());
}
+ @Test
+ public final void testIsInterElementWhitespace() {
+ assertFalse(isInterElementWhitespace("foo"));
+ assertTrue(isInterElementWhitespace(""));
+ assertTrue(isInterElementWhitespace(" "));
+ assertTrue(isInterElementWhitespace("\t"));
+ assertTrue(isInterElementWhitespace("\n"));
+ assertTrue(isInterElementWhitespace(" \n"));
+ assertTrue(isInterElementWhitespace("\r\n"));
+ assertTrue(isInterElementWhitespace("\r"));
+ assertTrue(isInterElementWhitespace(" "));
+ assertTrue(isInterElementWhitespace(" \t "));
+ assertFalse(isInterElementWhitespace(" foo "));
+ assertFalse(isInterElementWhitespace("\u00A0"));
+ assertFalse(isInterElementWhitespace("\u0000"));
+ }
+
}