From 258fc44ab32fa9318d433c4ed44f47e04f4b1fa0 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Fri, 10 Dec 2021 18:06:24 -0800 Subject: [PATCH 1/9] Updating to allow empty allow lists, and adding tests --- src/Definition/HTMLDefinition.hack | 2 +- tests/AllowedTest.hack | 48 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/AllowedTest.hack diff --git a/src/Definition/HTMLDefinition.hack b/src/Definition/HTMLDefinition.hack index 062066e..5322aa5 100644 --- a/src/Definition/HTMLDefinition.hack +++ b/src/Definition/HTMLDefinition.hack @@ -1921,7 +1921,7 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier\HTMLPurifier_Definition { } } - if ($allowed_elements is dict<_, _> && !C\is_empty($allowed_elements)) { + if ($allowed_elements is dict<_, _>) { foreach ($this->info as $name => $d) { if (!C\contains_key($allowed_elements, $name)) { unset($this->info[$name]); diff --git a/tests/AllowedTest.hack b/tests/AllowedTest.hack new file mode 100644 index 0000000..dada234 --- /dev/null +++ b/tests/AllowedTest.hack @@ -0,0 +1,48 @@ +/* Created by Nikita Ashok and Jake Polacek on 08/04/2020 */ + +namespace HTMLPurifier\_Private\Tests; + +use function Facebook\FBExpect\expect; +use type Facebook\HackTest\HackTest; +use namespace HTMLPurifier; +use namespace HTMLPurifier\{Strategy, Token, Lexer}; + +class AllowedTest extends HackTest { + public function testEmptyAllowedList(): void { + echo "\ntestDefaultAllowed()..."; + //porting over first config classes.... + $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); + $config->def->defaults['HTML.AllowedElements'] = dict[]; + + $purifier = new HTMLPurifier\HTMLPurifier($config); + $dirty_html = '

Title

Go to Slack'; + $clean_html = $purifier->purify($dirty_html); + expect($clean_html)->toEqual('TitleGo to Slack'); + echo "finished.\n\n"; + } + + public function testStripTagsNotInDefaultPolicy(): void { + echo "\ntestStripTagsNotInDefaultPolicy()..."; + //porting over first config classes.... + $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); + + $purifier = new HTMLPurifier\HTMLPurifier($config); + $dirty_html = 'test'; + $clean_html = $purifier->purify($dirty_html); + expect($clean_html)->toEqual('test'); + echo "finished.\n\n"; + } + + public function testCustomTagsWithAttributes(): void { + echo "\ntestCustomTagsWithAttributes()..."; + //porting over first config classes.... + $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); + $config->def->defaults['HTML.Allowed'] = 'img[src|alt]'; + + $purifier = new HTMLPurifier\HTMLPurifier($config); + $dirty_html = 'testhello'; + $clean_html = $purifier->purify($dirty_html); + expect($clean_html)->toEqual('testhelloalert(1);'); + echo "finished.\n\n"; + } +} From 73b02be1fbc320f46cf6a78061a692566c5bbf6c Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Wed, 15 Dec 2021 18:24:07 -0800 Subject: [PATCH 2/9] Adding an HTMLSanitizer policy and tweaking logic to pass tests --- src/Definition/HTMLDefinition.hack | 2 +- src/HTMLSanitizerPolicy.hack | 448 +++++++++++++++++++++++++++ src/Injector.hack | 22 +- tests/AllowedTest.hack | 18 +- tests/CommentRemovalTest.hack | 107 +++++-- tests/DOMLexTest.hack | 4 +- tests/HTMLPurifierTest.hack | 480 ++++++++++++----------------- tests/InjectorTest.hack | 42 ++- 8 files changed, 769 insertions(+), 354 deletions(-) create mode 100644 src/HTMLSanitizerPolicy.hack diff --git a/src/Definition/HTMLDefinition.hack b/src/Definition/HTMLDefinition.hack index 5322aa5..23e3a0b 100644 --- a/src/Definition/HTMLDefinition.hack +++ b/src/Definition/HTMLDefinition.hack @@ -1916,7 +1916,7 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier\HTMLPurifier_Definition { C\is_empty($allowed_attributes) ) { $allowed = (string)$config->def->defaults['HTML.Allowed']; - if ($allowed !== '') { + if ($allowed is string && $allowed !== '') { list($allowed_elements, $allowed_attributes) = $this->parseTinyMCEAllowedList($allowed); } } diff --git a/src/HTMLSanitizerPolicy.hack b/src/HTMLSanitizerPolicy.hack new file mode 100644 index 0000000..ed49fb7 --- /dev/null +++ b/src/HTMLSanitizerPolicy.hack @@ -0,0 +1,448 @@ +namespace HTMLPurifier; +use namespace HH\Lib\C; + +enum html_tags_t: string { + + //Main root + HTML = "html"; + + //Document metadata + BASE = "base"; + HEAD = "head"; + LINK = "link"; + META = "meta"; + STYLE = "style"; + TITLE = "title"; + + //Sectioning root + BODY = "body"; + + //Content sectioningSection + ADDRESS = "address"; + ARTICLE = "article"; + ASIDE = "aside"; + FOOTER = "footer"; + HEADER = "header"; + H1 = "h1"; + H2 = "h2"; + H3 = "h3"; + H4 = "h4"; + H5 = "h5"; + H6 = "h6"; + HGROUP = "hgroup"; + MAIN = "main"; + NAV = "nav"; + SECTION = "section"; + + //Text content + BLOCKQUOTE = "blockquote"; + DD = "dd"; + DIR = "dir"; + DIV = "div"; + DL = "dl"; + DT = "dt"; + FIGCAPTION = "figcaption"; + FIGURE = "figure"; + HR = "hr"; + LI = "li"; + OL = "ol"; + P = "p"; + PRE = "pre"; + UL = "ul"; + + //Inline text semantics + A = "a"; + ABBR = "abbr"; + B = "b"; + BDI = "bdi"; + BDO = "bdo"; + BR = "br"; + CITE = "cite"; + CODE = "code"; + DATA = "data"; + DFN = "dfn"; + EM = "em"; + I = "i"; + KBD = "kbd"; + MARK = "mark"; + Q = "q"; + RB = "rb"; + RP = "rp"; + RT = "rt"; + RTC = "rtc"; + RUBY = "ruby"; + S = "s"; + SAMP = "samp"; + SMALL = "small"; + SPAN = "span"; + STRONG = "strong"; + SUB = "sub"; + SUP = "sup"; + TIME = "time"; + /* HHAST_FIXME[EnumMemberNaming] */ tt = "tt"; + U = "u"; + VAR = "var"; + /* HHAST_FIXME[EnumMemberNaming] */ wbr = "wbr"; + + //Image and multimedia + AREA = "area"; + /* HHAST_FIXME[EnumMemberNaming] */ audio = "audio"; + IMG = "img"; + MAP = "map"; + TRACK = "track"; + VIDEO = "video"; + + //Embedded content + APPLET = "applet"; + EMBED = "embed"; + IFRAME = "iframe"; + NOEMBED = "noembed"; + OBJECT = "object"; + PARAM = "param"; + PICTURE = "picture"; + SOURCE = "source"; + + //Scripting + CANVAS = "canvas"; + NOSCRIPT = "noscript"; + SCRIPT = "script"; + + //Demarcating edits + DEL = "del"; + INS = "ins"; + + //Table content + CAPTION = "caption"; + COL = "col"; + COLGROUP = "colgroup"; + TABLE = "table"; + TBODY = "tbody"; + TD = "td"; + TFOOT = "tfoot"; + TH = "th"; + THEAD = "thead"; + TR = "tr"; + + //Forms + BUTTON = "button"; + DATALIST = "datalist"; + FIELDSET = "fieldset"; + FORM = "form"; + INPUT = "input"; + LABEL = "label"; + LEGEND = "legend"; + METER = "meter"; + OPTGROUP = "optgroup"; + OPTION = "option"; + OUTPUT = "output"; + PROGRESS = "progress"; + SELECT = "select"; + TEXTAREA = "textarea"; + + //Interactive elements + DETAILS = "details"; + DIALOG = "dialog"; + MENU = "menu"; + MENUITEM = "menuitem"; + SUMMARY = "summary"; + + //Web Components + CONTENT = "content"; + ELEMENT = "element"; + SHADOW = "shadow"; + SLOT = "slot"; + TEMPLATE = "template"; + + //Obsolete and deprecated elements + ACRONYM = "acronym"; + BASEFONT = "basefont"; + BGSOUND = "bgsound"; + BIG = "big"; + BLINK = "blink"; + CENTER = "center"; + COMMAND = "command"; + FONT = "font"; + FRAME = "frame"; + FRAMESET = "frameset"; + IMAGE = "image"; + ISINDEX = "isindex"; + KEYGEN = "keygen"; + LISTING = "listing"; + MARQUEE = "marquee"; + MULTICOL = "multicol"; + NEXTID = "nextid"; + NOBR = "nobr"; + NOFRAMES = "noframes"; + PLAINTEXT = "plaintext"; + SPACER = "spacer"; + STRIKE = "strike"; + XMP = "xmp"; +} + +enum html_attributes_t: string { + ACCEPT = "accept"; + ACCEPTCHARSET = "accept-charset"; + ACCESSKEY = "accesskey"; + ACTION = "action"; + ALIGN = "align"; + ALLOW = "allow"; + ALLOWFULLSCREEN = 'allowfullscreen'; + ALT = "alt"; + ASYNC = "async"; + AUTOCAPITALIZE = "autocapitalize"; + AUTOCOMPLETE = "autocomplete"; + AUTOFOCUS = "autofocus"; + AUTOPLAY = "autoplay"; + BGCOLOR = "bgcolor"; + BORDER = "border"; + BUFFERED = "buffered"; + CHALLENGE = "challenge"; + CHARSET = "charset"; + CHECKED = "checked"; + CITE = "cite"; + CLASSES = "class"; // cannot be named "CLASS" + CODE = "code"; + CODEBASE = "codebase"; + COLOR = "color"; + COLS = "cols"; + COLSPAN = "colspan"; + CONTENT = "content"; + CONTENTEDITABLE = "contenteditable"; + CONTEXTMENU = "contextmenu"; + CONTROLS = "controls"; + COORDS = "coords"; + CROSSORIGIN = "crossorigin"; + CSP = "csp"; + DATA = "data"; + DATETIME = "datetime"; + DECODING = "decoding"; + DEFAULT = "default"; + DEFER = "defer"; + DIR = "dir"; + DIRNAME = "dirname"; + DISABLED = "disabled"; + DOWNLOAD = "download"; + DRAGGABLE = "draggable"; + DROPZONE = "dropzone"; + ENCTYPE = "enctype"; + FOR = "for"; + FORM = "form"; + FORMACTION = "formaction"; + HEADERS = "headers"; + HEIGHT = "height"; + HIDDEN = "hidden"; + HIGH = "high"; + HREF = "href"; + HREFLANG = "hreflang"; + HTTPEQUIV = "http-equiv"; + ICON = "icon"; + ID = "id"; + IMPORTANCE = "importance"; + INTEGRITY = "integrity"; + ISMAP = "ismap"; + ITEMPROP = "itemprop"; + KEYTYPE = "keytype"; + KIND = "kind"; + LABEL = "label"; + LANG = "lang"; + LANGUAGE = "language"; + LAZYLOAD = "lazyload"; + LIST = "list"; + LOOP = "loop"; + LOW = "low"; + MANIFEST = "manifest"; + MAX = "max"; + MAXLENGTH = "maxlength"; + MINLENGTH = "minlength"; + MEDIA = "media"; + METHOD = "method"; + MIN = "min"; + MULTIPLE = "multiple"; + MUTED = "muted"; + NAME = "name"; + NOVALIDATE = "novalidate"; + OPEN = "open"; + OPTIMUM = "optimum"; + PATTERN = "pattern"; + PING = "ping"; + PLACEHOLDER = "placeholder"; + POSTER = "poster"; + PRELOAD = "preload"; + RADIOGROUP = "radiogroup"; + READONLY = "readonly"; + REFERRERPOLICY = "referrerpolicy"; + REL = "rel"; + REQUIRED = "required"; + REVERSED = "reversed"; + ROWS = "rows"; + ROWSPAN = "rowspan"; + SANDBOX = "sandbox"; + SCOPE = "scope"; + SCOPED = "scoped"; + SELECTED = "selected"; + SHAPE = "shape"; + SIZE = "size"; + SIZES = "sizes"; + SLOT = "slot"; + SPAN = "span"; + SPELLCHECK = "spellcheck"; + SRC = "src"; + SRCDOC = "srcdoc"; + SRCLANG = "srclang"; + SRCSET = "srcset"; + START = "start"; + STEP = "step"; + STYLE = "style"; + SUMMARY = "summary"; + TABINDEX = "tabindex"; + TARGET = "target"; + TITLE = "title"; + TRANSLATE = "translate"; + TYPE = "type"; + USEMAP = "usemap"; + VALUE = "value"; + WIDTH = "width"; + WRAP = "wrap"; + DATA_CHECKED = "data-checked"; + DATA_CLOG_CLICK = "data-clog-click"; + DATA_CLOG_UI_ELEMENT = "data-clog-ui-element"; + DATA_CLOG_UI_STEP = "data-clog-ui-step"; +} + +type html_input_t = shape( + 'dirty_html' => string, + 'policy' => HTMLSanitizerPolicy, +); + +/* +* Default policy constant. This is the list of default allowed tags and +* attributes when calling `HTMLSanitizerPolicy::fromEmpty()` + */ +const dict> HTML_SANITIZER_DEFAULT_POLICY = dict[ + html_tags_t::P => keyset[], + html_tags_t::B => keyset[], + html_tags_t::I => keyset[], +]; + +final class HTMLSanitizerException extends \Exception {} + +/** + * HTMLSanitizerPolicy lets you define allowlist policy settings for html purifier + */ + +final class HTMLSanitizerPolicy { + + private dict> $html_purifier_policy = dict[]; + + /** + * Construct policy class from set of predefined policy allowlist + * + * @param html_purifier_policy_from_t $policyFrom select from predefined policy + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public function __construct(dict> $policy) { + foreach ($policy as $allowed_tag => $allowed_attributes) { + $this->addAllowedTagWithAttributes($allowed_tag, $allowed_attributes); + } + } + + /** + * Use the default allowlist policy. + * + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public static function fromDefault(): HTMLSanitizerPolicy { + $html_purifier_policy = HTML_SANITIZER_DEFAULT_POLICY; + return new HTMLSanitizerPolicy($html_purifier_policy); + } + + /** + * Use the empty allowlist policy. + * + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public static function fromEmpty(): HTMLSanitizerPolicy { + return new HTMLSanitizerPolicy(dict[]); + } + + /** + * Add a single allowed tag to the allowlist. This only allows the tag with + * any default safe attributes that the library sets. + * + * @param html_tags_t $tag + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public function addAllowedTag(html_tags_t $allowed_tag): HTMLSanitizerPolicy { + // Skip if we already have the same tag in the policy + if (!C\contains_key($this->html_purifier_policy, $allowed_tag)) { + $this->html_purifier_policy[$allowed_tag] = keyset[]; + } else { + throw new HTMLSanitizerException("html tag \"$allowed_tag\" already exist in the policy"); + } + return $this; + } + + /** + * Add multiple allowed tags to the allowlist. This only allows the tags with + * any default safe attributes that the library sets. + * + * @param keyset $allowed_tags + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public function addAllowedTags(keyset $allowed_tags): HTMLSanitizerPolicy { + foreach ($allowed_tags as $allowed_tag) { + $this->addAllowedTag($allowed_tag); + } + return $this; + } + + /** + * Add a tag with allowed attributes to the allowlist + * + * @param keyset $allowed_tags + * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object + */ + public function addAllowedTagWithAttributes( + html_tags_t $tag, + keyset $attributes, + ): HTMLSanitizerPolicy { + $this->addAllowedTag($tag); + foreach ($attributes as $attribute) { + $this->html_purifier_policy[$tag][] = $attribute; + } + return $this; + } + + public function addAllowedTagsWithAttributes( + dict> $allowed_tags, + ): HTMLSanitizerPolicy { + foreach ($allowed_tags as $tag => $attributes) { + $this->addAllowedTagWithAttributes($tag, $attributes); + } + return $this; + } + + /** + * This function maps the object from $html_purifier_policy to the Policy + * object in htmlpurifier-hack. + * @return Policy object for htmlpurifier-hack + */ + public function constructPolicy(): HTMLPurifier_Policy { + /** + * Do series of loop on each keys and items in $html_purifier_policy to map + * and populate the Policy object. The loop also converts the tags and + * attributes type to string as used by the Policy object + */ + $allowed_tags_attributes = dict[]; + foreach ($this->html_purifier_policy as $tag => $attributes) { + $list_attributes = vec[]; + foreach ($attributes as $attribute) { + $list_attributes[] = (string)$attribute; + } + $allowed_tags_attributes[(string)$tag] = $list_attributes; + } + $policy_message = new HTMLPurifier_Policy($allowed_tags_attributes); + return $policy_message; + } + +} diff --git a/src/Injector.hack b/src/Injector.hack index 919468e..5e9cb34 100644 --- a/src/Injector.hack +++ b/src/Injector.hack @@ -2,6 +2,7 @@ namespace HTMLPurifier; use namespace HTMLPurifier\Definition; +use HH; use namespace HH\Lib\C; use namespace Facebook\TypeAssert; @@ -112,31 +113,18 @@ abstract class HTMLPurifier_Injector { */ public function checkNeeded(HTMLPurifier_Config $config): string { $def = TypeAssert\matches($config->getHTMLDefinition()); - $i = 0; - $index = 0; foreach ($this->needed as $element => $attributes) { - if ($i is int) { - $i = $element; + if (!HH\idx($def->info, $element)) { + return $element; } - if ($i is string && !C\contains_key($def->info, $i)) { - return $i; - } - if (!($element is vec<_>)) { - $index++; - $i = $index; + if (!($attributes is vec<_>)) { continue; } foreach ($attributes as $name) { - if ( - $element is string && - C\contains_key($def->info, $element) && - !C\contains_key($def->info[$element]->attr, $name) - ) { + if (!HH\idx($def->info[$element]->attr, $name)) { return "$element.$name"; } } - $index++; - $i = $index; } return ''; } diff --git a/tests/AllowedTest.hack b/tests/AllowedTest.hack index dada234..09fed07 100644 --- a/tests/AllowedTest.hack +++ b/tests/AllowedTest.hack @@ -12,9 +12,8 @@ class AllowedTest extends HackTest { echo "\ntestDefaultAllowed()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $config->def->defaults['HTML.AllowedElements'] = dict[]; - - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

Title

Go to Slack'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('TitleGo to Slack'); @@ -25,8 +24,8 @@ class AllowedTest extends HackTest { echo "\ntestStripTagsNotInDefaultPolicy()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'test'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('test'); @@ -37,9 +36,12 @@ class AllowedTest extends HackTest { echo "\ntestCustomTagsWithAttributes()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $config->def->defaults['HTML.Allowed'] = 'img[src|alt]'; - - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::IMG, + keyset[HTMLPurifier\html_attributes_t::SRC, HTMLPurifier\html_attributes_t::ALT], + ); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'testhello'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('testhelloalert(1);'); diff --git a/tests/CommentRemovalTest.hack b/tests/CommentRemovalTest.hack index 9e77a3e..bf8e239 100644 --- a/tests/CommentRemovalTest.hack +++ b/tests/CommentRemovalTest.hack @@ -11,7 +11,8 @@ class CommentRemovalTest extends HackTest { public function testValidCommentRemoval(): void { echo "\nrunning testValidCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html1 = ''; $dirty_html2 = 'Hello World!'; $dirty_html3 = 'Hello World!'; @@ -28,7 +29,8 @@ class CommentRemovalTest extends HackTest { public function testParseErrorCommentRemoval(): void { echo "\nrunning testParseErrorCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html1 = ''; // abruptly closed comment $dirty_html2 = ''; // abruptly closed comment @@ -49,8 +51,18 @@ class CommentRemovalTest extends HackTest { public function testCure53PoCCommentRemoval(): void { echo "\nrunning testCure53PoCCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = new HTMLPurifier\HTMLPurifier_Policy(dict['a' => vec['id', 'name', 'href', 'target', 'rel']]); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::A, + keyset[ + HTMLPurifier\html_attributes_t::ID, + HTMLPurifier\html_attributes_t::NAME, + HTMLPurifier\html_attributes_t::HREF, + HTMLPurifier\html_attributes_t::TARGET, + HTMLPurifier\html_attributes_t::REL, + ], + ); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_poc1 = ''; $clean_html = $purifier->purify($dirty_html); @@ -262,10 +377,18 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testSanitizeHtmlWithIframeForSearchProtocolsPolicySet()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict["iframe" => vec["title", "width", "height", "src", "allowfullscreen"]], + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::IFRAME, + keyset[ + HTMLPurifier\html_attributes_t::TITLE, + HTMLPurifier\html_attributes_t::WIDTH, + HTMLPurifier\html_attributes_t::HEIGHT, + HTMLPurifier\html_attributes_t::SRC, + HTMLPurifier\html_attributes_t::ALLOWFULLSCREEN, + ], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); // Test1 clean iframe with usertesting domain with no protocol $dirty_html = ''; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); $expected_html = ''; @@ -326,11 +458,21 @@ class HTMLPurifierTest extends HackTest { public function testImagePolicyWithMissingAltAttribute(): void { echo "\nrunning testImagePolicyWithMissingAltAttribute()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy(dict[ - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ]); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::IMG, + keyset[ + HTMLPurifier\html_attributes_t::SRC, + HTMLPurifier\html_attributes_t::ALT, + HTMLPurifier\html_attributes_t::CLASSES, + HTMLPurifier\html_attributes_t::WIDTH, + HTMLPurifier\html_attributes_t::HEIGHT, + HTMLPurifier\html_attributes_t::SRCSET, + HTMLPurifier\html_attributes_t::SIZES, + ], + ); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = ''; $clean_html = $purifier->purify($dirty_html); @@ -343,72 +485,18 @@ class HTMLPurifierTest extends HackTest { public function testWebappPolicy(): void { echo "\nrunning testWebappPolicy()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); expect(true)->toNotBeNull(); echo "finished.\n\n"; } public function testSpecialCharacterValidateUTF8(): void { echo "\nrunning testSpecialCharacterValidateUTF8()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '
  • Just a sentence. •
  • Just a sentence.•
  • @@ -458,36 +546,9 @@ class HTMLPurifierTest extends HackTest { public function testQuote(): void { echo "\nrunning testWebappPolicy()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    how to use the "at" html sanitizerHow it works

    '; $clean_html = $purifier->purify($dirty_html); @@ -499,36 +560,9 @@ class HTMLPurifierTest extends HackTest { public function testRel(): void { echo "\nrunning testRel()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -538,36 +572,9 @@ class HTMLPurifierTest extends HackTest { public function testAtagTargetAttribute(): void { echo "\nrunning testAtagTargetAttribute()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -577,36 +584,9 @@ class HTMLPurifierTest extends HackTest { public function testAtagNoChange(): void { echo "\nrunning testAtagNoChange()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -616,36 +596,9 @@ class HTMLPurifierTest extends HackTest { public function testAtagStripAdd(): void { echo "\nrunning testAtagStripAdd()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -655,36 +608,9 @@ class HTMLPurifierTest extends HackTest { public function testAtagStripLeave(): void { echo "\nrunning testAtagStripLeave()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -694,36 +620,9 @@ class HTMLPurifierTest extends HackTest { public function testAtagNoTarget(): void { echo "\nrunning testAtagNoTarget()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy( - dict[ - 'b' => vec[], - 'ul' => vec[], - 'li' => vec[], - 'ol' => vec[], - 'h2' => vec[], - 'h4' => vec[], - 'br' => vec[], - 'div' => vec[], - 'strong' => vec[], - 'del' => vec[], - 'em' => vec[], - 'pre' => vec[], - 'code' => vec[], - 'table' => vec[], - 'tbody' => vec[], - 'td' => vec[], - 'th' => vec[], - 'thead' => vec[], - 'tr' => vec[], - 'a' => vec['id', 'name', 'href', 'target', 'rel'], - 'h3' => vec['class'], - 'p' => vec['class'], - 'aside' => vec['class'], - 'img' => vec['src', 'alt', 'class', 'width', 'height', 'srcset', 'sizes'], - ], - ); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = $this->standardPolicy(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '

    '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

    '; @@ -735,7 +634,18 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagNoTarget()..."; $policy = new HTMLPurifier\HTMLPurifier_Policy(dict['a' => vec['id', 'name', 'href', 'target', 'rel']]); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::A, + keyset[ + HTMLPurifier\html_attributes_t::ID, + HTMLPurifier\html_attributes_t::NAME, + HTMLPurifier\html_attributes_t::HREF, + HTMLPurifier\html_attributes_t::TARGET, + HTMLPurifier\html_attributes_t::REL, + ], + ); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = ''; $clean_html = $purifier->purify($dirty_html); $expected_html = ''; diff --git a/tests/InjectorTest.hack b/tests/InjectorTest.hack index 6998088..dcb6c9e 100644 --- a/tests/InjectorTest.hack +++ b/tests/InjectorTest.hack @@ -8,7 +8,8 @@ class InjectorTest extends HackTest { private function assertAutoParagraphResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.AutoParagraph"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -18,7 +19,9 @@ class InjectorTest extends HackTest { private function assertDisplayURIResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTag(HTMLPurifier\html_tags_t::A); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.DisplayLinkURI"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -28,7 +31,8 @@ class InjectorTest extends HackTest { private function assertRemoveEmptyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.RemoveEmpty"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -38,7 +42,12 @@ class InjectorTest extends HackTest { private function assertPurifierLinkifyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTags(keyset[HTMLPurifier\html_tags_t::DIV, HTMLPurifier\html_tags_t::SPAN]); + $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[ + HTMLPurifier\html_attributes_t::HREF, + ]); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.PurifierLinkify"] = true; $config->def->defaults["AutoFormat.PurifierLinkify.DocURL"] = '#%s'; $clean_html = $purifier->purify($dirty); @@ -49,7 +58,12 @@ class InjectorTest extends HackTest { private function assertLinkifyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTag(HTMLPurifier\html_tags_t::SPAN); + $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[ + HTMLPurifier\html_attributes_t::HREF, + ]); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.Linkify"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -59,8 +73,19 @@ class InjectorTest extends HackTest { private function assertRemoveSpansWithoutAttributesResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); - $config->def->defaults['HTML.Allowed'] = 'span[class],div,p,strong,em'; + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy->addAllowedTags(keyset[ + HTMLPurifier\html_tags_t::DIV, + HTMLPurifier\html_tags_t::P, + HTMLPurifier\html_tags_t::STRONG, + HTMLPurifier\html_tags_t::EM, + ]); + $policy->addAllowedTagWithAttributes( + HTMLPurifier\html_tags_t::SPAN, + keyset[HTMLPurifier\html_attributes_t::CLASSES], + ); + // $config->def->defaults['HTML.Allowed'] = 'span[class],div,p,strong,em'; + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.RemoveSpansWithoutAttributes"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -70,7 +95,8 @@ class InjectorTest extends HackTest { private function assertSafeObjectResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config); + $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.Custom"] = vec[new Injector\HTMLPurifier_Injector_SafeObject()]; $config->def->defaults["HTML.Trusted"] = true; $clean_html = $purifier->purify($dirty); From 2e6234531bff2faa411c1acc20aac907988d3155 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Wed, 15 Dec 2021 18:37:16 -0800 Subject: [PATCH 3/9] removing hhast_fixme for the linter --- src/HTMLSanitizerPolicy.hack | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HTMLSanitizerPolicy.hack b/src/HTMLSanitizerPolicy.hack index ed49fb7..c827645 100644 --- a/src/HTMLSanitizerPolicy.hack +++ b/src/HTMLSanitizerPolicy.hack @@ -79,14 +79,14 @@ enum html_tags_t: string { SUB = "sub"; SUP = "sup"; TIME = "time"; - /* HHAST_FIXME[EnumMemberNaming] */ tt = "tt"; + TT = "tt"; U = "u"; VAR = "var"; - /* HHAST_FIXME[EnumMemberNaming] */ wbr = "wbr"; + WBR = "wbr"; //Image and multimedia AREA = "area"; - /* HHAST_FIXME[EnumMemberNaming] */ audio = "audio"; + AUDIO = "audio"; IMG = "img"; MAP = "map"; TRACK = "track"; From 18493bd0c516062aff2e32aeb7b6e248d8c13c82 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Wed, 15 Dec 2021 18:45:54 -0800 Subject: [PATCH 4/9] Using addAllowedTagsWithAttributes instead of addAllowedTagWithAttributes --- tests/CommentRemovalTest.hack | 36 +++++++++---------------- tests/HTMLPurifierTest.hack | 50 +++++++++++++++-------------------- 2 files changed, 34 insertions(+), 52 deletions(-) diff --git a/tests/CommentRemovalTest.hack b/tests/CommentRemovalTest.hack index bf8e239..aadc2bb 100644 --- a/tests/CommentRemovalTest.hack +++ b/tests/CommentRemovalTest.hack @@ -110,28 +110,18 @@ class CommentRemovalTest extends HackTest { HTMLPurifier\html_tags_t::TR, ], ); - $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[ - HTMLPurifier\html_attributes_t::ID, - HTMLPurifier\html_attributes_t::NAME, - HTMLPurifier\html_attributes_t::HREF, - HTMLPurifier\html_attributes_t::TARGET, - HTMLPurifier\html_attributes_t::REL, - ]); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::H3, - keyset[HTMLPurifier\html_attributes_t::CLASSES], - ); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::P, - keyset[HTMLPurifier\html_attributes_t::CLASSES], - ); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::ASIDE, - keyset[HTMLPurifier\html_attributes_t::CLASSES], - ); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::IMG, - keyset[ + $policy->addAllowedTagsWithAttributes(dict[ + HTMLPurifier\html_tags_t::A => keyset[ + HTMLPurifier\html_attributes_t::ID, + HTMLPurifier\html_attributes_t::NAME, + HTMLPurifier\html_attributes_t::HREF, + HTMLPurifier\html_attributes_t::TARGET, + HTMLPurifier\html_attributes_t::REL, + ], + HTMLPurifier\html_tags_t::H3 => keyset[HTMLPurifier\html_attributes_t::CLASSES], + HTMLPurifier\html_tags_t::P => keyset[HTMLPurifier\html_attributes_t::CLASSES], + HTMLPurifier\html_tags_t::ASIDE => keyset[HTMLPurifier\html_attributes_t::CLASSES], + HTMLPurifier\html_tags_t::IMG => keyset[ HTMLPurifier\html_attributes_t::SRC, HTMLPurifier\html_attributes_t::ALT, HTMLPurifier\html_attributes_t::CLASSES, @@ -140,7 +130,7 @@ class CommentRemovalTest extends HackTest { HTMLPurifier\html_attributes_t::SRCSET, HTMLPurifier\html_attributes_t::SIZES, ], - ); + ]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_email1 = "'; diff --git a/tests/CommentRemovalTest.hack b/tests/CommentRemovalTest.hack index aadc2bb..ccc81aa 100644 --- a/tests/CommentRemovalTest.hack +++ b/tests/CommentRemovalTest.hack @@ -5,7 +5,7 @@ namespace HTMLPurifier\_Private\Tests; use function Facebook\FBExpect\expect; use type Facebook\HackTest\HackTest; use namespace HTMLPurifier; -use namespace HTMLPurifier\{Strategy, Token, Lexer}; +use namespace HTMLPurifier\{Strategy, Token, Lexer, Enums}; class CommentRemovalTest extends HackTest { public function testValidCommentRemoval(): void { @@ -53,13 +53,13 @@ class CommentRemovalTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::A, + Enums\HtmlTags::A, keyset[ - HTMLPurifier\html_attributes_t::ID, - HTMLPurifier\html_attributes_t::NAME, - HTMLPurifier\html_attributes_t::HREF, - HTMLPurifier\html_attributes_t::TARGET, - HTMLPurifier\html_attributes_t::REL, + Enums\HtmlAttributes::ID, + Enums\HtmlAttributes::NAME, + Enums\HtmlAttributes::HREF, + Enums\HtmlAttributes::TARGET, + Enums\HtmlAttributes::REL, ], ); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); @@ -89,46 +89,46 @@ class CommentRemovalTest extends HackTest { $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTags( keyset[ - HTMLPurifier\html_tags_t::B, - HTMLPurifier\html_tags_t::UL, - HTMLPurifier\html_tags_t::LI, - HTMLPurifier\html_tags_t::OL, - HTMLPurifier\html_tags_t::H2, - HTMLPurifier\html_tags_t::H4, - HTMLPurifier\html_tags_t::BR, - HTMLPurifier\html_tags_t::DIV, - HTMLPurifier\html_tags_t::STRONG, - HTMLPurifier\html_tags_t::DEL, - HTMLPurifier\html_tags_t::EM, - HTMLPurifier\html_tags_t::PRE, - HTMLPurifier\html_tags_t::CODE, - HTMLPurifier\html_tags_t::TABLE, - HTMLPurifier\html_tags_t::TBODY, - HTMLPurifier\html_tags_t::TD, - HTMLPurifier\html_tags_t::TH, - HTMLPurifier\html_tags_t::THEAD, - HTMLPurifier\html_tags_t::TR, + Enums\HtmlTags::B, + Enums\HtmlTags::UL, + Enums\HtmlTags::LI, + Enums\HtmlTags::OL, + Enums\HtmlTags::H2, + Enums\HtmlTags::H4, + Enums\HtmlTags::BR, + Enums\HtmlTags::DIV, + Enums\HtmlTags::STRONG, + Enums\HtmlTags::DEL, + Enums\HtmlTags::EM, + Enums\HtmlTags::PRE, + Enums\HtmlTags::CODE, + Enums\HtmlTags::TABLE, + Enums\HtmlTags::TBODY, + Enums\HtmlTags::TD, + Enums\HtmlTags::TH, + Enums\HtmlTags::THEAD, + Enums\HtmlTags::TR, ], ); $policy->addAllowedTagsWithAttributes(dict[ - HTMLPurifier\html_tags_t::A => keyset[ - HTMLPurifier\html_attributes_t::ID, - HTMLPurifier\html_attributes_t::NAME, - HTMLPurifier\html_attributes_t::HREF, - HTMLPurifier\html_attributes_t::TARGET, - HTMLPurifier\html_attributes_t::REL, + Enums\HtmlTags::A => keyset[ + Enums\HtmlAttributes::ID, + Enums\HtmlAttributes::NAME, + Enums\HtmlAttributes::HREF, + Enums\HtmlAttributes::TARGET, + Enums\HtmlAttributes::REL, ], - HTMLPurifier\html_tags_t::H3 => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::P => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::ASIDE => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::IMG => keyset[ - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::ALT, - HTMLPurifier\html_attributes_t::CLASSES, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::SRCSET, - HTMLPurifier\html_attributes_t::SIZES, + Enums\HtmlTags::H3 => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::P => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::ASIDE => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::IMG => keyset[ + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::ALT, + Enums\HtmlAttributes::CLASSES, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::SRCSET, + Enums\HtmlAttributes::SIZES, ], ]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); diff --git a/tests/HTMLPurifierTest.hack b/tests/HTMLPurifierTest.hack index 2225056..ee360ea 100644 --- a/tests/HTMLPurifierTest.hack +++ b/tests/HTMLPurifierTest.hack @@ -5,54 +5,54 @@ namespace HTMLPurifier\_Private\Tests; use function Facebook\FBExpect\expect; use type Facebook\HackTest\HackTest; use namespace HTMLPurifier; -use namespace HTMLPurifier\{Strategy, Token, Lexer}; +use namespace HTMLPurifier\{Strategy, Token, Lexer, Enums}; class HTMLPurifierTest extends HackTest { private function standardPolicy(): HTMLPurifier\HTMLSanitizerPolicy { $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTags( keyset[ - HTMLPurifier\html_tags_t::B, - HTMLPurifier\html_tags_t::UL, - HTMLPurifier\html_tags_t::LI, - HTMLPurifier\html_tags_t::OL, - HTMLPurifier\html_tags_t::H2, - HTMLPurifier\html_tags_t::H4, - HTMLPurifier\html_tags_t::BR, - HTMLPurifier\html_tags_t::DIV, - HTMLPurifier\html_tags_t::STRONG, - HTMLPurifier\html_tags_t::DEL, - HTMLPurifier\html_tags_t::EM, - HTMLPurifier\html_tags_t::PRE, - HTMLPurifier\html_tags_t::CODE, - HTMLPurifier\html_tags_t::TABLE, - HTMLPurifier\html_tags_t::TBODY, - HTMLPurifier\html_tags_t::TD, - HTMLPurifier\html_tags_t::TH, - HTMLPurifier\html_tags_t::THEAD, - HTMLPurifier\html_tags_t::TR, + Enums\HtmlTags::B, + Enums\HtmlTags::UL, + Enums\HtmlTags::LI, + Enums\HtmlTags::OL, + Enums\HtmlTags::H2, + Enums\HtmlTags::H4, + Enums\HtmlTags::BR, + Enums\HtmlTags::DIV, + Enums\HtmlTags::STRONG, + Enums\HtmlTags::DEL, + Enums\HtmlTags::EM, + Enums\HtmlTags::PRE, + Enums\HtmlTags::CODE, + Enums\HtmlTags::TABLE, + Enums\HtmlTags::TBODY, + Enums\HtmlTags::TD, + Enums\HtmlTags::TH, + Enums\HtmlTags::THEAD, + Enums\HtmlTags::TR, ], ); $policy->addAllowedTagsWithAttributes( dict[ - HTMLPurifier\html_tags_t::A => keyset[ - HTMLPurifier\html_attributes_t::ID, - HTMLPurifier\html_attributes_t::NAME, - HTMLPurifier\html_attributes_t::HREF, - HTMLPurifier\html_attributes_t::TARGET, - HTMLPurifier\html_attributes_t::REL, + Enums\HtmlTags::A => keyset[ + Enums\HtmlAttributes::ID, + Enums\HtmlAttributes::NAME, + Enums\HtmlAttributes::HREF, + Enums\HtmlAttributes::TARGET, + Enums\HtmlAttributes::REL, ], - HTMLPurifier\html_tags_t::H3 => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::P => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::ASIDE => keyset[HTMLPurifier\html_attributes_t::CLASSES], - HTMLPurifier\html_tags_t::IMG => keyset[ - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::ALT, - HTMLPurifier\html_attributes_t::CLASSES, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::SRCSET, - HTMLPurifier\html_attributes_t::SIZES, + Enums\HtmlTags::H3 => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::P => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::ASIDE => keyset[Enums\HtmlAttributes::CLASSES], + Enums\HtmlTags::IMG => keyset[ + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::ALT, + Enums\HtmlAttributes::CLASSES, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::SRCSET, + Enums\HtmlAttributes::SIZES, ], ], ); @@ -107,7 +107,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTags(keyset[HTMLPurifier\html_tags_t::DEL, HTMLPurifier\html_tags_t::DIV]); + $policy->addAllowedTags(keyset[Enums\HtmlTags::DEL, Enums\HtmlTags::DIV]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'Inline context
    No block allowed
    '; @@ -122,7 +122,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::CENTER); + $policy->addAllowedTag(Enums\HtmlTags::CENTER); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '
    Centered
    '; @@ -137,7 +137,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::SPAN); + $policy->addAllowedTag(Enums\HtmlTags::SPAN); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'Text'; @@ -152,7 +152,7 @@ class HTMLPurifierTest extends HackTest { // porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTags(keyset[HTMLPurifier\html_tags_t::H2, HTMLPurifier\html_tags_t::DIV]); + $policy->addAllowedTags(keyset[Enums\HtmlTags::H2, Enums\HtmlTags::DIV]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '
    @@ -170,17 +170,14 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); $policy->addAllowedTags(keyset[ - HTMLPurifier\html_tags_t::CAPTION, - HTMLPurifier\html_tags_t::TFOOT, - HTMLPurifier\html_tags_t::TR, - HTMLPurifier\html_tags_t::TH, - HTMLPurifier\html_tags_t::TBODY, - HTMLPurifier\html_tags_t::TABLE, + Enums\HtmlTags::CAPTION, + Enums\HtmlTags::TFOOT, + Enums\HtmlTags::TR, + Enums\HtmlTags::TH, + Enums\HtmlTags::TBODY, + Enums\HtmlTags::TABLE, ]); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::TD, - keyset[HTMLPurifier\html_attributes_t::STYLE], - ); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::TD, keyset[Enums\HtmlAttributes::STYLE]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = ' @@ -231,7 +228,7 @@ class HTMLPurifierTest extends HackTest { new Token\HTMLPurifier_Token_Text("Bold"), new Token\HTMLPurifier_Token_End("b", dict[]), ]; - + \var_dump($tokens); expect($tokens)->toHaveSameContentAs($expected_tokens); echo "finished.\n"; } @@ -272,7 +269,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::A); + $policy->addAllowedTag(Enums\HtmlTags::A); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'Hello'; $clean_html = $purifier->purify($dirty_html); @@ -285,7 +282,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::A); + $policy->addAllowedTag(Enums\HtmlTags::A); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'Hello'; $clean_html = $purifier->purify($dirty_html); @@ -298,7 +295,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::B); + $policy->addAllowedTag(Enums\HtmlTags::B); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = 'Hello'; $purifier = new HTMLPurifier\HTMLPurifier($config); @@ -312,10 +309,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::DIV, - keyset[HTMLPurifier\html_attributes_t::ALIGN], - ); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::DIV, keyset[Enums\HtmlAttributes::ALIGN]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '
    Hello'; $purifier = new HTMLPurifier\HTMLPurifier($config); @@ -329,10 +323,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::DIV, - keyset[HTMLPurifier\html_attributes_t::ALIGN], - ); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::DIV, keyset[Enums\HtmlAttributes::ALIGN]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $dirty_html = '
    Hello'; $clean_html = $purifier->purify($dirty_html); @@ -346,13 +337,13 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::IFRAME, + Enums\HtmlTags::IFRAME, keyset[ - HTMLPurifier\html_attributes_t::TITLE, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::ALLOWFULLSCREEN, + Enums\HtmlAttributes::TITLE, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::ALLOWFULLSCREEN, ], ); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); @@ -371,13 +362,13 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::IFRAME, + Enums\HtmlTags::IFRAME, keyset[ - HTMLPurifier\html_attributes_t::TITLE, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::ALLOWFULLSCREEN, + Enums\HtmlAttributes::TITLE, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::ALLOWFULLSCREEN, ], ); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); @@ -414,7 +405,7 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[HTMLPurifier\html_attributes_t::HREF]); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::A, keyset[Enums\HtmlAttributes::HREF]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["URI.Munge"] = "/redirect.php?url=%s&check=%t"; $config->def->defaults["URI.MungeSecretKey"] = "foo"; @@ -431,11 +422,11 @@ class HTMLPurifierTest extends HackTest { //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::IFRAME, keyset[ - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::ALLOWFULLSCREEN, + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::IFRAME, keyset[ + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::ALLOWFULLSCREEN, ]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); @@ -453,15 +444,15 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::IMG, + Enums\HtmlTags::IMG, keyset[ - HTMLPurifier\html_attributes_t::SRC, - HTMLPurifier\html_attributes_t::ALT, - HTMLPurifier\html_attributes_t::CLASSES, - HTMLPurifier\html_attributes_t::WIDTH, - HTMLPurifier\html_attributes_t::HEIGHT, - HTMLPurifier\html_attributes_t::SRCSET, - HTMLPurifier\html_attributes_t::SIZES, + Enums\HtmlAttributes::SRC, + Enums\HtmlAttributes::ALT, + Enums\HtmlAttributes::CLASSES, + Enums\HtmlAttributes::WIDTH, + Enums\HtmlAttributes::HEIGHT, + Enums\HtmlAttributes::SRCSET, + Enums\HtmlAttributes::SIZES, ], ); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); @@ -628,13 +619,13 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::A, + Enums\HtmlTags::A, keyset[ - HTMLPurifier\html_attributes_t::ID, - HTMLPurifier\html_attributes_t::NAME, - HTMLPurifier\html_attributes_t::HREF, - HTMLPurifier\html_attributes_t::TARGET, - HTMLPurifier\html_attributes_t::REL, + Enums\HtmlAttributes::ID, + Enums\HtmlAttributes::NAME, + Enums\HtmlAttributes::HREF, + Enums\HtmlAttributes::TARGET, + Enums\HtmlAttributes::REL, ], ); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); diff --git a/tests/InjectorTest.hack b/tests/InjectorTest.hack index dcb6c9e..281430e 100644 --- a/tests/InjectorTest.hack +++ b/tests/InjectorTest.hack @@ -2,7 +2,7 @@ use function Facebook\FBExpect\expect; use type Facebook\HackTest\HackTest; use namespace HTMLPurifier; -use namespace HTMLPurifier\{Strategy, Token, Lexer, Injector}; +use namespace HTMLPurifier\{Strategy, Token, Lexer, Injector, Enums}; class InjectorTest extends HackTest { private function assertAutoParagraphResult(string $name, string $dirty, string $expected): void { @@ -20,7 +20,7 @@ class InjectorTest extends HackTest { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::A); + $policy->addAllowedTag(Enums\HtmlTags::A); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.DisplayLinkURI"] = true; $clean_html = $purifier->purify($dirty); @@ -43,9 +43,9 @@ class InjectorTest extends HackTest { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTags(keyset[HTMLPurifier\html_tags_t::DIV, HTMLPurifier\html_tags_t::SPAN]); - $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[ - HTMLPurifier\html_attributes_t::HREF, + $policy->addAllowedTags(keyset[Enums\HtmlTags::DIV, Enums\HtmlTags::SPAN]); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::A, keyset[ + Enums\HtmlAttributes::HREF, ]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.PurifierLinkify"] = true; @@ -59,9 +59,9 @@ class InjectorTest extends HackTest { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $policy->addAllowedTag(HTMLPurifier\html_tags_t::SPAN); - $policy->addAllowedTagWithAttributes(HTMLPurifier\html_tags_t::A, keyset[ - HTMLPurifier\html_attributes_t::HREF, + $policy->addAllowedTag(Enums\HtmlTags::SPAN); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::A, keyset[ + Enums\HtmlAttributes::HREF, ]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.Linkify"] = true; @@ -75,15 +75,12 @@ class InjectorTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); $policy->addAllowedTags(keyset[ - HTMLPurifier\html_tags_t::DIV, - HTMLPurifier\html_tags_t::P, - HTMLPurifier\html_tags_t::STRONG, - HTMLPurifier\html_tags_t::EM, + Enums\HtmlTags::DIV, + Enums\HtmlTags::P, + Enums\HtmlTags::STRONG, + Enums\HtmlTags::EM, ]); - $policy->addAllowedTagWithAttributes( - HTMLPurifier\html_tags_t::SPAN, - keyset[HTMLPurifier\html_attributes_t::CLASSES], - ); + $policy->addAllowedTagWithAttributes(Enums\HtmlTags::SPAN, keyset[Enums\HtmlAttributes::CLASSES]); // $config->def->defaults['HTML.Allowed'] = 'span[class],div,p,strong,em'; $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); $config->def->defaults["AutoFormat.RemoveSpansWithoutAttributes"] = true; From 99de7dd649f81049b89b4c3125104f13845a7f97 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Fri, 17 Dec 2021 16:57:02 -0800 Subject: [PATCH 6/9] Consolidating the HTMLSanitizerPolicy and HTMLPurifier_Policy --- src/HTMLSanitizerPolicy.hack | 142 ---------------------------------- src/Policy.hack | 115 +++++++++++++++++++++++++-- tests/AllowedTest.hack | 14 ++-- tests/CommentRemovalTest.hack | 36 +++++---- tests/DOMLexTest.hack | 4 +- tests/HTMLPurifierTest.hack | 107 +++++++++++++------------ tests/InjectorTest.hack | 28 +++---- 7 files changed, 208 insertions(+), 238 deletions(-) delete mode 100644 src/HTMLSanitizerPolicy.hack diff --git a/src/HTMLSanitizerPolicy.hack b/src/HTMLSanitizerPolicy.hack deleted file mode 100644 index 0b2e588..0000000 --- a/src/HTMLSanitizerPolicy.hack +++ /dev/null @@ -1,142 +0,0 @@ -namespace HTMLPurifier; -use namespace HH\Lib\C; -// use namespace HTMLPurifier\Enums; -use type HTMLPurifier\Enums\{HtmlTags, HtmlAttributes}; - -type html_input_t = shape( - 'dirty_html' => string, - 'policy' => HTMLSanitizerPolicy, -); - -/* -* Default policy constant. This is the list of default allowed tags and -* attributes when calling `HTMLSanitizerPolicy::fromEmpty()` - */ -const dict> HTML_SANITIZER_DEFAULT_POLICY = dict[ - HtmlTags::P => keyset[], - HtmlTags::B => keyset[], - HtmlTags::I => keyset[], -]; - -final class HTMLSanitizerException extends \Exception {} - -/** - * HTMLSanitizerPolicy lets you define allowlist policy settings for html purifier - */ - -final class HTMLSanitizerPolicy { - - private dict> $html_purifier_policy = dict[]; - - /** - * Construct policy class from set of predefined policy allowlist - * - * @param html_purifier_policy_from_t $policyFrom select from predefined policy - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public function __construct(dict> $policy) { - foreach ($policy as $allowed_tag => $allowed_attributes) { - $this->addAllowedTagWithAttributes($allowed_tag, $allowed_attributes); - } - } - - /** - * Use the default allowlist policy. - * - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public static function fromDefault(): HTMLSanitizerPolicy { - $html_purifier_policy = HTML_SANITIZER_DEFAULT_POLICY; - return new HTMLSanitizerPolicy($html_purifier_policy); - } - - /** - * Use the empty allowlist policy. - * - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public static function fromEmpty(): HTMLSanitizerPolicy { - return new HTMLSanitizerPolicy(dict[]); - } - - /** - * Add a single allowed tag to the allowlist. This only allows the tag with - * any default safe attributes that the library sets. - * - * @param HtmlTags $tag - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public function addAllowedTag(HtmlTags $allowed_tag): HTMLSanitizerPolicy { - // Skip if we already have the same tag in the policy - if (!C\contains_key($this->html_purifier_policy, $allowed_tag)) { - $this->html_purifier_policy[$allowed_tag] = keyset[]; - } else { - throw new HTMLSanitizerException("html tag \"$allowed_tag\" already exist in the policy"); - } - return $this; - } - - /** - * Add multiple allowed tags to the allowlist. This only allows the tags with - * any default safe attributes that the library sets. - * - * @param keyset $allowed_tags - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public function addAllowedTags(keyset $allowed_tags): HTMLSanitizerPolicy { - foreach ($allowed_tags as $allowed_tag) { - $this->addAllowedTag($allowed_tag); - } - return $this; - } - - /** - * Add a tag with allowed attributes to the allowlist - * - * @param keyset $allowed_tags - * @return HTMLSanitizerPolicy the current HTMLSanitizerPolicy object - */ - public function addAllowedTagWithAttributes( - HtmlTags $tag, - keyset $attributes, - ): HTMLSanitizerPolicy { - $this->addAllowedTag($tag); - foreach ($attributes as $attribute) { - $this->html_purifier_policy[$tag][] = $attribute; - } - return $this; - } - - public function addAllowedTagsWithAttributes( - dict> $allowed_tags, - ): HTMLSanitizerPolicy { - foreach ($allowed_tags as $tag => $attributes) { - $this->addAllowedTagWithAttributes($tag, $attributes); - } - return $this; - } - - /** - * This function maps the object from $html_purifier_policy to the Policy - * object in htmlpurifier-hack. - * @return Policy object for htmlpurifier-hack - */ - public function constructPolicy(): HTMLPurifier_Policy { - /** - * Do series of loop on each keys and items in $html_purifier_policy to map - * and populate the Policy object. The loop also converts the tags and - * attributes type to string as used by the Policy object - */ - $allowed_tags_attributes = dict[]; - foreach ($this->html_purifier_policy as $tag => $attributes) { - $list_attributes = vec[]; - foreach ($attributes as $attribute) { - $list_attributes[] = (string)$attribute; - } - $allowed_tags_attributes[(string)$tag] = $list_attributes; - } - $policy_message = new HTMLPurifier_Policy($allowed_tags_attributes); - return $policy_message; - } - -} diff --git a/src/Policy.hack b/src/Policy.hack index b1fde85..3fc7612 100644 --- a/src/Policy.hack +++ b/src/Policy.hack @@ -4,11 +4,114 @@ namespace HTMLPurifier; use namespace HH\Lib\{C, Str}; +use type HTMLPurifier\Enums\{HtmlTags, HtmlAttributes}; + +type html_input_t = shape( + 'dirty_html' => string, + 'policy' => HTMLPurifier_Policy, +); + +/* +* Default policy constant. This is the list of default allowed tags and +* attributes when calling `HTMLPurifier_Policy::fromEmpty()` + */ +const dict> HTML_SANITIZER_DEFAULT_POLICY = dict[ + HtmlTags::P => keyset[], + HtmlTags::B => keyset[], + HtmlTags::I => keyset[], +]; + class HTMLPurifier_Policy { - public dict> $allowed_tags_attributes = dict[]; + // public dict> $allowed_tags_attributes = dict[]; + + private dict> $html_purifier_policy = dict[]; + + /** + * Construct policy class from set of predefined policy allowlist + * + * @param html_purifier_policy_from_t $policyFrom select from predefined policy + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public function __construct(dict> $policy) { + foreach ($policy as $allowed_tag => $allowed_attributes) { + $this->addAllowedTagWithAttributes($allowed_tag, $allowed_attributes); + } + } + + /** + * Use the default allowlist policy. + * + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public static function fromDefault(): HTMLPurifier_Policy { + $html_purifier_policy = HTML_SANITIZER_DEFAULT_POLICY; + return new HTMLPurifier_Policy($html_purifier_policy); + } + + /** + * Use the empty allowlist policy. + * + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public static function fromEmpty(): HTMLPurifier_Policy { + return new HTMLPurifier_Policy(dict[]); + } - public function __construct(dict> $allowed_tags_attributes) { - $this->allowed_tags_attributes = $allowed_tags_attributes; + /** + * Add a single allowed tag to the allowlist. This only allows the tag with + * any default safe attributes that the library sets. + * + * @param HtmlTags $tag + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public function addAllowedTag(HtmlTags $allowed_tag): HTMLPurifier_Policy { + // Skip if we already have the same tag in the policy + if (!C\contains_key($this->html_purifier_policy, $allowed_tag)) { + $this->html_purifier_policy[$allowed_tag] = keyset[]; + } else { + throw new HTMLSanitizerException("html tag \"$allowed_tag\" already exist in the policy"); + } + return $this; + } + + /** + * Add multiple allowed tags to the allowlist. This only allows the tags with + * any default safe attributes that the library sets. + * + * @param keyset $allowed_tags + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public function addAllowedTags(keyset $allowed_tags): HTMLPurifier_Policy { + foreach ($allowed_tags as $allowed_tag) { + $this->addAllowedTag($allowed_tag); + } + return $this; + } + + /** + * Add a tag with allowed attributes to the allowlist + * + * @param keyset $allowed_tags + * @return HTMLPurifier_Policy the current HTMLPurifier_Policy object + */ + public function addAllowedTagWithAttributes( + HtmlTags $tag, + keyset $attributes, + ): HTMLPurifier_Policy { + $this->addAllowedTag($tag); + foreach ($attributes as $attribute) { + $this->html_purifier_policy[$tag][] = $attribute; + } + return $this; + } + + public function addAllowedTagsWithAttributes( + dict> $allowed_tags, + ): HTMLPurifier_Policy { + foreach ($allowed_tags as $tag => $attributes) { + $this->addAllowedTagWithAttributes($tag, $attributes); + } + return $this; } public function configPolicy(HTMLPurifier_Config $config): HTMLPurifier_Config { @@ -16,14 +119,14 @@ class HTMLPurifier_Policy { /* Get Tags and Attributes from policy objects and convert it to htmlpurifier html allowed config * format: element1[attr1|attr2],element2.... */ - $allowedTagsAttributes = $this->allowed_tags_attributes; + $allowedTagsAttributes = $this->html_purifier_policy; if (!C\is_empty($allowedTagsAttributes)) { foreach ($allowedTagsAttributes as $tag => $list_attrb) { - $html_allowed = $html_allowed.",".$tag; + $html_allowed = $html_allowed.",".(string)$tag; if (!C\is_empty($list_attrb)) { $a_attributes = vec[]; foreach ($list_attrb as $attrb) { - $a_attributes[] = $attrb; + $a_attributes[] = (string)$attrb; } $s_attribute = Str\join($a_attributes, "|"); if ($s_attribute !== "") diff --git a/tests/AllowedTest.hack b/tests/AllowedTest.hack index 3942155..576e6e2 100644 --- a/tests/AllowedTest.hack +++ b/tests/AllowedTest.hack @@ -9,11 +9,11 @@ use namespace HTMLPurifier\{Strategy, Token, Lexer, Enums}; class AllowedTest extends HackTest { public function testEmptyAllowedList(): void { - echo "\ntestDefaultAllowed()..."; + echo "\ntestEmptyAllowed()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromEmpty(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

    Title

    Go to Slack'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('TitleGo to Slack'); @@ -24,8 +24,8 @@ class AllowedTest extends HackTest { echo "\ntestStripTagsNotInDefaultPolicy()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'test'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('test'); @@ -36,12 +36,12 @@ class AllowedTest extends HackTest { echo "\ntestCustomTagsWithAttributes()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTagWithAttributes( Enums\HtmlTags::IMG, keyset[Enums\HtmlAttributes::SRC, Enums\HtmlAttributes::ALT], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'testhello'; $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('testhelloalert(1);'); diff --git a/tests/CommentRemovalTest.hack b/tests/CommentRemovalTest.hack index ccc81aa..6eafded 100644 --- a/tests/CommentRemovalTest.hack +++ b/tests/CommentRemovalTest.hack @@ -11,8 +11,8 @@ class CommentRemovalTest extends HackTest { public function testValidCommentRemoval(): void { echo "\nrunning testValidCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html1 = ''; $dirty_html2 = 'Hello World!'; $dirty_html3 = 'Hello World!'; @@ -29,8 +29,8 @@ class CommentRemovalTest extends HackTest { public function testParseErrorCommentRemoval(): void { echo "\nrunning testParseErrorCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html1 = ''; // abruptly closed comment $dirty_html2 = ''; // abruptly closed comment @@ -51,7 +51,7 @@ class CommentRemovalTest extends HackTest { public function testCure53PoCCommentRemoval(): void { echo "\nrunning testCure53PoCCommentRemoval()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTagWithAttributes( Enums\HtmlTags::A, keyset[ @@ -62,7 +62,7 @@ class CommentRemovalTest extends HackTest { Enums\HtmlAttributes::REL, ], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_poc1 = ''; $clean_html = $purifier->purify($dirty_html); @@ -360,7 +360,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testSanitizeHtmlWithIframeForSearchProtocolsPolicySet()..."; //porting over first config classes.... $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromEmpty(); $policy->addAllowedTagWithAttributes( Enums\HtmlTags::IFRAME, keyset[ @@ -371,7 +371,7 @@ class HTMLPurifierTest extends HackTest { Enums\HtmlAttributes::ALLOWFULLSCREEN, ], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); // Test1 clean iframe with usertesting domain with no protocol $dirty_html = ''; @@ -442,7 +442,7 @@ class HTMLPurifierTest extends HackTest { public function testImagePolicyWithMissingAltAttribute(): void { echo "\nrunning testImagePolicyWithMissingAltAttribute()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromEmpty(); $policy->addAllowedTagWithAttributes( Enums\HtmlTags::IMG, keyset[ @@ -455,7 +455,7 @@ class HTMLPurifierTest extends HackTest { Enums\HtmlAttributes::SIZES, ], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = ''; $clean_html = $purifier->purify($dirty_html); @@ -470,7 +470,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testWebappPolicy()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); expect(true)->toNotBeNull(); echo "finished.\n\n"; } @@ -479,7 +479,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testSpecialCharacterValidateUTF8()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '
    • Just a sentence. •
    • Just a sentence.•
    • @@ -531,7 +531,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testWebappPolicy()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      how to use the "at" html sanitizerHow it works

      '; $clean_html = $purifier->purify($dirty_html); @@ -545,7 +545,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testRel()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -557,7 +557,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagTargetAttribute()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -569,7 +569,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagNoChange()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -581,7 +581,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagStripAdd()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -593,7 +593,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagStripLeave()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -605,7 +605,7 @@ class HTMLPurifierTest extends HackTest { echo "\nrunning testAtagNoTarget()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = $this->standardPolicy(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '

      '; $clean_html = $purifier->purify($dirty_html); $expected_html = '

      '; @@ -615,9 +615,8 @@ class HTMLPurifierTest extends HackTest { public function testDisabledTargetBlankTransform(): void { echo "\nrunning testAtagNoTarget()..."; - $policy = new HTMLPurifier\HTMLPurifier_Policy(dict['a' => vec['id', 'name', 'href', 'target', 'rel']]); $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromEmpty(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromEmpty(); $policy->addAllowedTagWithAttributes( Enums\HtmlTags::A, keyset[ @@ -628,7 +627,7 @@ class HTMLPurifierTest extends HackTest { Enums\HtmlAttributes::REL, ], ); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = ''; $clean_html = $purifier->purify($dirty_html); $expected_html = ''; diff --git a/tests/InjectorTest.hack b/tests/InjectorTest.hack index 281430e..494807d 100644 --- a/tests/InjectorTest.hack +++ b/tests/InjectorTest.hack @@ -8,8 +8,8 @@ class InjectorTest extends HackTest { private function assertAutoParagraphResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.AutoParagraph"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -19,9 +19,9 @@ class InjectorTest extends HackTest { private function assertDisplayURIResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTag(Enums\HtmlTags::A); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.DisplayLinkURI"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -31,8 +31,8 @@ class InjectorTest extends HackTest { private function assertRemoveEmptyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.RemoveEmpty"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -42,12 +42,12 @@ class InjectorTest extends HackTest { private function assertPurifierLinkifyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTags(keyset[Enums\HtmlTags::DIV, Enums\HtmlTags::SPAN]); $policy->addAllowedTagWithAttributes(Enums\HtmlTags::A, keyset[ Enums\HtmlAttributes::HREF, ]); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.PurifierLinkify"] = true; $config->def->defaults["AutoFormat.PurifierLinkify.DocURL"] = '#%s'; $clean_html = $purifier->purify($dirty); @@ -58,12 +58,12 @@ class InjectorTest extends HackTest { private function assertLinkifyResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTag(Enums\HtmlTags::SPAN); $policy->addAllowedTagWithAttributes(Enums\HtmlTags::A, keyset[ Enums\HtmlAttributes::HREF, ]); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.Linkify"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -73,7 +73,7 @@ class InjectorTest extends HackTest { private function assertRemoveSpansWithoutAttributesResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); $policy->addAllowedTags(keyset[ Enums\HtmlTags::DIV, Enums\HtmlTags::P, @@ -82,7 +82,7 @@ class InjectorTest extends HackTest { ]); $policy->addAllowedTagWithAttributes(Enums\HtmlTags::SPAN, keyset[Enums\HtmlAttributes::CLASSES]); // $config->def->defaults['HTML.Allowed'] = 'span[class],div,p,strong,em'; - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.RemoveSpansWithoutAttributes"] = true; $clean_html = $purifier->purify($dirty); expect($clean_html)->toEqual($expected); @@ -92,8 +92,8 @@ class InjectorTest extends HackTest { private function assertSafeObjectResult(string $name, string $dirty, string $expected): void { echo "\nrunning test$name()..."; $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); - $policy = HTMLPurifier\HTMLSanitizerPolicy::fromDefault(); - $purifier = new HTMLPurifier\HTMLPurifier($config, $policy->constructPolicy()); + $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); + $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $config->def->defaults["AutoFormat.Custom"] = vec[new Injector\HTMLPurifier_Injector_SafeObject()]; $config->def->defaults["HTML.Trusted"] = true; $clean_html = $purifier->purify($dirty); From 7cd049010804b17f393d8e9e46c0401c1086ddcc Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Fri, 17 Dec 2021 17:02:45 -0800 Subject: [PATCH 7/9] Forgot to carry over the exception and convert the tag to a string --- src/Policy.hack | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Policy.hack b/src/Policy.hack index 3fc7612..d4b3454 100644 --- a/src/Policy.hack +++ b/src/Policy.hack @@ -21,6 +21,8 @@ const dict> HTML_SANITIZER_DEFAULT_POLICY = dic HtmlTags::I => keyset[], ]; +final class HTMLSanitizerException extends \Exception {} + class HTMLPurifier_Policy { // public dict> $allowed_tags_attributes = dict[]; @@ -69,7 +71,7 @@ class HTMLPurifier_Policy { if (!C\contains_key($this->html_purifier_policy, $allowed_tag)) { $this->html_purifier_policy[$allowed_tag] = keyset[]; } else { - throw new HTMLSanitizerException("html tag \"$allowed_tag\" already exist in the policy"); + throw new HTMLSanitizerException("html tag \"(string)$allowed_tag\" already exist in the policy"); } return $this; } From cd1938e396926a06f67324c8a0171e2a29076410 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Mon, 20 Dec 2021 17:07:29 -0500 Subject: [PATCH 8/9] Addressing Jack's comments --- .vscode/launch.json | 2 +- src/Injector.hack | 8 ++------ src/Policy.hack | 4 +--- tests/HTMLPurifierTest.hack | 14 +++----------- 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c3dcd87..9b88432 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,7 @@ "name": "HHVM: Run Script", "type": "hhvm", "request": "launch", - "script": "src/index.hack", + "script": "src/main.hack", "hhvmArgs": [ "-v", "Eval.JitEnableRenameFunction=true", diff --git a/src/Injector.hack b/src/Injector.hack index 5e9cb34..814d087 100644 --- a/src/Injector.hack +++ b/src/Injector.hack @@ -2,7 +2,6 @@ namespace HTMLPurifier; use namespace HTMLPurifier\Definition; -use HH; use namespace HH\Lib\C; use namespace Facebook\TypeAssert; @@ -114,14 +113,11 @@ abstract class HTMLPurifier_Injector { public function checkNeeded(HTMLPurifier_Config $config): string { $def = TypeAssert\matches($config->getHTMLDefinition()); foreach ($this->needed as $element => $attributes) { - if (!HH\idx($def->info, $element)) { + if (!C\contains_key($def->info, $element)) { return $element; } - if (!($attributes is vec<_>)) { - continue; - } foreach ($attributes as $name) { - if (!HH\idx($def->info[$element]->attr, $name)) { + if (!C\contains_key($def->info[$element]->attr, $name)) { return "$element.$name"; } } diff --git a/src/Policy.hack b/src/Policy.hack index d4b3454..8e2489a 100644 --- a/src/Policy.hack +++ b/src/Policy.hack @@ -3,7 +3,6 @@ namespace HTMLPurifier; use namespace HH\Lib\{C, Str}; - use type HTMLPurifier\Enums\{HtmlTags, HtmlAttributes}; type html_input_t = shape( @@ -13,7 +12,7 @@ type html_input_t = shape( /* * Default policy constant. This is the list of default allowed tags and -* attributes when calling `HTMLPurifier_Policy::fromEmpty()` +* attributes when calling `HTMLPurifier_Policy::fromDefault()` */ const dict> HTML_SANITIZER_DEFAULT_POLICY = dict[ HtmlTags::P => keyset[], @@ -24,7 +23,6 @@ const dict> HTML_SANITIZER_DEFAULT_POLICY = dic final class HTMLSanitizerException extends \Exception {} class HTMLPurifier_Policy { - // public dict> $allowed_tags_attributes = dict[]; private dict> $html_purifier_policy = dict[]; diff --git a/tests/HTMLPurifierTest.hack b/tests/HTMLPurifierTest.hack index c292e0d..4c0d56d 100644 --- a/tests/HTMLPurifierTest.hack +++ b/tests/HTMLPurifierTest.hack @@ -68,7 +68,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'Bold'; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('Bold'); echo "finished.\n\n"; @@ -82,7 +81,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = ''; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual(''); echo "finished.\n\n"; @@ -96,7 +94,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'hello'; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('hello'); echo "finished.\n\n"; @@ -111,7 +108,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'Inline context
      No block allowed
      '; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('Inline context No block allowed'); echo "finished.\n\n"; @@ -126,7 +122,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '
      Centered
      '; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('
      Centered
      '); echo "finished.\n\n"; @@ -141,7 +136,6 @@ class HTMLPurifierTest extends HackTest { $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'Text'; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('Text'); echo "finished.\n\n"; @@ -216,7 +210,7 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); // This is weird, but based off of how we define config in HTMLPurifier constructor - $config = $policy |> $$->configPolicy($config); + $config = $policy->configPolicy($config); $context = new HTMLPurifier\HTMLPurifier_Context(); $html = "Bold"; @@ -228,7 +222,7 @@ class HTMLPurifierTest extends HackTest { new Token\HTMLPurifier_Token_Text("Bold"), new Token\HTMLPurifier_Token_End("b", dict[]), ]; - \var_dump($tokens); + expect($tokens)->toHaveSameContentAs($expected_tokens); echo "finished.\n"; } @@ -238,7 +232,7 @@ class HTMLPurifierTest extends HackTest { $config = HTMLPurifier\HTMLPurifier_Config::createDefault(); $policy = HTMLPurifier\HTMLPurifier_Policy::fromDefault(); // This is weird, but based off of how we define config in HTMLPurifier constructor - $config = $policy |> $$->configPolicy($config); + $config = $policy->configPolicy($config); $context = new HTMLPurifier\HTMLPurifier_Context(); $remove_foreign_elements = new Strategy\HTMLPurifier_Strategy_RemoveForeignElements(); @@ -298,7 +292,6 @@ class HTMLPurifierTest extends HackTest { $policy->addAllowedTag(Enums\HtmlTags::B); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = 'Hello'; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('Hello'); echo "finished.\n\n"; @@ -312,7 +305,6 @@ class HTMLPurifierTest extends HackTest { $policy->addAllowedTagWithAttributes(Enums\HtmlTags::DIV, keyset[Enums\HtmlAttributes::ALIGN]); $purifier = new HTMLPurifier\HTMLPurifier($config, $policy); $dirty_html = '
      Hello'; - $purifier = new HTMLPurifier\HTMLPurifier($config); $clean_html = $purifier->purify($dirty_html); expect($clean_html)->toEqual('
      Hello
      '); echo "finished.\n\n"; From 22e0123fa632ae75dec2b37fe8f98071b0812ff3 Mon Sep 17 00:00:00 2001 From: Jake Polacek Date: Tue, 21 Dec 2021 11:00:33 -0500 Subject: [PATCH 9/9] Updating docstring and removing unimplemented tags --- src/Definition/HTMLDefinition.hack | 1 - src/Enums/HTMLTags.hack | 152 +++++++++++++++-------------- 2 files changed, 79 insertions(+), 74 deletions(-) diff --git a/src/Definition/HTMLDefinition.hack b/src/Definition/HTMLDefinition.hack index 23e3a0b..3431ffb 100644 --- a/src/Definition/HTMLDefinition.hack +++ b/src/Definition/HTMLDefinition.hack @@ -1820,7 +1820,6 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier\HTMLPurifier_Definition { "fieldset" => true, ]; $this->info_content_sets['Block'] = $block_info; - } // RAW CUSTOMIZATION STUFF -------------------------------------------- diff --git a/src/Enums/HTMLTags.hack b/src/Enums/HTMLTags.hack index ab30f07..e021662 100644 --- a/src/Enums/HTMLTags.hack +++ b/src/Enums/HTMLTags.hack @@ -1,21 +1,85 @@ namespace HTMLPurifier\Enums; -enum HtmlTags: string { - - //Main root - HTML = "html"; - - //Document metadata - BASE = "base"; - HEAD = "head"; - LINK = "link"; - META = "meta"; - STYLE = "style"; - TITLE = "title"; - - //Sectioning root - BODY = "body"; +/** + * The HtmlTags enums are meant to be added to policies when a developer + * would like to allow the corresponding tag to remain in HTML. + * + * For example, if a developer has an empty policy, and adds HtmlTags::B + * via one of the addTag functions defined in src/Policy.hack, their + * policy will then permit the presence of tags in the clean HTML. + * + * Please note that this list of HTML Tags is incomplete. In order for a + * tag to be used, it must also be defined in the HTMLDefinition info + * property (found in src/Definition/HTMLDefinition). The following tags + * have been dropped from HtmlTags as attempting to add them to a policy + * would result in a thrown error: + * HtmlTags::HTML, + * HtmlTags::BASE, + * HtmlTags::HEAD, + * HtmlTags::LINK, + * HtmlTags::META, + * HtmlTags::STYLE, + * HtmlTags::TITLE, + * HtmlTags::BODY, + * HtmlTags::FIGURE, + * HtmlTags::DATA, + * HtmlTags::RB, + * HtmlTags::RP, + * HtmlTags::RT, + * HtmlTags::RTC, + * HtmlTags::RUBY, + * HtmlTags::TIME, + * HtmlTags::AREA, + * HtmlTags::MAP, + * HtmlTags::VIDEO, + * HtmlTags::APPLET, + * HtmlTags::EMBED, + * HtmlTags::NOEMBED, + * HtmlTags::OBJECT, + * HtmlTags::PARAM, + * HtmlTags::CANVAS, + * HtmlTags::NOSCRIPT, + * HtmlTags::SCRIPT, + * HtmlTags::BUTTON, + * HtmlTags::DATALIST, + * HtmlTags::FIELDSET, + * HtmlTags::FORM, + * HtmlTags::INPUT, + * HtmlTags::LABEL, + * HtmlTags::LEGEND, + * HtmlTags::METER, + * HtmlTags::OPTGROUP, + * HtmlTags::OPTION, + * HtmlTags::OUTPUT, + * HtmlTags::SELECT, + * HtmlTags::TEXTAREA, + * HtmlTags::DETAILS, + * HtmlTags::MENUITEM, + * HtmlTags::CONTENT, + * HtmlTags::ELEMENT, + * HtmlTags::SHADOW, + * HtmlTags::SLOT, + * HtmlTags::TEMPLATE, + * HtmlTags::BGSOUND, + * HtmlTags::BLINK, + * HtmlTags::COMMAND, + * HtmlTags::FRAME, + * HtmlTags::FRAMESET, + * HtmlTags::IMAGE, + * HtmlTags::ISINDEX, + * HtmlTags::KEYGEN, + * HtmlTags::LISTING, + * HtmlTags::MARQUEE, + * HtmlTags::MULTICOL, + * HtmlTags::NEXTID, + * HtmlTags::NOBR, + * HtmlTags::NOFRAMES, + * HtmlTags::PLAINTEXT, + * HtmlTags::SPACER, + * HtmlTags::XMP, + */ +enum HtmlTags: string { //Content sectioningSection ADDRESS = "address"; ARTICLE = "article"; @@ -41,7 +105,6 @@ enum HtmlTags: string { DL = "dl"; DT = "dt"; FIGCAPTION = "figcaption"; - FIGURE = "figure"; HR = "hr"; LI = "li"; OL = "ol"; @@ -58,18 +121,12 @@ enum HtmlTags: string { BR = "br"; CITE = "cite"; CODE = "code"; - DATA = "data"; DFN = "dfn"; EM = "em"; I = "i"; KBD = "kbd"; MARK = "mark"; Q = "q"; - RB = "rb"; - RP = "rp"; - RT = "rt"; - RTC = "rtc"; - RUBY = "ruby"; S = "s"; SAMP = "samp"; SMALL = "small"; @@ -77,35 +134,21 @@ enum HtmlTags: string { STRONG = "strong"; SUB = "sub"; SUP = "sup"; - TIME = "time"; TT = "tt"; U = "u"; VAR = "var"; WBR = "wbr"; //Image and multimedia - AREA = "area"; AUDIO = "audio"; IMG = "img"; - MAP = "map"; TRACK = "track"; - VIDEO = "video"; //Embedded content - APPLET = "applet"; - EMBED = "embed"; IFRAME = "iframe"; - NOEMBED = "noembed"; - OBJECT = "object"; - PARAM = "param"; PICTURE = "picture"; SOURCE = "source"; - //Scripting - CANVAS = "canvas"; - NOSCRIPT = "noscript"; - SCRIPT = "script"; - //Demarcating edits DEL = "del"; INS = "ins"; @@ -124,56 +167,19 @@ enum HtmlTags: string { //Forms BUTTON = "button"; - DATALIST = "datalist"; - FIELDSET = "fieldset"; - FORM = "form"; - INPUT = "input"; - LABEL = "label"; - LEGEND = "legend"; - METER = "meter"; - OPTGROUP = "optgroup"; - OPTION = "option"; - OUTPUT = "output"; PROGRESS = "progress"; - SELECT = "select"; TEXTAREA = "textarea"; //Interactive elements - DETAILS = "details"; DIALOG = "dialog"; MENU = "menu"; - MENUITEM = "menuitem"; SUMMARY = "summary"; - //Web Components - CONTENT = "content"; - ELEMENT = "element"; - SHADOW = "shadow"; - SLOT = "slot"; - TEMPLATE = "template"; - //Obsolete and deprecated elements ACRONYM = "acronym"; BASEFONT = "basefont"; - BGSOUND = "bgsound"; BIG = "big"; - BLINK = "blink"; CENTER = "center"; - COMMAND = "command"; FONT = "font"; - FRAME = "frame"; - FRAMESET = "frameset"; - IMAGE = "image"; - ISINDEX = "isindex"; - KEYGEN = "keygen"; - LISTING = "listing"; - MARQUEE = "marquee"; - MULTICOL = "multicol"; - NEXTID = "nextid"; - NOBR = "nobr"; - NOFRAMES = "noframes"; - PLAINTEXT = "plaintext"; - SPACER = "spacer"; STRIKE = "strike"; - XMP = "xmp"; }