From dcf7fb9c7afdcc435b370e18bf81f694f8d7d580 Mon Sep 17 00:00:00 2001 From: mikesamuel Date: Tue, 6 Nov 2012 16:24:04 +0000 Subject: release r124 git-svn-id: http://owasp-java-html-sanitizer.googlecode.com/svn/trunk@124 ad8eed46-c659-4a31-e19d-951d88f54425 --- .../html/TagBalancingHtmlStreamEventReceiver.html | 16 +- .../html/TagBalancingHtmlStreamEventReceiver.html | 1583 +++++++++++--------- distrib/lib/owasp-java-html-sanitizer-src.jar | Bin 86756 -> 87486 bytes distrib/lib/owasp-java-html-sanitizer.jar | Bin 96240 -> 97267 bytes 4 files changed, 843 insertions(+), 756 deletions(-) (limited to 'distrib') diff --git a/distrib/javadoc/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html b/distrib/javadoc/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html index e6fe0f0..2699740 100644 --- a/distrib/javadoc/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html +++ b/distrib/javadoc/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html @@ -98,7 +98,7 @@ java.lang.Object
-
public class TagBalancingHtmlStreamEventReceiver
extends java.lang.Object
implements HtmlStreamEventReceiver
+
public class TagBalancingHtmlStreamEventReceiver
extends java.lang.Object
implements HtmlStreamEventReceiver

@@ -215,7 +215,7 @@ Wraps an HTML stream event receiver to fill in missing close tags.

TagBalancingHtmlStreamEventReceiver

-public TagBalancingHtmlStreamEventReceiver(HtmlStreamEventReceiver underlying)
+public TagBalancingHtmlStreamEventReceiver(HtmlStreamEventReceiver underlying)
@@ -232,7 +232,7 @@ public

setNestingLimit

-public void setNestingLimit(int limit)
+public void setNestingLimit(int limit)
@@ -246,7 +246,7 @@ public void

openDocument

-public void openDocument()
+public void openDocument()
Specified by:
openDocument in interface HtmlStreamEventReceiver
@@ -260,7 +260,7 @@ public void

closeDocument

-public void closeDocument()
+public void closeDocument()
Specified by:
closeDocument in interface HtmlStreamEventReceiver
@@ -274,7 +274,7 @@ public void

openTag

-public void openTag(java.lang.String elementName,
+public void openTag(java.lang.String elementName,
                     java.util.List<java.lang.String> attrs)
@@ -289,7 +289,7 @@ public void

closeTag

-public void closeTag(java.lang.String elementName)
+public void closeTag(java.lang.String elementName)
Specified by:
closeTag in interface HtmlStreamEventReceiver
@@ -303,7 +303,7 @@ public void

text

-public void text(java.lang.String text)
+public void text(java.lang.String text)
Specified by:
text in interface HtmlStreamEventReceiver
diff --git a/distrib/javadoc/src-html/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html b/distrib/javadoc/src-html/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html index c2b8bd5..2697494 100644 --- a/distrib/javadoc/src-html/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html +++ b/distrib/javadoc/src-html/org/owasp/html/TagBalancingHtmlStreamEventReceiver.html @@ -33,789 +33,876 @@ 030 031 import java.util.List; 032 -033 import javax.annotation.concurrent.Immutable; -034 -035 import com.google.common.collect.ImmutableMap; -036 import com.google.common.collect.Lists; -037 -038 /** -039 * Wraps an HTML stream event receiver to fill in missing close tags. -040 * If the balancer is given the HTML {@code <p>1<p>2}, the wrapped receiver will -041 * see events equivalent to {@code <p>1</p><p>2</p>}. -042 * -043 * @author Mike Samuel <mikesamuel@gmail.com> -044 */ -045 @TCB -046 public class TagBalancingHtmlStreamEventReceiver -047 implements HtmlStreamEventReceiver { -048 private final HtmlStreamEventReceiver underlying; -049 private int nestingLimit = Integer.MAX_VALUE; -050 private final List<ElementContainmentInfo> openElements -051 = Lists.newArrayList(); -052 -053 public TagBalancingHtmlStreamEventReceiver( -054 HtmlStreamEventReceiver underlying) { -055 this.underlying = underlying; -056 } -057 -058 public void setNestingLimit(int limit) { -059 if (openElements.size() > limit) { -060 throw new IllegalStateException(); -061 } -062 this.nestingLimit = limit; -063 } -064 -065 public void openDocument() { -066 underlying.openDocument(); -067 } -068 -069 public void closeDocument() { -070 for (int i = Math.min(nestingLimit, openElements.size()); --i >= 0;) { -071 underlying.closeTag(openElements.get(i).elementName); -072 } -073 openElements.clear(); -074 underlying.closeDocument(); -075 } -076 -077 public void openTag(String elementName, List<String> attrs) { -078 String canonElementName = HtmlLexer.canonicalName(elementName); -079 ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( -080 canonElementName); -081 // Treat unrecognized tags as void, but emit closing tags in closeTag(). -082 if (elInfo == null) { -083 if (openElements.size() < nestingLimit) { -084 underlying.openTag(elementName, attrs); -085 } -086 return; -087 } -088 -089 // Close all the elements that cannot contain the element to open. -090 List<ElementContainmentInfo> toResumeInReverse = null; -091 for (int i = openElements.size(); --i >= 0;) { -092 ElementContainmentInfo top = openElements.get(i); -093 if ((top.contents & elInfo.types) != 0) { break; } -094 if (openElements.size() < nestingLimit) { -095 underlying.closeTag(top.elementName); -096 } -097 openElements.remove(i); -098 if (top.resumable) { -099 if (toResumeInReverse == null) { -100 toResumeInReverse = Lists.newArrayList(); -101 } -102 toResumeInReverse.add(top); -103 } -104 } -105 -106 if (toResumeInReverse != null) { -107 resume(toResumeInReverse); -108 } -109 if (openElements.size() < nestingLimit) { -110 underlying.openTag(elementName, attrs); -111 } -112 if (!elInfo.isVoid) { -113 openElements.add(elInfo); -114 } -115 } +033 import javax.annotation.Nullable; +034 import javax.annotation.concurrent.Immutable; +035 +036 import com.google.common.collect.ImmutableMap; +037 import com.google.common.collect.Lists; +038 +039 /** +040 * Wraps an HTML stream event receiver to fill in missing close tags. +041 * If the balancer is given the HTML {@code <p>1<p>2}, the wrapped receiver will +042 * see events equivalent to {@code <p>1</p><p>2</p>}. +043 * +044 * @author Mike Samuel <mikesamuel@gmail.com> +045 */ +046 @TCB +047 public class TagBalancingHtmlStreamEventReceiver +048 implements HtmlStreamEventReceiver { +049 private final HtmlStreamEventReceiver underlying; +050 private int nestingLimit = Integer.MAX_VALUE; +051 private final List<ElementContainmentInfo> openElements +052 = Lists.newArrayList(); +053 +054 public TagBalancingHtmlStreamEventReceiver( +055 HtmlStreamEventReceiver underlying) { +056 this.underlying = underlying; +057 } +058 +059 public void setNestingLimit(int limit) { +060 if (openElements.size() > limit) { +061 throw new IllegalStateException(); +062 } +063 this.nestingLimit = limit; +064 } +065 +066 public void openDocument() { +067 underlying.openDocument(); +068 } +069 +070 public void closeDocument() { +071 for (int i = Math.min(nestingLimit, openElements.size()); --i >= 0;) { +072 underlying.closeTag(openElements.get(i).elementName); +073 } +074 openElements.clear(); +075 underlying.closeDocument(); +076 } +077 +078 public void openTag(String elementName, List<String> attrs) { +079 String canonElementName = HtmlLexer.canonicalName(elementName); +080 ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( +081 canonElementName); +082 // Treat unrecognized tags as void, but emit closing tags in closeTag(). +083 if (elInfo == null) { +084 if (openElements.size() < nestingLimit) { +085 underlying.openTag(elementName, attrs); +086 } +087 return; +088 } +089 +090 prepareForContent(elInfo); +091 +092 if (openElements.size() < nestingLimit) { +093 underlying.openTag(elInfo.elementName, attrs); +094 } +095 if (!elInfo.isVoid) { +096 openElements.add(elInfo); +097 } +098 } +099 +100 private void prepareForContent(ElementContainmentInfo elInfo) { +101 int nOpen = openElements.size(); +102 if (nOpen != 0) { +103 ElementContainmentInfo top = openElements.get(nOpen - 1); +104 if ((top.contents & elInfo.types) == 0) { +105 ElementContainmentInfo blockContainerChild = top.blockContainerChild; +106 // Open implied elements, such as list-items and table cells & rows. +107 if (blockContainerChild != null +108 && (blockContainerChild.contents & elInfo.types) != 0) { +109 underlying.openTag( +110 blockContainerChild.elementName, Lists.<String>newArrayList()); +111 openElements.add(blockContainerChild); +112 top = blockContainerChild; +113 ++nOpen; +114 } +115 } 116 -117 public void closeTag(String elementName) { -118 String canonElementName = HtmlLexer.canonicalName(elementName); -119 ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( -120 canonElementName); -121 if (elInfo == null) { // Allow unrecognized end tags through. -122 if (openElements.size() < nestingLimit) { -123 underlying.closeTag(elementName); -124 } -125 return; -126 } -127 int index = openElements.lastIndexOf(elInfo); -128 if (index < 0) { return; } // Don't close unopened tags. -129 int last = openElements.size(); -130 // Close all the elements that cannot contain the element to open. -131 List<ElementContainmentInfo> toResumeInReverse = null; -132 while (--last > index) { -133 ElementContainmentInfo unclosed = openElements.remove(last); -134 if (last + 1 < nestingLimit) { -135 underlying.closeTag(unclosed.elementName); -136 } -137 if (unclosed.resumable) { -138 if (toResumeInReverse == null) { -139 toResumeInReverse = Lists.newArrayList(); -140 } -141 toResumeInReverse.add(unclosed); -142 } -143 } -144 if (openElements.size() < nestingLimit) { -145 underlying.closeTag(elementName); -146 } -147 openElements.remove(index); -148 if (toResumeInReverse != null) { -149 resume(toResumeInReverse); +117 // Close all the elements that cannot contain the element to open. +118 List<ElementContainmentInfo> toResumeInReverse = null; +119 while (true) { +120 if ((top.contents & elInfo.types) != 0) { break; } +121 if (openElements.size() < nestingLimit) { +122 underlying.closeTag(top.elementName); +123 } +124 openElements.remove(--nOpen); +125 if (top.resumable) { +126 if (toResumeInReverse == null) { +127 toResumeInReverse = Lists.newArrayList(); +128 } +129 toResumeInReverse.add(top); +130 } +131 if (nOpen == 0) { break; } +132 top = openElements.get(nOpen - 1); +133 } +134 +135 if (toResumeInReverse != null) { +136 resume(toResumeInReverse); +137 } +138 } +139 } +140 +141 public void closeTag(String elementName) { +142 String canonElementName = HtmlLexer.canonicalName(elementName); +143 ElementContainmentInfo elInfo = ELEMENT_CONTAINMENT_RELATIONSHIPS.get( +144 canonElementName); +145 if (elInfo == null) { // Allow unrecognized end tags through. +146 if (openElements.size() < nestingLimit) { +147 underlying.closeTag(elementName); +148 } +149 return; 150 } -151 } -152 -153 private void resume(List<ElementContainmentInfo> toResumeInReverse) { -154 for (ElementContainmentInfo toResume : toResumeInReverse) { -155 // TODO: If resuming of things other than plain formatting tags like <b> -156 // and <i>, then we need to store the attributes for resumable tags so -157 // that we can resume with the appropriate attributes. -158 if (openElements.size() < nestingLimit) { -159 underlying.openTag(toResume.elementName, Lists.<String>newArrayList()); -160 } -161 openElements.add(toResume); -162 } -163 } -164 -165 public void text(String text) { -166 if (openElements.size() < nestingLimit) { -167 underlying.text(text); +151 int index = openElements.lastIndexOf(elInfo); +152 if (index < 0) { +153 // Let any of </h1>, </h2>, ... close other header tags. +154 if (isHeaderElementName(canonElementName)) { +155 for (int i = openElements.size(); -- i >= 0;) { +156 ElementContainmentInfo openEl = openElements.get(i); +157 if (isHeaderElementName(openEl.elementName)) { +158 elInfo = openEl; +159 index = i; +160 canonElementName = openEl.elementName; +161 break; +162 } +163 } +164 } +165 if (index < 0) { +166 return; // Don't close unopened tags. +167 } 168 } -169 } -170 -171 -172 @Immutable -173 static final class ElementContainmentInfo { -174 final String elementName; -175 /** -176 * True if the adoption agency algorithm allows an element to be resumed -177 * after a mis-nested end tag closes it. -178 * E.g. in {@code <b>Foo<i>Bar</b>Baz</i>} the {@code <i>} element is -179 * resumed after the {@code <b>} element is closed. -180 */ -181 final boolean resumable; -182 /** A set of bits of element groups into which the element falls. */ -183 final int types; -184 /** The type of elements that an element can contain. */ -185 final int contents; -186 /** True if the element has no content -- not even text content. */ -187 final boolean isVoid; -188 -189 ElementContainmentInfo( -190 String elementName, boolean resumable, int types, int contents) { -191 this.elementName = elementName; -192 this.resumable = resumable; -193 this.types = types; -194 this.contents = contents; -195 this.isVoid = contents == 0 -196 && HtmlTextEscapingMode.isVoidElement(elementName); -197 } -198 -199 @Override public String toString() { -200 return "<" + elementName + ">"; -201 } -202 } -203 -204 ImmutableMap<String, ElementContainmentInfo> ELEMENT_CONTAINMENT_RELATIONSHIPS -205 = new ElementContainmentRelationships().toMap(); -206 -207 private static class ElementContainmentRelationships { -208 private enum ElementGroup { -209 BLOCK, -210 INLINE, -211 INLINE_MINUS_A, -212 MIXED, -213 TABLE_CONTENT, -214 HEAD_CONTENT, -215 TOP_CONTENT, -216 AREA_ELEMENT, -217 FORM_ELEMENT, -218 LEGEND_ELEMENT, -219 LI_ELEMENT, -220 DL_PART, -221 P_ELEMENT, -222 OPTIONS_ELEMENT, -223 OPTION_ELEMENT, -224 PARAM_ELEMENT, -225 TABLE_ELEMENT, -226 TR_ELEMENT, -227 TD_ELEMENT, -228 COL_ELEMENT, -229 ; -230 } -231 -232 private static int elementGroupBits(ElementGroup a) { -233 return 1 << a.ordinal(); -234 } -235 -236 private static int elementGroupBits( -237 ElementGroup a, ElementGroup b) { -238 return (1 << a.ordinal()) | (1 << b.ordinal()); -239 } -240 -241 private static int elementGroupBits( -242 ElementGroup a, ElementGroup b, ElementGroup c) { -243 return (1 << a.ordinal()) | (1 << b.ordinal()) | (1 << c.ordinal()); -244 } -245 -246 private static int elementGroupBits( -247 ElementGroup... bits) { -248 int bitField = 0; -249 for (ElementGroup bit : bits) { -250 bitField |= (1 << bit.ordinal()); -251 } -252 return bitField; -253 } -254 -255 private ImmutableMap.Builder<String, ElementContainmentInfo> definitions -256 = ImmutableMap.builder(); -257 -258 private void defineElement( -259 String elementName, boolean resumable, int types, int contentTypes) { -260 definitions.put(elementName, new ElementContainmentInfo( -261 elementName, resumable, types, contentTypes)); +169 int last = openElements.size(); +170 // Close all the elements that cannot contain the element to open. +171 List<ElementContainmentInfo> toResumeInReverse = null; +172 while (--last > index) { +173 ElementContainmentInfo unclosed = openElements.remove(last); +174 if (last + 1 < nestingLimit) { +175 underlying.closeTag(unclosed.elementName); +176 } +177 if (unclosed.resumable) { +178 if (toResumeInReverse == null) { +179 toResumeInReverse = Lists.newArrayList(); +180 } +181 toResumeInReverse.add(unclosed); +182 } +183 } +184 if (openElements.size() < nestingLimit) { +185 underlying.closeTag(elInfo.elementName); +186 } +187 openElements.remove(index); +188 if (toResumeInReverse != null) { +189 resume(toResumeInReverse); +190 } +191 } +192 +193 private void resume(List<ElementContainmentInfo> toResumeInReverse) { +194 for (ElementContainmentInfo toResume : toResumeInReverse) { +195 // TODO: If resuming of things other than plain formatting tags like <b> +196 // and <i>, then we need to store the attributes for resumable tags so +197 // that we can resume with the appropriate attributes. +198 if (openElements.size() < nestingLimit) { +199 underlying.openTag(toResume.elementName, Lists.<String>newArrayList()); +200 } +201 openElements.add(toResume); +202 } +203 } +204 +205 private static final int HTML_SPACE_CHAR_BITMASK = +206 (1 << ' ') | (1 << '\t') | (1 << '\n') | (1 << '\u000c') | (1 << '\r'); +207 +208 public void text(String text) { +209 int n = text.length(); +210 for (int i = 0; i < n; ++i) { +211 int ch = text.charAt(i); +212 if (ch > 0x20 || (HTML_SPACE_CHAR_BITMASK & (1 << ch)) == 0) { +213 prepareForContent(ElementContainmentRelationships.CHARACTER_DATA); +214 break; +215 } +216 } +217 +218 if (openElements.size() < nestingLimit) { +219 underlying.text(text); +220 } +221 } +222 +223 private static boolean isHeaderElementName(String canonElementName) { +224 return canonElementName.length() == 2 && canonElementName.charAt(0) == 'h' +225 && canonElementName.charAt(1) <= '9'; +226 } +227 +228 +229 @Immutable +230 private static final class ElementContainmentInfo { +231 final String elementName; +232 /** +233 * True if the adoption agency algorithm allows an element to be resumed +234 * after a mis-nested end tag closes it. +235 * E.g. in {@code <b>Foo<i>Bar</b>Baz</i>} the {@code <i>} element is +236 * resumed after the {@code <b>} element is closed. +237 */ +238 final boolean resumable; +239 /** A set of bits of element groups into which the element falls. */ +240 final int types; +241 /** The type of elements that an element can contain. */ +242 final int contents; +243 /** True if the element has no content -- not even text content. */ +244 final boolean isVoid; +245 /** A legal child of this node that can contain block content. */ +246 final @Nullable ElementContainmentInfo blockContainerChild; +247 +248 ElementContainmentInfo( +249 String elementName, boolean resumable, int types, int contents, +250 @Nullable ElementContainmentInfo blockContainerChild) { +251 this.elementName = elementName; +252 this.resumable = resumable; +253 this.types = types; +254 this.contents = contents; +255 this.isVoid = contents == 0 +256 && HtmlTextEscapingMode.isVoidElement(elementName); +257 this.blockContainerChild = blockContainerChild; +258 } +259 +260 @Override public String toString() { +261 return "<" + elementName + ">"; 262 } -263 -264 private ImmutableMap<String, ElementContainmentInfo> toMap() { -265 return definitions.build(); -266 } +263 } +264 +265 ImmutableMap<String, ElementContainmentInfo> ELEMENT_CONTAINMENT_RELATIONSHIPS +266 = new ElementContainmentRelationships().toMap(); 267 -268 { -269 defineElement( -270 "a", false, elementGroupBits( -271 ElementGroup.INLINE -272 ), elementGroupBits( -273 ElementGroup.INLINE_MINUS_A -274 )); -275 defineElement( -276 "abbr", true, elementGroupBits( -277 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -278 ), elementGroupBits( -279 ElementGroup.INLINE -280 )); -281 defineElement( -282 "acronym", true, elementGroupBits( -283 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -284 ), elementGroupBits( -285 ElementGroup.INLINE -286 )); -287 defineElement( -288 "address", false, elementGroupBits( -289 ElementGroup.BLOCK -290 ), elementGroupBits( -291 ElementGroup.INLINE, ElementGroup.P_ELEMENT -292 )); -293 defineElement( -294 "applet", false, elementGroupBits( -295 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -296 ), elementGroupBits( -297 ElementGroup.BLOCK, ElementGroup.INLINE, -298 ElementGroup.PARAM_ELEMENT -299 )); -300 defineElement( -301 "area", false, elementGroupBits(ElementGroup.AREA_ELEMENT), 0); -302 defineElement( -303 "audio", false, elementGroupBits( -304 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -305 ), 0); -306 defineElement( -307 "b", true, elementGroupBits( -308 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -309 ), elementGroupBits( -310 ElementGroup.INLINE -311 )); -312 defineElement( -313 "base", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); -314 defineElement( -315 "basefont", false, elementGroupBits( -316 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -317 ), 0); -318 defineElement( -319 "bdi", true, elementGroupBits( -320 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -321 ), elementGroupBits( -322 ElementGroup.INLINE -323 )); -324 defineElement( -325 "bdo", true, elementGroupBits( -326 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -327 ), elementGroupBits( -328 ElementGroup.INLINE -329 )); -330 defineElement( -331 "big", true, elementGroupBits( -332 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -333 ), elementGroupBits( -334 ElementGroup.INLINE -335 )); -336 defineElement( -337 "blink", true, elementGroupBits( -338 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -339 ), elementGroupBits( -340 ElementGroup.INLINE -341 )); -342 defineElement( -343 "blockquote", false, elementGroupBits( -344 ElementGroup.BLOCK -345 ), elementGroupBits( -346 ElementGroup.BLOCK, ElementGroup.INLINE -347 )); -348 defineElement( -349 "body", false, elementGroupBits( -350 ElementGroup.TOP_CONTENT -351 ), elementGroupBits( -352 ElementGroup.BLOCK, ElementGroup.INLINE -353 )); -354 defineElement( -355 "br", false, elementGroupBits( -356 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -357 ), 0); -358 defineElement( -359 "button", false, elementGroupBits( -360 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -361 ), elementGroupBits( -362 ElementGroup.BLOCK, ElementGroup.INLINE -363 )); -364 defineElement( -365 "canvas", false, elementGroupBits( -366 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -367 ), elementGroupBits( -368 ElementGroup.INLINE +268 private static class ElementContainmentRelationships { +269 private enum ElementGroup { +270 BLOCK, +271 INLINE, +272 INLINE_MINUS_A, +273 MIXED, +274 TABLE_CONTENT, +275 HEAD_CONTENT, +276 TOP_CONTENT, +277 AREA_ELEMENT, +278 FORM_ELEMENT, +279 LEGEND_ELEMENT, +280 LI_ELEMENT, +281 DL_PART, +282 P_ELEMENT, +283 OPTIONS_ELEMENT, +284 OPTION_ELEMENT, +285 PARAM_ELEMENT, +286 TABLE_ELEMENT, +287 TR_ELEMENT, +288 TD_ELEMENT, +289 COL_ELEMENT, +290 CHARACTER_DATA, +291 ; +292 } +293 +294 private static int elementGroupBits(ElementGroup a) { +295 return 1 << a.ordinal(); +296 } +297 +298 private static int elementGroupBits( +299 ElementGroup a, ElementGroup b) { +300 return (1 << a.ordinal()) | (1 << b.ordinal()); +301 } +302 +303 private static int elementGroupBits( +304 ElementGroup a, ElementGroup b, ElementGroup c) { +305 return (1 << a.ordinal()) | (1 << b.ordinal()) | (1 << c.ordinal()); +306 } +307 +308 private static int elementGroupBits( +309 ElementGroup... bits) { +310 int bitField = 0; +311 for (ElementGroup bit : bits) { +312 bitField |= (1 << bit.ordinal()); +313 } +314 return bitField; +315 } +316 +317 private ImmutableMap.Builder<String, ElementContainmentInfo> definitions +318 = ImmutableMap.builder(); +319 +320 private ElementContainmentInfo defineElement( +321 String elementName, boolean resumable, int types, int contentTypes) { +322 return defineElement(elementName, resumable, types, contentTypes, null); +323 } +324 +325 private ElementContainmentInfo defineElement( +326 String elementName, boolean resumable, int types, int contentTypes, +327 @Nullable ElementContainmentInfo blockContainer) { +328 ElementContainmentInfo info = new ElementContainmentInfo( +329 elementName, resumable, types, contentTypes, blockContainer); +330 definitions.put(elementName, info); +331 return info; +332 } +333 +334 private ImmutableMap<String, ElementContainmentInfo> toMap() { +335 return definitions.build(); +336 } +337 +338 { +339 defineElement( +340 "a", false, elementGroupBits( +341 ElementGroup.INLINE +342 ), elementGroupBits( +343 ElementGroup.INLINE_MINUS_A +344 )); +345 defineElement( +346 "abbr", true, elementGroupBits( +347 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +348 ), elementGroupBits( +349 ElementGroup.INLINE +350 )); +351 defineElement( +352 "acronym", true, elementGroupBits( +353 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +354 ), elementGroupBits( +355 ElementGroup.INLINE +356 )); +357 defineElement( +358 "address", false, elementGroupBits( +359 ElementGroup.BLOCK +360 ), elementGroupBits( +361 ElementGroup.INLINE, ElementGroup.P_ELEMENT +362 )); +363 defineElement( +364 "applet", false, elementGroupBits( +365 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +366 ), elementGroupBits( +367 ElementGroup.BLOCK, ElementGroup.INLINE, +368 ElementGroup.PARAM_ELEMENT 369 )); 370 defineElement( -371 "caption", false, elementGroupBits( -372 ElementGroup.TABLE_CONTENT -373 ), elementGroupBits( -374 ElementGroup.INLINE -375 )); +371 "area", false, elementGroupBits(ElementGroup.AREA_ELEMENT), 0); +372 defineElement( +373 "audio", false, elementGroupBits( +374 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +375 ), 0); 376 defineElement( -377 "center", false, elementGroupBits( -378 ElementGroup.BLOCK +377 "b", true, elementGroupBits( +378 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 379 ), elementGroupBits( -380 ElementGroup.BLOCK, ElementGroup.INLINE +380 ElementGroup.INLINE 381 )); 382 defineElement( -383 "cite", true, elementGroupBits( -384 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -385 ), elementGroupBits( -386 ElementGroup.INLINE -387 )); +383 "base", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); +384 defineElement( +385 "basefont", false, elementGroupBits( +386 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +387 ), 0); 388 defineElement( -389 "code", true, elementGroupBits( +389 "bdi", true, elementGroupBits( 390 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A 391 ), elementGroupBits( 392 ElementGroup.INLINE 393 )); 394 defineElement( -395 "col", false, elementGroupBits( -396 ElementGroup.TABLE_CONTENT, ElementGroup.COL_ELEMENT -397 ), 0); -398 defineElement( -399 "colgroup", false, elementGroupBits( -400 ElementGroup.TABLE_CONTENT -401 ), elementGroupBits( -402 ElementGroup.COL_ELEMENT -403 )); -404 defineElement( -405 "dd", false, elementGroupBits( -406 ElementGroup.DL_PART -407 ), elementGroupBits( -408 ElementGroup.BLOCK, ElementGroup.INLINE -409 )); -410 defineElement( -411 "del", true, elementGroupBits( -412 ElementGroup.BLOCK, ElementGroup.INLINE, -413 ElementGroup.MIXED -414 ), elementGroupBits( -415 ElementGroup.BLOCK, ElementGroup.INLINE -416 )); -417 defineElement( -418 "dfn", true, elementGroupBits( -419 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -420 ), elementGroupBits( -421 ElementGroup.INLINE -422 )); -423 defineElement( -424 "dir", false, elementGroupBits( -425 ElementGroup.BLOCK -426 ), elementGroupBits( -427 ElementGroup.LI_ELEMENT -428 )); -429 defineElement( -430 "div", false, elementGroupBits( -431 ElementGroup.BLOCK -432 ), elementGroupBits( -433 ElementGroup.BLOCK, ElementGroup.INLINE -434 )); -435 defineElement( -436 "dl", false, elementGroupBits( -437 ElementGroup.BLOCK -438 ), elementGroupBits( -439 ElementGroup.DL_PART -440 )); -441 defineElement( -442 "dt", false, elementGroupBits( -443 ElementGroup.DL_PART -444 ), elementGroupBits( -445 ElementGroup.INLINE -446 )); -447 defineElement( -448 "em", true, elementGroupBits( -449 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -450 ), elementGroupBits( -451 ElementGroup.INLINE -452 )); -453 defineElement( -454 "fieldset", false, elementGroupBits( -455 ElementGroup.BLOCK -456 ), elementGroupBits( -457 ElementGroup.BLOCK, ElementGroup.INLINE, -458 ElementGroup.LEGEND_ELEMENT -459 )); -460 defineElement( -461 "font", false, elementGroupBits( -462 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -463 ), elementGroupBits( -464 ElementGroup.INLINE -465 )); -466 defineElement( -467 "form", false, elementGroupBits( -468 ElementGroup.BLOCK, ElementGroup.FORM_ELEMENT -469 ), elementGroupBits( -470 ElementGroup.BLOCK, ElementGroup.INLINE, -471 ElementGroup.INLINE_MINUS_A, ElementGroup.TR_ELEMENT, -472 ElementGroup.TD_ELEMENT +395 "bdo", true, elementGroupBits( +396 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +397 ), elementGroupBits( +398 ElementGroup.INLINE +399 )); +400 defineElement( +401 "big", true, elementGroupBits( +402 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +403 ), elementGroupBits( +404 ElementGroup.INLINE +405 )); +406 defineElement( +407 "blink", true, elementGroupBits( +408 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +409 ), elementGroupBits( +410 ElementGroup.INLINE +411 )); +412 defineElement( +413 "blockquote", false, elementGroupBits( +414 ElementGroup.BLOCK +415 ), elementGroupBits( +416 ElementGroup.BLOCK, ElementGroup.INLINE +417 )); +418 defineElement( +419 "body", false, elementGroupBits( +420 ElementGroup.TOP_CONTENT +421 ), elementGroupBits( +422 ElementGroup.BLOCK, ElementGroup.INLINE +423 )); +424 defineElement( +425 "br", false, elementGroupBits( +426 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +427 ), 0); +428 defineElement( +429 "button", false, elementGroupBits( +430 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +431 ), elementGroupBits( +432 ElementGroup.BLOCK, ElementGroup.INLINE +433 )); +434 defineElement( +435 "canvas", false, elementGroupBits( +436 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +437 ), elementGroupBits( +438 ElementGroup.INLINE +439 )); +440 defineElement( +441 "caption", false, elementGroupBits( +442 ElementGroup.TABLE_CONTENT +443 ), elementGroupBits( +444 ElementGroup.INLINE +445 )); +446 defineElement( +447 "center", false, elementGroupBits( +448 ElementGroup.BLOCK +449 ), elementGroupBits( +450 ElementGroup.BLOCK, ElementGroup.INLINE +451 )); +452 defineElement( +453 "cite", true, elementGroupBits( +454 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +455 ), elementGroupBits( +456 ElementGroup.INLINE +457 )); +458 defineElement( +459 "code", true, elementGroupBits( +460 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +461 ), elementGroupBits( +462 ElementGroup.INLINE +463 )); +464 defineElement( +465 "col", false, elementGroupBits( +466 ElementGroup.TABLE_CONTENT, ElementGroup.COL_ELEMENT +467 ), 0); +468 defineElement( +469 "colgroup", false, elementGroupBits( +470 ElementGroup.TABLE_CONTENT +471 ), elementGroupBits( +472 ElementGroup.COL_ELEMENT 473 )); -474 defineElement( -475 "h1", false, elementGroupBits( -476 ElementGroup.BLOCK +474 ElementContainmentInfo DD = defineElement( +475 "dd", false, elementGroupBits( +476 ElementGroup.DL_PART 477 ), elementGroupBits( -478 ElementGroup.INLINE +478 ElementGroup.BLOCK, ElementGroup.INLINE 479 )); 480 defineElement( -481 "h2", false, elementGroupBits( -482 ElementGroup.BLOCK -483 ), elementGroupBits( -484 ElementGroup.INLINE -485 )); -486 defineElement( -487 "h3", false, elementGroupBits( -488 ElementGroup.BLOCK -489 ), elementGroupBits( -490 ElementGroup.INLINE -491 )); -492 defineElement( -493 "h4", false, elementGroupBits( -494 ElementGroup.BLOCK -495 ), elementGroupBits( -496 ElementGroup.INLINE -497 )); -498 defineElement( -499 "h5", false, elementGroupBits( -500 ElementGroup.BLOCK -501 ), elementGroupBits( -502 ElementGroup.INLINE -503 )); -504 defineElement( -505 "h6", false, elementGroupBits( -506 ElementGroup.BLOCK -507 ), elementGroupBits( -508 ElementGroup.INLINE -509 )); -510 defineElement( -511 "head", false, elementGroupBits( -512 ElementGroup.TOP_CONTENT -513 ), elementGroupBits( -514 ElementGroup.HEAD_CONTENT -515 )); -516 defineElement( -517 "hr", false, elementGroupBits(ElementGroup.BLOCK), 0); +481 "del", true, elementGroupBits( +482 ElementGroup.BLOCK, ElementGroup.INLINE, +483 ElementGroup.MIXED +484 ), elementGroupBits( +485 ElementGroup.BLOCK, ElementGroup.INLINE +486 )); +487 defineElement( +488 "dfn", true, elementGroupBits( +489 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +490 ), elementGroupBits( +491 ElementGroup.INLINE +492 )); +493 defineElement( +494 "dir", false, elementGroupBits( +495 ElementGroup.BLOCK +496 ), elementGroupBits( +497 ElementGroup.LI_ELEMENT +498 )); +499 defineElement( +500 "div", false, elementGroupBits( +501 ElementGroup.BLOCK +502 ), elementGroupBits( +503 ElementGroup.BLOCK, ElementGroup.INLINE +504 )); +505 defineElement( +506 "dl", false, elementGroupBits( +507 ElementGroup.BLOCK +508 ), elementGroupBits( +509 ElementGroup.DL_PART +510 ), +511 DD); +512 defineElement( +513 "dt", false, elementGroupBits( +514 ElementGroup.DL_PART +515 ), elementGroupBits( +516 ElementGroup.INLINE +517 )); 518 defineElement( -519 "html", false, 0, elementGroupBits(ElementGroup.TOP_CONTENT)); -520 defineElement( -521 "i", true, elementGroupBits( -522 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -523 ), elementGroupBits( -524 ElementGroup.INLINE -525 )); -526 defineElement( -527 "iframe", false, elementGroupBits( -528 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -529 ), elementGroupBits( -530 ElementGroup.BLOCK, ElementGroup.INLINE -531 )); -532 defineElement( -533 "img", false, elementGroupBits( -534 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -535 ), 0); -536 defineElement( -537 "input", false, elementGroupBits( -538 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -539 ), 0); -540 defineElement( -541 "ins", true, elementGroupBits( -542 ElementGroup.BLOCK, ElementGroup.INLINE -543 ), elementGroupBits( -544 ElementGroup.BLOCK, ElementGroup.INLINE -545 )); -546 defineElement( -547 "isindex", false, elementGroupBits(ElementGroup.INLINE), 0); -548 defineElement( -549 "kbd", true, elementGroupBits( -550 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -551 ), elementGroupBits( -552 ElementGroup.INLINE -553 )); -554 defineElement( -555 "label", false, elementGroupBits( -556 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -557 ), elementGroupBits( -558 ElementGroup.INLINE -559 )); -560 defineElement( -561 "legend", false, elementGroupBits( -562 ElementGroup.LEGEND_ELEMENT -563 ), elementGroupBits( -564 ElementGroup.INLINE -565 )); -566 defineElement( -567 "li", false, elementGroupBits( -568 ElementGroup.LI_ELEMENT -569 ), elementGroupBits( -570 ElementGroup.BLOCK, ElementGroup.INLINE -571 )); -572 defineElement( -573 "link", false, elementGroupBits( -574 ElementGroup.INLINE, ElementGroup.HEAD_CONTENT -575 ), 0); -576 defineElement( -577 "listing", false, elementGroupBits( -578 ElementGroup.BLOCK -579 ), elementGroupBits( -580 ElementGroup.INLINE -581 )); -582 defineElement( -583 "map", false, elementGroupBits( -584 ElementGroup.INLINE -585 ), elementGroupBits( -586 ElementGroup.BLOCK, ElementGroup.AREA_ELEMENT -587 )); -588 defineElement( -589 "meta", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); -590 defineElement( -591 "nobr", false, elementGroupBits( -592 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -593 ), elementGroupBits( -594 ElementGroup.INLINE -595 )); -596 defineElement( -597 "noframes", false, elementGroupBits( -598 ElementGroup.BLOCK, ElementGroup.TOP_CONTENT -599 ), elementGroupBits( -600 ElementGroup.BLOCK, ElementGroup.INLINE, -601 ElementGroup.TOP_CONTENT +519 "em", true, elementGroupBits( +520 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +521 ), elementGroupBits( +522 ElementGroup.INLINE +523 )); +524 defineElement( +525 "fieldset", false, elementGroupBits( +526 ElementGroup.BLOCK +527 ), elementGroupBits( +528 ElementGroup.BLOCK, ElementGroup.INLINE, +529 ElementGroup.LEGEND_ELEMENT +530 )); +531 defineElement( +532 "font", false, elementGroupBits( +533 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +534 ), elementGroupBits( +535 ElementGroup.INLINE +536 )); +537 defineElement( +538 "form", false, elementGroupBits( +539 ElementGroup.BLOCK, ElementGroup.FORM_ELEMENT +540 ), elementGroupBits( +541 ElementGroup.BLOCK, ElementGroup.INLINE, +542 ElementGroup.INLINE_MINUS_A, ElementGroup.TR_ELEMENT, +543 ElementGroup.TD_ELEMENT +544 )); +545 defineElement( +546 "h1", false, elementGroupBits( +547 ElementGroup.BLOCK +548 ), elementGroupBits( +549 ElementGroup.INLINE +550 )); +551 defineElement( +552 "h2", false, elementGroupBits( +553 ElementGroup.BLOCK +554 ), elementGroupBits( +555 ElementGroup.INLINE +556 )); +557 defineElement( +558 "h3", false, elementGroupBits( +559 ElementGroup.BLOCK +560 ), elementGroupBits( +561 ElementGroup.INLINE +562 )); +563 defineElement( +564 "h4", false, elementGroupBits( +565 ElementGroup.BLOCK +566 ), elementGroupBits( +567 ElementGroup.INLINE +568 )); +569 defineElement( +570 "h5", false, elementGroupBits( +571 ElementGroup.BLOCK +572 ), elementGroupBits( +573 ElementGroup.INLINE +574 )); +575 defineElement( +576 "h6", false, elementGroupBits( +577 ElementGroup.BLOCK +578 ), elementGroupBits( +579 ElementGroup.INLINE +580 )); +581 defineElement( +582 "head", false, elementGroupBits( +583 ElementGroup.TOP_CONTENT +584 ), elementGroupBits( +585 ElementGroup.HEAD_CONTENT +586 )); +587 defineElement( +588 "hr", false, elementGroupBits(ElementGroup.BLOCK), 0); +589 defineElement( +590 "html", false, 0, elementGroupBits(ElementGroup.TOP_CONTENT)); +591 defineElement( +592 "i", true, elementGroupBits( +593 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +594 ), elementGroupBits( +595 ElementGroup.INLINE +596 )); +597 defineElement( +598 "iframe", false, elementGroupBits( +599 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +600 ), elementGroupBits( +601 ElementGroup.BLOCK, ElementGroup.INLINE 602 )); 603 defineElement( -604 "noscript", false, elementGroupBits( -605 ElementGroup.BLOCK -606 ), elementGroupBits( -607 ElementGroup.BLOCK, ElementGroup.INLINE -608 )); -609 defineElement( -610 "object", false, elementGroupBits( -611 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A, -612 ElementGroup.HEAD_CONTENT -613 ), elementGroupBits( -614 ElementGroup.BLOCK, ElementGroup.INLINE, -615 ElementGroup.PARAM_ELEMENT +604 "img", false, elementGroupBits( +605 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +606 ), 0); +607 defineElement( +608 "input", false, elementGroupBits( +609 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +610 ), 0); +611 defineElement( +612 "ins", true, elementGroupBits( +613 ElementGroup.BLOCK, ElementGroup.INLINE +614 ), elementGroupBits( +615 ElementGroup.BLOCK, ElementGroup.INLINE 616 )); 617 defineElement( -618 "ol", false, elementGroupBits( -619 ElementGroup.BLOCK -620 ), elementGroupBits( -621 ElementGroup.LI_ELEMENT -622 )); -623 defineElement( -624 "optgroup", false, elementGroupBits( -625 ElementGroup.OPTIONS_ELEMENT -626 ), elementGroupBits( -627 ElementGroup.OPTIONS_ELEMENT -628 )); -629 defineElement( -630 "option", false, elementGroupBits( -631 ElementGroup.OPTIONS_ELEMENT, ElementGroup.OPTION_ELEMENT -632 ), 0); -633 defineElement( -634 "p", false, elementGroupBits( -635 ElementGroup.BLOCK, ElementGroup.P_ELEMENT -636 ), elementGroupBits( -637 ElementGroup.INLINE, ElementGroup.TABLE_ELEMENT -638 )); -639 defineElement( -640 "param", false, elementGroupBits(ElementGroup.PARAM_ELEMENT), 0); -641 defineElement( -642 "pre", false, elementGroupBits( -643 ElementGroup.BLOCK -644 ), elementGroupBits( -645 ElementGroup.INLINE -646 )); +618 "isindex", false, elementGroupBits(ElementGroup.INLINE), 0); +619 defineElement( +620 "kbd", true, elementGroupBits( +621 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +622 ), elementGroupBits( +623 ElementGroup.INLINE +624 )); +625 defineElement( +626 "label", false, elementGroupBits( +627 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +628 ), elementGroupBits( +629 ElementGroup.INLINE +630 )); +631 defineElement( +632 "legend", false, elementGroupBits( +633 ElementGroup.LEGEND_ELEMENT +634 ), elementGroupBits( +635 ElementGroup.INLINE +636 )); +637 ElementContainmentInfo LI = defineElement( +638 "li", false, elementGroupBits( +639 ElementGroup.LI_ELEMENT +640 ), elementGroupBits( +641 ElementGroup.BLOCK, ElementGroup.INLINE +642 )); +643 defineElement( +644 "link", false, elementGroupBits( +645 ElementGroup.INLINE, ElementGroup.HEAD_CONTENT +646 ), 0); 647 defineElement( -648 "q", true, elementGroupBits( -649 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +648 "listing", false, elementGroupBits( +649 ElementGroup.BLOCK 650 ), elementGroupBits( 651 ElementGroup.INLINE 652 )); 653 defineElement( -654 "s", true, elementGroupBits( -655 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +654 "map", false, elementGroupBits( +655 ElementGroup.INLINE 656 ), elementGroupBits( -657 ElementGroup.INLINE +657 ElementGroup.BLOCK, ElementGroup.AREA_ELEMENT 658 )); 659 defineElement( -660 "samp", true, elementGroupBits( -661 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -662 ), elementGroupBits( -663 ElementGroup.INLINE -664 )); -665 defineElement( -666 "script", false, elementGroupBits( -667 ElementGroup.BLOCK, ElementGroup.INLINE, -668 ElementGroup.INLINE_MINUS_A, ElementGroup.MIXED, -669 ElementGroup.TABLE_CONTENT, ElementGroup.HEAD_CONTENT, -670 ElementGroup.TOP_CONTENT, ElementGroup.AREA_ELEMENT, -671 ElementGroup.FORM_ELEMENT, ElementGroup.LEGEND_ELEMENT, -672 ElementGroup.LI_ELEMENT, ElementGroup.DL_PART, -673 ElementGroup.P_ELEMENT, ElementGroup.OPTIONS_ELEMENT, -674 ElementGroup.OPTION_ELEMENT, ElementGroup.PARAM_ELEMENT, -675 ElementGroup.TABLE_ELEMENT, ElementGroup.TR_ELEMENT, -676 ElementGroup.TD_ELEMENT, ElementGroup.COL_ELEMENT -677 ), 0); -678 defineElement( -679 "select", false, elementGroupBits( -680 ElementGroup.INLINE -681 ), elementGroupBits( -682 ElementGroup.OPTIONS_ELEMENT -683 )); -684 defineElement( -685 "small", true, elementGroupBits( -686 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -687 ), elementGroupBits( -688 ElementGroup.INLINE -689 )); -690 defineElement( -691 "span", false, elementGroupBits( -692 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -693 ), elementGroupBits( -694 ElementGroup.INLINE -695 )); -696 defineElement( -697 "strike", true, elementGroupBits( -698 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -699 ), elementGroupBits( -700 ElementGroup.INLINE -701 )); -702 defineElement( -703 "strong", true, elementGroupBits( -704 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -705 ), elementGroupBits( -706 ElementGroup.INLINE -707 )); -708 defineElement( -709 "style", false, elementGroupBits( -710 ElementGroup.INLINE, ElementGroup.HEAD_CONTENT -711 ), 0); -712 defineElement( -713 "sub", true, elementGroupBits( -714 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -715 ), elementGroupBits( -716 ElementGroup.INLINE -717 )); -718 defineElement( -719 "sup", true, elementGroupBits( -720 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -721 ), elementGroupBits( -722 ElementGroup.INLINE -723 )); -724 defineElement( -725 "table", false, elementGroupBits( -726 ElementGroup.BLOCK, ElementGroup.TABLE_ELEMENT -727 ), elementGroupBits( -728 ElementGroup.TABLE_CONTENT, ElementGroup.FORM_ELEMENT -729 )); -730 defineElement( -731 "tbody", false, elementGroupBits( -732 ElementGroup.TABLE_CONTENT -733 ), elementGroupBits( -734 ElementGroup.TR_ELEMENT -735 )); -736 defineElement( -737 "td", false, elementGroupBits( -738 ElementGroup.TD_ELEMENT -739 ), elementGroupBits( -740 ElementGroup.BLOCK, ElementGroup.INLINE -741 )); -742 defineElement( -743 "textarea", false, -744 // No, a textarea cannot be inside a link. -745 elementGroupBits(ElementGroup.INLINE), 0); -746 defineElement( -747 "tfoot", false, elementGroupBits( -748 ElementGroup.TABLE_CONTENT +660 "meta", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); +661 defineElement( +662 "nobr", false, elementGroupBits( +663 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +664 ), elementGroupBits( +665 ElementGroup.INLINE +666 )); +667 defineElement( +668 "noframes", false, elementGroupBits( +669 ElementGroup.BLOCK, ElementGroup.TOP_CONTENT +670 ), elementGroupBits( +671 ElementGroup.BLOCK, ElementGroup.INLINE, +672 ElementGroup.TOP_CONTENT +673 )); +674 defineElement( +675 "noscript", false, elementGroupBits( +676 ElementGroup.BLOCK +677 ), elementGroupBits( +678 ElementGroup.BLOCK, ElementGroup.INLINE +679 )); +680 defineElement( +681 "object", false, elementGroupBits( +682 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A, +683 ElementGroup.HEAD_CONTENT +684 ), elementGroupBits( +685 ElementGroup.BLOCK, ElementGroup.INLINE, +686 ElementGroup.PARAM_ELEMENT +687 )); +688 defineElement( +689 "ol", false, elementGroupBits( +690 ElementGroup.BLOCK +691 ), elementGroupBits( +692 ElementGroup.LI_ELEMENT +693 ), +694 LI); +695 defineElement( +696 "optgroup", false, elementGroupBits( +697 ElementGroup.OPTIONS_ELEMENT +698 ), elementGroupBits( +699 ElementGroup.OPTIONS_ELEMENT +700 )); +701 defineElement( +702 "option", false, elementGroupBits( +703 ElementGroup.OPTIONS_ELEMENT, ElementGroup.OPTION_ELEMENT +704 ), 0); +705 defineElement( +706 "p", false, elementGroupBits( +707 ElementGroup.BLOCK, ElementGroup.P_ELEMENT +708 ), elementGroupBits( +709 ElementGroup.INLINE, ElementGroup.TABLE_ELEMENT +710 )); +711 defineElement( +712 "param", false, elementGroupBits(ElementGroup.PARAM_ELEMENT), 0); +713 defineElement( +714 "pre", false, elementGroupBits( +715 ElementGroup.BLOCK +716 ), elementGroupBits( +717 ElementGroup.INLINE +718 )); +719 defineElement( +720 "q", true, elementGroupBits( +721 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +722 ), elementGroupBits( +723 ElementGroup.INLINE +724 )); +725 defineElement( +726 "s", true, elementGroupBits( +727 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +728 ), elementGroupBits( +729 ElementGroup.INLINE +730 )); +731 defineElement( +732 "samp", true, elementGroupBits( +733 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +734 ), elementGroupBits( +735 ElementGroup.INLINE +736 )); +737 defineElement( +738 "script", false, elementGroupBits( +739 ElementGroup.BLOCK, ElementGroup.INLINE, +740 ElementGroup.INLINE_MINUS_A, ElementGroup.MIXED, +741 ElementGroup.TABLE_CONTENT, ElementGroup.HEAD_CONTENT, +742 ElementGroup.TOP_CONTENT, ElementGroup.AREA_ELEMENT, +743 ElementGroup.FORM_ELEMENT, ElementGroup.LEGEND_ELEMENT, +744 ElementGroup.LI_ELEMENT, ElementGroup.DL_PART, +745 ElementGroup.P_ELEMENT, ElementGroup.OPTIONS_ELEMENT, +746 ElementGroup.OPTION_ELEMENT, ElementGroup.PARAM_ELEMENT, +747 ElementGroup.TABLE_ELEMENT, ElementGroup.TR_ELEMENT, +748 ElementGroup.TD_ELEMENT, ElementGroup.COL_ELEMENT 749 ), elementGroupBits( -750 ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, -751 ElementGroup.TD_ELEMENT -752 )); -753 defineElement( -754 "th", false, elementGroupBits( -755 ElementGroup.TD_ELEMENT -756 ), elementGroupBits( -757 ElementGroup.BLOCK, ElementGroup.INLINE -758 )); -759 defineElement( -760 "thead", false, elementGroupBits( -761 ElementGroup.TABLE_CONTENT -762 ), elementGroupBits( -763 ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, -764 ElementGroup.TD_ELEMENT -765 )); -766 defineElement( -767 "title", false, elementGroupBits(ElementGroup.HEAD_CONTENT), 0); -768 defineElement( -769 "tr", false, elementGroupBits( -770 ElementGroup.TABLE_CONTENT, ElementGroup.TR_ELEMENT -771 ), elementGroupBits( -772 ElementGroup.FORM_ELEMENT, ElementGroup.TD_ELEMENT -773 )); -774 defineElement( -775 "tt", true, elementGroupBits( -776 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -777 ), elementGroupBits( -778 ElementGroup.INLINE -779 )); -780 defineElement( -781 "u", true, elementGroupBits( -782 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -783 ), elementGroupBits( -784 ElementGroup.INLINE -785 )); -786 defineElement( -787 "ul", false, elementGroupBits( -788 ElementGroup.BLOCK -789 ), elementGroupBits( -790 ElementGroup.LI_ELEMENT -791 )); -792 defineElement( -793 "var", false, elementGroupBits( -794 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -795 ), elementGroupBits( -796 ElementGroup.INLINE -797 )); -798 defineElement( -799 "video", false, elementGroupBits( -800 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -801 ), 0); -802 defineElement( -803 "wbr", false, elementGroupBits( -804 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A -805 ), 0); -806 defineElement( -807 "xmp", false, elementGroupBits( -808 ElementGroup.BLOCK -809 ), elementGroupBits( -810 ElementGroup.INLINE -811 )); -812 -813 } -814 } -815 } +750 ElementGroup.CHARACTER_DATA)); +751 defineElement( +752 "select", false, elementGroupBits( +753 ElementGroup.INLINE +754 ), elementGroupBits( +755 ElementGroup.OPTIONS_ELEMENT +756 )); +757 defineElement( +758 "small", true, elementGroupBits( +759 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +760 ), elementGroupBits( +761 ElementGroup.INLINE +762 )); +763 defineElement( +764 "span", false, elementGroupBits( +765 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +766 ), elementGroupBits( +767 ElementGroup.INLINE +768 )); +769 defineElement( +770 "strike", true, elementGroupBits( +771 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +772 ), elementGroupBits( +773 ElementGroup.INLINE +774 )); +775 defineElement( +776 "strong", true, elementGroupBits( +777 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +778 ), elementGroupBits( +779 ElementGroup.INLINE +780 )); +781 defineElement( +782 "style", false, elementGroupBits( +783 ElementGroup.INLINE, ElementGroup.HEAD_CONTENT +784 ), elementGroupBits( +785 ElementGroup.CHARACTER_DATA +786 )); +787 defineElement( +788 "sub", true, elementGroupBits( +789 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +790 ), elementGroupBits( +791 ElementGroup.INLINE +792 )); +793 defineElement( +794 "sup", true, elementGroupBits( +795 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +796 ), elementGroupBits( +797 ElementGroup.INLINE +798 )); +799 defineElement( +800 "table", false, elementGroupBits( +801 ElementGroup.BLOCK, ElementGroup.TABLE_ELEMENT +802 ), elementGroupBits( +803 ElementGroup.TABLE_CONTENT, ElementGroup.FORM_ELEMENT +804 )); +805 defineElement( +806 "tbody", false, elementGroupBits( +807 ElementGroup.TABLE_CONTENT +808 ), elementGroupBits( +809 ElementGroup.TR_ELEMENT +810 )); +811 ElementContainmentInfo TD = defineElement( +812 "td", false, elementGroupBits( +813 ElementGroup.TD_ELEMENT +814 ), elementGroupBits( +815 ElementGroup.BLOCK, ElementGroup.INLINE +816 )); +817 defineElement( +818 "textarea", false, +819 // No, a textarea cannot be inside a link. +820 elementGroupBits(ElementGroup.INLINE), +821 elementGroupBits(ElementGroup.CHARACTER_DATA)); +822 defineElement( +823 "tfoot", false, elementGroupBits( +824 ElementGroup.TABLE_CONTENT +825 ), elementGroupBits( +826 ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, +827 ElementGroup.TD_ELEMENT +828 )); +829 defineElement( +830 "th", false, elementGroupBits( +831 ElementGroup.TD_ELEMENT +832 ), elementGroupBits( +833 ElementGroup.BLOCK, ElementGroup.INLINE +834 )); +835 defineElement( +836 "thead", false, elementGroupBits( +837 ElementGroup.TABLE_CONTENT +838 ), elementGroupBits( +839 ElementGroup.FORM_ELEMENT, ElementGroup.TR_ELEMENT, +840 ElementGroup.TD_ELEMENT +841 )); +842 defineElement( +843 "title", false, elementGroupBits(ElementGroup.HEAD_CONTENT), +844 elementGroupBits(ElementGroup.CHARACTER_DATA)); +845 defineElement( +846 "tr", false, elementGroupBits( +847 ElementGroup.TABLE_CONTENT, ElementGroup.TR_ELEMENT +848 ), elementGroupBits( +849 ElementGroup.FORM_ELEMENT, ElementGroup.TD_ELEMENT +850 ), +851 TD); +852 defineElement( +853 "tt", true, elementGroupBits( +854 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +855 ), elementGroupBits( +856 ElementGroup.INLINE +857 )); +858 defineElement( +859 "u", true, elementGroupBits( +860 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +861 ), elementGroupBits( +862 ElementGroup.INLINE +863 )); +864 defineElement( +865 "ul", false, elementGroupBits( +866 ElementGroup.BLOCK +867 ), elementGroupBits( +868 ElementGroup.LI_ELEMENT +869 ), +870 LI); +871 defineElement( +872 "var", false, elementGroupBits( +873 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +874 ), elementGroupBits( +875 ElementGroup.INLINE +876 )); +877 defineElement( +878 "video", false, elementGroupBits( +879 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +880 ), 0); +881 defineElement( +882 "wbr", false, elementGroupBits( +883 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A +884 ), 0); +885 defineElement( +886 "xmp", false, elementGroupBits( +887 ElementGroup.BLOCK +888 ), elementGroupBits( +889 ElementGroup.INLINE +890 )); +891 +892 } +893 +894 private static final ElementContainmentInfo CHARACTER_DATA +895 = new ElementContainmentInfo( +896 "#text", false, +897 elementGroupBits( +898 ElementGroup.INLINE, ElementGroup.INLINE_MINUS_A, +899 ElementGroup.BLOCK, ElementGroup.CHARACTER_DATA), +900 0, null); +901 } +902 } diff --git a/distrib/lib/owasp-java-html-sanitizer-src.jar b/distrib/lib/owasp-java-html-sanitizer-src.jar index 90c47a5..890ca4b 100644 Binary files a/distrib/lib/owasp-java-html-sanitizer-src.jar and b/distrib/lib/owasp-java-html-sanitizer-src.jar differ diff --git a/distrib/lib/owasp-java-html-sanitizer.jar b/distrib/lib/owasp-java-html-sanitizer.jar index 941d178..379c3b2 100644 Binary files a/distrib/lib/owasp-java-html-sanitizer.jar and b/distrib/lib/owasp-java-html-sanitizer.jar differ -- cgit v1.2.3