From d148edbcf1c477e7df9392bf87c96c49295d3333 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sat, 6 Jun 2020 07:29:01 -0700 Subject: [PATCH 01/48] Exclude more resources from the distribution package (#257) --- .gitattributes | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/.gitattributes b/.gitattributes index c0bcf3bdc..4c528011b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,13 +1,23 @@ /.gitattributes export-ignore /.gitignore export-ignore /.travis.yml export-ignore -/Doxyfile export-ignore -/art/ export-ignore -/benchmarks/ export-ignore -/configdoc/ export-ignore +/art export-ignore +/benchmarks export-ignore +/configdoc export-ignore /configdoc/usage.xml -crlf -/docs/ export-ignore -/phpdoc.ini -/smoketests/ export-ignore -/tests/* export-ignore -/tests/path2class.func.php -export-ignore +/docs export-ignore +/Doxyfile export-ignore +/extras export-ignore +/INSTALL* export-ignore +/maintenance export-ignore +/NEWS export-ignore +/package.php export-ignore +/plugins export-ignore +/phpdoc.ini export-ignore +/smoketests export-ignore +/test-* export-ignore +/tests export-ignore +/TODO export-ignore +/update-for-release export-ignore +/WHATSNEW export-ignore +/WYSIWYG export-ignore From 3bdc031224ffac6edef45353069b281a3ed0a9b5 Mon Sep 17 00:00:00 2001 From: Mateusz Turcza Date: Mon, 29 Jun 2020 02:26:33 +0200 Subject: [PATCH 02/48] Add %HTML.Forms config directive (#260) The %HTML.Forms directive enables Forms module regardless of the %HTML.Trusted value. This adds support for form elements without enabling other unsafe modules, such as Scripts, Iframe or Object. To achieve the same effect without this directive one has to explicitly list all enabled modules in %HTML.AllowedModules, and any not listed will be removed. This however is not very convenient, as the allowed modules may vary between doctypes. Resolves #213. --- configdoc/usage.xml | 5 +++++ library/HTMLPurifier/ConfigSchema/schema.ser | 2 +- .../HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt | 11 +++++++++++ library/HTMLPurifier/HTMLModule/Forms.php | 4 ++++ tests/HTMLPurifier/HTMLModule/FormsTest.php | 7 +++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt diff --git a/configdoc/usage.xml b/configdoc/usage.xml index 65c34638b..d1c8edb0b 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -480,6 +480,11 @@ 330 + + + 31 + + 28 diff --git a/library/HTMLPurifier/ConfigSchema/schema.ser b/library/HTMLPurifier/ConfigSchema/schema.ser index 47bd259b2..a5426c736 100644 --- a/library/HTMLPurifier/ConfigSchema/schema.ser +++ b/library/HTMLPurifier/ConfigSchema/schema.ser @@ -1 +1 @@ -O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:139:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:23:"Core.AllowParseManyTags";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file +O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:127:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:127:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:140:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:23:"Core.AllowParseManyTags";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:10:"HTML.Forms";i:7;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file diff --git a/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt b/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt new file mode 100644 index 000000000..4a432d89b --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt @@ -0,0 +1,11 @@ +HTML.Forms +TYPE: bool +VERSION: 4.13.0 +DEFAULT: false +--DESCRIPTION-- +

+ Whether or not to permit form elements in the user input, regardless of + %HTML.Trusted value. Please be very careful when using this functionality, as + enabling forms in untrusted documents may allow for phishing attacks. +

+--# vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/HTMLModule/Forms.php b/library/HTMLPurifier/HTMLModule/Forms.php index 6f7ddbc05..eb0edcffd 100644 --- a/library/HTMLPurifier/HTMLModule/Forms.php +++ b/library/HTMLPurifier/HTMLModule/Forms.php @@ -28,6 +28,10 @@ class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule */ public function setup($config) { + if ($config->get('HTML.Forms')) { + $this->safe = true; + } + $form = $this->addElement( 'form', 'Form', diff --git a/tests/HTMLPurifier/HTMLModule/FormsTest.php b/tests/HTMLPurifier/HTMLModule/FormsTest.php index 09b0d4d1e..ceab8c243 100644 --- a/tests/HTMLPurifier/HTMLModule/FormsTest.php +++ b/tests/HTMLPurifier/HTMLModule/FormsTest.php @@ -161,6 +161,13 @@ public function testLegacy() $this->assertResult('
'); } + public function testHTMLFormsConfigDirective() + { + $this->config->set('HTML.Trusted', false); + $this->config->set('HTML.Forms', true); + + $this->assertResult('
'); + } } // vim: et sw=4 sts=4 From ce7efc11b20b47bc7f287ee66ef02b6cd4b6fce2 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 28 Jun 2020 20:38:16 -0400 Subject: [PATCH 03/48] Delete language tests that are interfering with PSR-0 compatibility Signed-off-by: Edward Z. Yang --- .../Language/classes/en-x-test.php | 9 ----- .../Language/messages/en-x-test.php | 13 ------- .../Language/messages/en-x-testmini.php | 14 ------- tests/HTMLPurifier/LanguageFactoryTest.php | 39 ------------------- 4 files changed, 75 deletions(-) delete mode 100644 library/HTMLPurifier/Language/classes/en-x-test.php delete mode 100644 library/HTMLPurifier/Language/messages/en-x-test.php delete mode 100644 library/HTMLPurifier/Language/messages/en-x-testmini.php diff --git a/library/HTMLPurifier/Language/classes/en-x-test.php b/library/HTMLPurifier/Language/classes/en-x-test.php deleted file mode 100644 index 8828f5cde..000000000 --- a/library/HTMLPurifier/Language/classes/en-x-test.php +++ /dev/null @@ -1,9 +0,0 @@ - 'HTML Purifier X' -); - -$errorNames = array(); - -// vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/Language/messages/en-x-testmini.php b/library/HTMLPurifier/Language/messages/en-x-testmini.php deleted file mode 100644 index e1e7db500..000000000 --- a/library/HTMLPurifier/Language/messages/en-x-testmini.php +++ /dev/null @@ -1,14 +0,0 @@ - 'HTML Purifier XNone' -); - -$errorNames = array(); - -// vim: et sw=4 sts=4 diff --git a/tests/HTMLPurifier/LanguageFactoryTest.php b/tests/HTMLPurifier/LanguageFactoryTest.php index e1a73ac79..2cc9a793b 100644 --- a/tests/HTMLPurifier/LanguageFactoryTest.php +++ b/tests/HTMLPurifier/LanguageFactoryTest.php @@ -29,45 +29,6 @@ public function test() } - public function testFallback() - { - $this->config->set('Core.Language', 'en-x-test'); - $language = $this->factory->create($this->config, $this->context); - - $this->assertIsA($language, 'HTMLPurifier_Language_en_x_test'); - $this->assertIdentical($language->code, 'en-x-test'); - - $language->load(); - - // test overloaded message - $this->assertIdentical($language->getMessage('HTMLPurifier'), 'HTML Purifier X'); - - // test inherited message - $this->assertIdentical($language->getMessage('LanguageFactoryTest: Pizza'), 'Pizza'); - - } - - public function testFallbackWithNoClass() - { - $this->config->set('Core.Language', 'en-x-testmini'); - $language = $this->factory->create($this->config, $this->context); - $this->assertIsA($language, 'HTMLPurifier_Language'); - $this->assertIdentical($language->code, 'en-x-testmini'); - $language->load(); - $this->assertIdentical($language->getMessage('HTMLPurifier'), 'HTML Purifier XNone'); - $this->assertIdentical($language->getMessage('LanguageFactoryTest: Pizza'), 'Pizza'); - $this->assertIdentical($language->error, false); - } - - public function testNoSuchLanguage() - { - $this->config->set('Core.Language', 'en-x-testnone'); - $language = $this->factory->create($this->config, $this->context); - $this->assertIsA($language, 'HTMLPurifier_Language'); - $this->assertIdentical($language->code, 'en-x-testnone'); - $this->assertIdentical($language->error, true); - } - } // vim: et sw=4 sts=4 From d7be9d2a8c7873d6acf25261da28e42c36bb1380 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 28 Jun 2020 20:55:45 -0400 Subject: [PATCH 04/48] Update changelog Signed-off-by: Edward Z. Yang --- NEWS | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/NEWS b/NEWS index 352835012..c74d4b35e 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,28 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== +4.13.0, unknown release date +! Add %HTML.Forms directive, which lets you accept forms in user + HTML without requiring full %HTML.Trusted. Note that forms can + be (trivially) used to setup phishing; e.g., an attacker can + use CSS absolute positioning to overlay a form on top of a login + element, so please be sure to use this with care! Fixes #213. + Thanks Mateusz Turcza for contributing this feature. +! tr@bgcolor attribute is now supported. Thanks Kieran Brahney + for this enhancement. +- Further improvements to PHP 6.4 support, contributed by Witold + Wasiczko and Eloy Lafuente. +- Fix PSR-0 compatibility. Thanks Jordi Boggiano for contributing + part of this fix. +- Fix bug with purifyArray where it doesn't work on empty arrays. + Thanks Fräntz Miccoli for the fix. +- Reduce amount of maintenance scripts included in distribution + packages. Thanks Sergei Morozov for this patch. +- Remove leading zeros unless if it is only a zero, fixes #239. Thanks + lubomirbartos for this fix. +- Correct type hinting of maybeGet*, fixes #240. Thanks Anders Jenbo + for this fix. + 4.12.0, released 2019-10-27 ! PHP 7.4 is supported, thank you Witold Wasiczko, Mateuz Turcza and Edi Modrić From 08e27c97e4c6ed02f37c5b2b20488046c8d90d75 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 28 Jun 2020 20:56:53 -0400 Subject: [PATCH 05/48] Release 4.13.0 Signed-off-by: Edward Z. Yang --- Doxyfile | 2 +- NEWS | 2 +- VERSION | 2 +- WHATSNEW | 6 ++++-- library/HTMLPurifier.includes.php | 2 +- library/HTMLPurifier.php | 6 +++--- library/HTMLPurifier/Config.php | 2 +- update-for-release | 2 +- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Doxyfile b/Doxyfile index fb53e475a..fdb92fe30 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 4.12.0 +PROJECT_NUMBER = 4.13.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/NEWS b/NEWS index c74d4b35e..8e1b8e4c9 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== -4.13.0, unknown release date +4.13.0, released 2020-06-28 ! Add %HTML.Forms directive, which lets you accept forms in user HTML without requiring full %HTML.Trusted. Note that forms can be (trivially) used to setup phishing; e.g., an attacker can diff --git a/VERSION b/VERSION index bcd250ed0..01b73abe5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.12.0 \ No newline at end of file +4.13.0 \ No newline at end of file diff --git a/WHATSNEW b/WHATSNEW index aec9b37c1..ae24886ee 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -1,2 +1,4 @@ -HTML Purifier 4.12.x is a maintenance release which makes -compatibility fixes for PHP 7.4. +HTML Purifier 4.13.x is a maintenance release which fixes +PSR-0 compatibility of our package. There are also a few +new features (%HTML.Forms and tg@bgcolor support) and +a number of minor bugfixes. diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index 3158b2b86..151e6752d 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.12.0 + * @version 4.13.0 * * @warning * You must *not* include any other HTML Purifier files before this file, diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index 10e61c149..3c0f8a0ec 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.12.0 - Standards Compliant HTML Filtering + HTML Purifier 4.13.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.12.0'; + public $version = '4.13.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.12.0'; + const VERSION = '4.13.0'; /** * Global configuration object. diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index 4ecaa141a..3133d8a4f 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.12.0'; + public $version = '4.13.0'; /** * Whether or not to automatically finalize diff --git a/update-for-release b/update-for-release index 32709d25e..2b9662a76 100644 --- a/update-for-release +++ b/update-for-release @@ -104,7 +104,7 @@ file_put_contents('library/HTMLPurifier/Config.php', $config_c); passthru('maintenance/flush.sh'); -if ($is_dev) echo "Review changes, write something in WHATSNEW and FOCUS, and then commit with log 'Release $version.'" . PHP_EOL; +if ($is_dev) echo "Review changes, write something in WHATSNEW, and then commit with log 'Release $version.'" . PHP_EOL; else echo "Numbers updated to dev, no other modifications necessary!"; // vim: et sw=4 sts=4 From 15258fd24ee4c3da2e4681f41ce9404c74f8b24d Mon Sep 17 00:00:00 2001 From: LeSuisse Date: Mon, 6 Jul 2020 20:36:33 +0200 Subject: [PATCH 06/48] Fix typo in the 4.13.0 NEWS: PHP 6.4 never existed (#262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corresponding PRs (#230, #242) are about PHP 7.4 and PHP 6.4 has never existed 🙂. --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8e1b8e4c9..0c1fdd790 100644 --- a/NEWS +++ b/NEWS @@ -18,7 +18,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier Thanks Mateusz Turcza for contributing this feature. ! tr@bgcolor attribute is now supported. Thanks Kieran Brahney for this enhancement. -- Further improvements to PHP 6.4 support, contributed by Witold +- Further improvements to PHP 7.4 support, contributed by Witold Wasiczko and Eloy Lafuente. - Fix PSR-0 compatibility. Thanks Jordi Boggiano for contributing part of this fix. From 4285590c90a1eaf36eb6ae147cc1cbfa7aa546a6 Mon Sep 17 00:00:00 2001 From: kishor <44048735+kish0808@users.noreply.github.com> Date: Tue, 15 Sep 2020 22:08:39 +0530 Subject: [PATCH 07/48] issue-256: Fix PHP 7.3 compatibility issues (#266) --- library/HTMLPurifier.autoload-legacy.php | 5 +++-- library/HTMLPurifier/HTMLModule.php | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/library/HTMLPurifier.autoload-legacy.php b/library/HTMLPurifier.autoload-legacy.php index c271cd158..7766b2037 100644 --- a/library/HTMLPurifier.autoload-legacy.php +++ b/library/HTMLPurifier.autoload-legacy.php @@ -7,9 +7,10 @@ * Must be separate to prevent deprecation warning on PHP 7.2 */ -function __autoload($class) +spl_autoload_register(function($class) { - return HTMLPurifier_Bootstrap::autoload($class); + return HTMLPurifier_Bootstrap::autoload($class); } +}); // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/HTMLModule.php b/library/HTMLPurifier/HTMLModule.php index 6d898f80c..9dbb98729 100644 --- a/library/HTMLPurifier/HTMLModule.php +++ b/library/HTMLPurifier/HTMLModule.php @@ -257,8 +257,9 @@ public function mergeInAttrIncludes(&$attr, $attr_includes) */ public function makeLookup($list) { + $args = func_get_args(); if (is_string($list)) { - $list = func_get_args(); + $list = $args; } $ret = array(); foreach ($list as $value) { From 6aa4166b7ef5021c6e6d95748a37e9541bd984d5 Mon Sep 17 00:00:00 2001 From: kishor <44048735+kish0808@users.noreply.github.com> Date: Wed, 16 Sep 2020 05:42:43 +0530 Subject: [PATCH 08/48] Issue-256: Fix PHP 7.3 compatibility issues update zend.ze1_compatibility_mode mode (#267) --- library/HTMLPurifier.autoload-legacy.php | 2 -- library/HTMLPurifier.autoload.php | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/library/HTMLPurifier.autoload-legacy.php b/library/HTMLPurifier.autoload-legacy.php index 7766b2037..0a17ee4ad 100644 --- a/library/HTMLPurifier.autoload-legacy.php +++ b/library/HTMLPurifier.autoload-legacy.php @@ -4,13 +4,11 @@ * @file * Legacy autoloader for systems lacking spl_autoload_register * - * Must be separate to prevent deprecation warning on PHP 7.2 */ spl_autoload_register(function($class) { return HTMLPurifier_Bootstrap::autoload($class); -} }); // vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier.autoload.php b/library/HTMLPurifier.autoload.php index 9d8d29926..7a691132f 100644 --- a/library/HTMLPurifier.autoload.php +++ b/library/HTMLPurifier.autoload.php @@ -17,6 +17,7 @@ require dirname(__FILE__) . '/HTMLPurifier.autoload-legacy.php'; } +// phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.zend_ze1_compatibility_modeRemoved if (ini_get('zend.ze1_compatibility_mode')) { trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR); } From 2512f595e0f4c5235e99ef97603a8db902b3cc5f Mon Sep 17 00:00:00 2001 From: Jasper Zonneveld Date: Thu, 1 Oct 2020 02:19:10 +0200 Subject: [PATCH 09/48] Check PHP version before checking magic quotes (#273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function has been DEPRECATED as of PHP 7.4.0. Relying on this function is highly discouraged. It is basically useless as of PHP 5.4 because it will always return false, so for modern applications it can be safely removed. But as this library still supports PHP 5.2 — according to the constraints in composer.json — I added a version check to prevent this method from being called (and trigger a notice) on PHP >=7.4. See: https://www.php.net/manual/en/function.get-magic-quotes-gpc.php --- library/HTMLPurifier/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index 3133d8a4f..f74c1f04d 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -803,7 +803,7 @@ public static function prepareArrayFromForm($array, $index = false, $allowed = t if ($index !== false) { $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); } - $mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); + $mq = $mq_fix && version_compare(PHP_VERSION, '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); $ret = array(); From 214cb8a6934f9682ce5a9d7a7f5a76801c7822e6 Mon Sep 17 00:00:00 2001 From: Marcus Artner Date: Tue, 26 Jan 2021 17:11:50 +0100 Subject: [PATCH 10/48] Fixed Issue #264: element removed from if there are no or elements (#283) --- library/HTMLPurifier/ChildDef/Table.php | 2 +- tests/HTMLPurifier/ChildDef/TableTest.php | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/library/HTMLPurifier/ChildDef/Table.php b/library/HTMLPurifier/ChildDef/Table.php index cb6b3e6cd..67c7e9535 100644 --- a/library/HTMLPurifier/ChildDef/Table.php +++ b/library/HTMLPurifier/ChildDef/Table.php @@ -164,7 +164,7 @@ public function validateChildren($children, $config, $context) } } - if (empty($content)) { + if (empty($content) && $thead === false && $tfoot === false) { return false; } diff --git a/tests/HTMLPurifier/ChildDef/TableTest.php b/tests/HTMLPurifier/ChildDef/TableTest.php index 49e96b652..aba6b1dc9 100644 --- a/tests/HTMLPurifier/ChildDef/TableTest.php +++ b/tests/HTMLPurifier/ChildDef/TableTest.php @@ -44,6 +44,22 @@ public function testXhtml11Illegal() ); } + public function testTheadOnlyNotRemoved() + { + $this->assertResult( + '', + '' + ); + } + + public function testTbodyOnlyNotRemoved() + { + $this->assertResult( + '', + '' + ); + } + public function testTrOverflowAndClose() { $this->assertResult( From 1354e7e8c558dc9ae353e07b8cde7ab0d46e7a25 Mon Sep 17 00:00:00 2001 From: Kieran Date: Sun, 28 Feb 2021 01:42:20 +0000 Subject: [PATCH 11/48] Fix "Parameter must be an array or an object that implements Countable" (#285) --- library/HTMLPurifier/Injector/Linkify.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/HTMLPurifier/Injector/Linkify.php b/library/HTMLPurifier/Injector/Linkify.php index 74f83eaa7..3b6d70f6e 100644 --- a/library/HTMLPurifier/Injector/Linkify.php +++ b/library/HTMLPurifier/Injector/Linkify.php @@ -40,6 +40,9 @@ public function handleText(&$token) '/\\b((?:[a-z][\\w\\-]+:(?:\\/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}\\/)(?:[^\\s()<>]|\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\))+(?:\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'".,<>?\x{00ab}\x{00bb}\x{201c}\x{201d}\x{2018}\x{2019}]))/iu', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE); + if ($bits === false) { + return; + } $token = array(); From 6f9aac9325e99a860928534cd4a5ade8962d3751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Sm=C3=ADtal?= Date: Thu, 22 Apr 2021 16:01:00 +0200 Subject: [PATCH 12/48] CSS: Add "background-size" tag support (#289) --- library/HTMLPurifier/AttrDef/CSS/Background.php | 2 ++ library/HTMLPurifier/CSSDefinition.php | 16 ++++++++++++++++ tests/HTMLPurifier/AttrDef/CSSTest.php | 3 +++ 3 files changed, 21 insertions(+) diff --git a/library/HTMLPurifier/AttrDef/CSS/Background.php b/library/HTMLPurifier/AttrDef/CSS/Background.php index 7f1ea3b0f..28c49883a 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Background.php +++ b/library/HTMLPurifier/AttrDef/CSS/Background.php @@ -25,6 +25,7 @@ public function __construct($config) $this->info['background-repeat'] = $def->info['background-repeat']; $this->info['background-attachment'] = $def->info['background-attachment']; $this->info['background-position'] = $def->info['background-position']; + $this->info['background-size'] = $def->info['background-size']; } /** @@ -53,6 +54,7 @@ public function validate($string, $config, $context) $caught['repeat'] = false; $caught['attachment'] = false; $caught['position'] = false; + $caught['size'] = false; $i = 0; // number of catches diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php index 21f1a5899..3f08b81c5 100644 --- a/library/HTMLPurifier/CSSDefinition.php +++ b/library/HTMLPurifier/CSSDefinition.php @@ -109,6 +109,22 @@ protected function doSetup($config) ); $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); + $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum( + array( + 'auto', + 'cover', + 'contain', + 'initial', + 'inherit', + ) + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + $border_color = $this->info['border-top-color'] = $this->info['border-bottom-color'] = diff --git a/tests/HTMLPurifier/AttrDef/CSSTest.php b/tests/HTMLPurifier/AttrDef/CSSTest.php index 318f471fd..17a56581b 100644 --- a/tests/HTMLPurifier/AttrDef/CSSTest.php +++ b/tests/HTMLPurifier/AttrDef/CSSTest.php @@ -92,6 +92,9 @@ public function test() $this->assertDef('background-repeat:repeat-y;'); $this->assertDef('background-attachment:fixed;'); $this->assertDef('background-position:left 90%;'); + $this->assertDef('background-size:50%;'); + $this->assertDef('background-size:cover;'); + $this->assertDef('background-size:200px;'); $this->assertDef('border-spacing:1em;'); $this->assertDef('border-spacing:1em 2em;'); $this->assertDef('border-color: rgb(0, 0, 0) rgb(10,0,10)', 'border-color:rgb(0,0,0) rgb(10,0,10);'); From 3a368d76686683d73c3463c7d051c12664f54ad2 Mon Sep 17 00:00:00 2001 From: Kieran Date: Sat, 22 May 2021 01:46:13 +0100 Subject: [PATCH 13/48] Switch to GitHub Actions (#293) --- .gitattributes | 2 +- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++++++++++ .travis.yml | 19 ------------------- 3 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.gitattributes b/.gitattributes index 4c528011b..7542171d4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,6 @@ /.gitattributes export-ignore +/.github export-ignore /.gitignore export-ignore -/.travis.yml export-ignore /art export-ignore /benchmarks export-ignore /configdoc export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..b95f9a4ee --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: ci + +on: + push: + branches: + - "master" + pull_request: + +jobs: + linux_tests: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4] + + name: PHP ${{ matrix.php }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + + - name: Clone simpletest + run: git clone --depth=50 https://github.com/ezyang/simpletest.git + + - name: Configure simpletest + run: cp test-settings.travis.php test-settings.php + + - name: Execute Unit tests + run: php tests/index.php diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b44c52a98..000000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: php -php: - - '5.6' - - '7.0' - - '7.1' - - '7.2' - - '7.3' - - '7.4' -matrix: - include: - - php: '5.4' - dist: trusty - - php: '5.5' - dist: trusty -before_script: - - git clone --depth=50 https://github.com/ezyang/simpletest.git - - cp test-settings.travis.php test-settings.php -script: - - php tests/index.php From 288bf75accb2d7949d955f033dda8221354f64df Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 20 Jul 2021 16:40:50 +0300 Subject: [PATCH 14/48] PHP 8 Support (#297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maksims Sļotovs --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b95f9a4ee..fa3849afd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: true matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4] + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0] name: PHP ${{ matrix.php }} diff --git a/README.md b/README.md index 9e0becc0a..e6b7199c1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -HTML Purifier [![Build Status](https://secure.travis-ci.org/ezyang/htmlpurifier.svg?branch=master)](http://travis-ci.org/ezyang/htmlpurifier) +HTML Purifier [![Build Status](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml) ============= HTML Purifier is an HTML filtering solution that uses a unique combination From c97bb9322386385a2cbfdd7aab705e3a47050581 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 26 Jul 2021 15:16:49 +0100 Subject: [PATCH 15/48] Fix GH workflow conditions (#298) * Fix GH workflow conditions * Remove PHP 8 --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa3849afd..907d0112e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,6 @@ name: ci on: push: - branches: - - "master" pull_request: jobs: @@ -12,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0] + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4] name: PHP ${{ matrix.php }} From 996eaf43310edf1d908bc0030a18b37b8cf6eefd Mon Sep 17 00:00:00 2001 From: Arkadiusz Biczewski Date: Tue, 7 Sep 2021 20:16:55 +0200 Subject: [PATCH 16/48] Remove unnecessary reference assigment (#301) * Remove unnecessary reference assigment Proposed code is PHP5 and PHP7 compatible. PHP5 interpreted `$e->$type[$attr]` as `$e->{$type[$attr]}`, but the expected behavior based on workaround is consistent with PHP7 interpretation: `($e->$type)[$attr]`. By using curly braces `{$e->$type}[$attr]` there is a forced interpretation order working for both versions. Details can be found on https://www.php.net/manual/en/migration70.incompatible.php (section "Changes to the handling of indirect variables, properties, and methods") * Fix syntax Use correct syntax for indirect variable evaluation order change. --- library/HTMLPurifier/HTMLModule/Tidy.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/HTMLPurifier/HTMLModule/Tidy.php b/library/HTMLPurifier/HTMLModule/Tidy.php index 08aa23247..12173ba70 100644 --- a/library/HTMLPurifier/HTMLModule/Tidy.php +++ b/library/HTMLPurifier/HTMLModule/Tidy.php @@ -146,10 +146,7 @@ public function populate($fixes) $type = "info_$type"; $e = $this; } - // PHP does some weird parsing when I do - // $e->$type[$attr], so I have to assign a ref. - $f =& $e->$type; - $f[$attr] = $fix; + $e->{$type}[$attr] = $fix; break; case 'tag_transform': $this->info_tag_transform[$params['element']] = $fix; From 41fc223f9671af0972ca392b892601e29ac22cf8 Mon Sep 17 00:00:00 2001 From: Kieran Date: Fri, 24 Dec 2021 02:26:14 +0000 Subject: [PATCH 17/48] feat: transform deprecated width attribute (#306) * Transform deprecated col@width attribute * Transform deprecated table@width attribute * reformat --- library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php b/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php index 700a25dbc..9ee3ffcc9 100644 --- a/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php +++ b/library/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php @@ -168,9 +168,11 @@ public function makeFixes() // @vspace for img ------------------------------------------------ $r['img@vspace'] = new HTMLPurifier_AttrTransform_ImgSpace('vspace'); - // @width for hr, td, th ------------------------------------------ + // @width for table, hr, td, th, col ------------------------------------------ + $r['table@width'] = $r['td@width'] = $r['th@width'] = + $r['col@width'] = $r['hr@width'] = new HTMLPurifier_AttrTransform_Length('width'); return $r; From 1c784a5c3d95941cd1ed40799c3931eda2024c3e Mon Sep 17 00:00:00 2001 From: Kieran Date: Fri, 24 Dec 2021 02:26:25 +0000 Subject: [PATCH 18/48] ci: test on php 8.0 (#308) * PHP 8 support * only php 8.0 * Merged to master Co-authored-by: Edward Z. Yang --- .github/workflows/ci.yml | 2 +- composer.json | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 907d0112e..7fe862e1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4] + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0] name: PHP ${{ matrix.php }} diff --git a/composer.json b/composer.json index 0ff86b5df..5f62d889d 100644 --- a/composer.json +++ b/composer.json @@ -15,9 +15,6 @@ "require": { "php": ">=5.2" }, - "require-dev": { - "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd" - }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, "files": ["library/HTMLPurifier.composer.php"], From 12ab42bd6e742c70c0a52f7b82477fcd44e64b75 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Fri, 24 Dec 2021 20:21:49 -0500 Subject: [PATCH 19/48] Release 4.14.0 Signed-off-by: Edward Z. Yang --- Doxyfile | 2 +- NEWS | 15 +++++++++++++++ VERSION | 2 +- WHATSNEW | 8 ++++---- configdoc/usage.xml | 14 +++++++------- library/HTMLPurifier.includes.php | 2 +- library/HTMLPurifier.php | 6 +++--- library/HTMLPurifier/Config.php | 2 +- 8 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Doxyfile b/Doxyfile index fdb92fe30..7d01f31d7 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 4.13.0 +PROJECT_NUMBER = 4.14.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/NEWS b/NEWS index 0c1fdd790..92c87218f 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,21 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== +4.14.0, released 2021-12-24 +! Add "background-size" support (#289), contributed by Václav Smítal +! Transform deprecated width attribute when tidying HTML, contributed by + Kieran. +- PHP 8 support, contributed by Maksims Sļotovs. +- Improved PHP 7.3 compatibility, contributed by kishor. +- Avoid spurious magic quotes notice in PHP 7.4. Thanks + Jasper Zonneveld for the fix. +- Do not remove thead from table even if there are no tbody/tr (#264). + Thanks Marcus Artner for the fix. +- Fix "Parameter must be an array or an object that implements + Countable" (#285)". Thanks Kieran for this fix. +. Fix unnecessary reference assignment, handling behavior change from + PHP5 and PHP7. Thanks Arkadiusz Biczewski for the fix. + 4.13.0, released 2020-06-28 ! Add %HTML.Forms directive, which lets you accept forms in user HTML without requiring full %HTML.Trusted. Note that forms can diff --git a/VERSION b/VERSION index 01b73abe5..09ce0ce71 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.13.0 \ No newline at end of file +4.14.0 \ No newline at end of file diff --git a/WHATSNEW b/WHATSNEW index ae24886ee..4d5e9291f 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -1,4 +1,4 @@ -HTML Purifier 4.13.x is a maintenance release which fixes -PSR-0 compatibility of our package. There are also a few -new features (%HTML.Forms and tg@bgcolor support) and -a number of minor bugfixes. +HTML Purifier 4.14.x is a maintenance release which improves +PHP7 and PHP8 compatibility. There are also some minor new features +(background-size) and some miscellaneous fixes to remove notices +from recent versions of PHP. diff --git a/configdoc/usage.xml b/configdoc/usage.xml index d1c8edb0b..c0df5aba4 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -19,37 +19,37 @@ - 240 + 256 - 365 + 381 - 369 + 385 - 373 + 389 - 377 + 393 - 506 + 522 - 522 + 538 diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index 151e6752d..ee81cac68 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.13.0 + * @version 4.14.0 * * @warning * You must *not* include any other HTML Purifier files before this file, diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index 3c0f8a0ec..2177fc851 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.13.0 - Standards Compliant HTML Filtering + HTML Purifier 4.14.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.13.0'; + public $version = '4.14.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.13.0'; + const VERSION = '4.14.0'; /** * Global configuration object. diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index f74c1f04d..16a6b322b 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.13.0'; + public $version = '4.14.0'; /** * Whether or not to automatically finalize From 1dd3e52365c32a142fb7c9c9f8f038f18e353270 Mon Sep 17 00:00:00 2001 From: David Rans Date: Fri, 8 Apr 2022 11:48:12 -0600 Subject: [PATCH 20/48] PHP 8.1: fix various deprecations/errors in newest version of PHP (#310) * Test on PHP 8.1 * PHP 8.1: fix deprecated NULL param to glob() * PHP 8.1: fix PHP error when passing NULL to rawurlencode() * PHP 8.1: calling ctype_lower with FALSE is deprecated * PHP 8.1: passing NULL to setAttribute() is deprecated * PHP 8.1: passing NULL to str_replace() is an error * PHP 8.1: fix error passing NULL to str_replace() * PHP 8.1: fix return type deprecation with backwards compatible attribute * Revert typo --- .github/workflows/ci.yml | 2 +- extras/FSTools.php | 2 +- library/HTMLPurifier/ElementDef.php | 2 +- library/HTMLPurifier/Length.php | 2 +- library/HTMLPurifier/Lexer.php | 4 ++-- library/HTMLPurifier/Lexer/PH5P.php | 2 +- library/HTMLPurifier/PropertyListIterator.php | 1 + library/HTMLPurifier/StringHash.php | 1 + library/HTMLPurifier/URIFilter/Munge.php | 10 +++++----- 9 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fe862e1b..ebb9e1a32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0] + php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1] name: PHP ${{ matrix.php }} diff --git a/extras/FSTools.php b/extras/FSTools.php index ce0076316..90d0f986a 100644 --- a/extras/FSTools.php +++ b/extras/FSTools.php @@ -136,7 +136,7 @@ public function rmdirr($dirname) /** * Recursively globs a directory. */ - public function globr($dir, $pattern, $flags = NULL) + public function globr($dir, $pattern, $flags = 0) { $files = $this->glob("$dir/$pattern", $flags); if ($files === false) $files = array(); diff --git a/library/HTMLPurifier/ElementDef.php b/library/HTMLPurifier/ElementDef.php index d5311cedc..57cfd2bb0 100644 --- a/library/HTMLPurifier/ElementDef.php +++ b/library/HTMLPurifier/ElementDef.php @@ -176,7 +176,7 @@ public function mergeIn($def) if (!empty($def->content_model)) { $this->content_model = - str_replace("#SUPER", $this->content_model, $def->content_model); + str_replace("#SUPER", (string)$this->content_model, $def->content_model); $this->child = false; } if (!empty($def->content_model_type)) { diff --git a/library/HTMLPurifier/Length.php b/library/HTMLPurifier/Length.php index e70da55a9..b6ea12345 100644 --- a/library/HTMLPurifier/Length.php +++ b/library/HTMLPurifier/Length.php @@ -78,7 +78,7 @@ protected function validate() if ($this->n === '0' && $this->unit === false) { return true; } - if (!ctype_lower($this->unit)) { + if ($this->unit === false || !ctype_lower($this->unit)) { $this->unit = strtolower($this->unit); } if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { diff --git a/library/HTMLPurifier/Lexer.php b/library/HTMLPurifier/Lexer.php index e9da3ed5e..e79009fda 100644 --- a/library/HTMLPurifier/Lexer.php +++ b/library/HTMLPurifier/Lexer.php @@ -306,8 +306,8 @@ public function normalize($html, $config, $context) { // normalize newlines to \n if ($config->get('Core.NormalizeNewlines')) { - $html = str_replace("\r\n", "\n", $html); - $html = str_replace("\r", "\n", $html); + $html = str_replace("\r\n", "\n", (string)$html); + $html = str_replace("\r", "\n", (string)$html); } if ($config->get('HTML.Trusted')) { diff --git a/library/HTMLPurifier/Lexer/PH5P.php b/library/HTMLPurifier/Lexer/PH5P.php index 72476ddf3..1564f283d 100644 --- a/library/HTMLPurifier/Lexer/PH5P.php +++ b/library/HTMLPurifier/Lexer/PH5P.php @@ -4410,7 +4410,7 @@ private function insertElement($token, $append = true, $check = false) foreach ($token['attr'] as $attr) { if (!$el->hasAttribute($attr['name'])) { - $el->setAttribute($attr['name'], $attr['value']); + $el->setAttribute($attr['name'], (string)$attr['value']); } } diff --git a/library/HTMLPurifier/PropertyListIterator.php b/library/HTMLPurifier/PropertyListIterator.php index 15b330ea3..f68fc8c30 100644 --- a/library/HTMLPurifier/PropertyListIterator.php +++ b/library/HTMLPurifier/PropertyListIterator.php @@ -29,6 +29,7 @@ public function __construct(Iterator $iterator, $filter = null) /** * @return bool */ + #[\ReturnTypeWillChange] public function accept() { $key = $this->getInnerIterator()->key(); diff --git a/library/HTMLPurifier/StringHash.php b/library/HTMLPurifier/StringHash.php index c07370197..c41ae3a76 100644 --- a/library/HTMLPurifier/StringHash.php +++ b/library/HTMLPurifier/StringHash.php @@ -20,6 +20,7 @@ class HTMLPurifier_StringHash extends ArrayObject * @param mixed $index * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($index) { $this->accessed[$index] = true; diff --git a/library/HTMLPurifier/URIFilter/Munge.php b/library/HTMLPurifier/URIFilter/Munge.php index 6e03315a1..e1393deb7 100644 --- a/library/HTMLPurifier/URIFilter/Munge.php +++ b/library/HTMLPurifier/URIFilter/Munge.php @@ -100,11 +100,11 @@ protected function makeReplace($uri, $config, $context) $string = $uri->toString(); // always available $this->replace['%s'] = $string; - $this->replace['%r'] = $context->get('EmbeddedURI', true); - $token = $context->get('CurrentToken', true); - $this->replace['%n'] = $token ? $token->name : null; - $this->replace['%m'] = $context->get('CurrentAttr', true); - $this->replace['%p'] = $context->get('CurrentCSSProperty', true); + $this->replace['%r'] = $context->get('EmbeddedURI', true) ?: ''; + $token = $context->get('CurrentToken', true) ?: ''; + $this->replace['%n'] = $token ? $token->name : ''; + $this->replace['%m'] = $context->get('CurrentAttr', true) ?: ''; + $this->replace['%p'] = $context->get('CurrentCSSProperty', true) ?: ''; // not always available if ($this->secretKey) { $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); From 38296c603b8b967e59a783c146ae61703a85663a Mon Sep 17 00:00:00 2001 From: func0der <529819+func0der@users.noreply.github.com> Date: Fri, 3 Jun 2022 05:03:44 +0200 Subject: [PATCH 21/48] Composer suggestions with extensions (#317) * Add suggestion for usage of Filter.ExtractStyleBlocks Resolves #316 * Add php extensions as suggestions Resolves #316 * Correct typo in composer property --- composer.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/composer.json b/composer.json index 5f62d889d..7e1e68086 100644 --- a/composer.json +++ b/composer.json @@ -21,5 +21,11 @@ "exclude-from-classmap": [ "/library/HTMLPurifier/Language/" ] + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-tidy": "Used for pretty-printing HTML" } } From 1db36fb09d4ab1bce79722014e70e7a96ad76165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Fri, 10 Jun 2022 22:30:01 +0200 Subject: [PATCH 22/48] Fix some PHP 8.2 deprecations (#319) * Define HTMLPurifier_Lexer::$_entity_parser property This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_URIFilterHarness::$filter property This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_AttrTransform_NameSync::$idDef property This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_AttrTransform_NameSyncTest::$accumulator property This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_AttrValidator_ErrorsTest::$language property This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_ChildDef_List::$whitespace property This fixes a PHP 8.2 deprecation. * Do not modify incoming tokens in RemoveSpansWithoutAttributes Previously the undefined property `->markForDeletion` was added to the incoming tokens. This causes a deprecation in PHP 8.2. Fix this by storing to-be-deleted tokens inside SplObjectStorage. In PHP 8 a WeakMap would be preferable, as that prevents leaks if `handleEnd` is never called for the token. --- library/HTMLPurifier/AttrTransform/NameSync.php | 5 +++++ library/HTMLPurifier/ChildDef/List.php | 2 ++ .../Injector/RemoveSpansWithoutAttributes.php | 15 +++++++++++++-- library/HTMLPurifier/Lexer.php | 5 +++++ tests/HTMLPurifier/AttrTransform/NameSyncTest.php | 5 +++++ tests/HTMLPurifier/AttrValidator_ErrorsTest.php | 5 +++++ tests/HTMLPurifier/URIFilterHarness.php | 5 +++++ 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/library/HTMLPurifier/AttrTransform/NameSync.php b/library/HTMLPurifier/AttrTransform/NameSync.php index 36079b786..5a1fdbbfc 100644 --- a/library/HTMLPurifier/AttrTransform/NameSync.php +++ b/library/HTMLPurifier/AttrTransform/NameSync.php @@ -8,6 +8,11 @@ class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform { + /** + * @type HTMLPurifier_AttrDef_HTML_ID + */ + public $idDef; + public function __construct() { $this->idDef = new HTMLPurifier_AttrDef_HTML_ID(); diff --git a/library/HTMLPurifier/ChildDef/List.php b/library/HTMLPurifier/ChildDef/List.php index 4fc70e0ef..3d584e727 100644 --- a/library/HTMLPurifier/ChildDef/List.php +++ b/library/HTMLPurifier/ChildDef/List.php @@ -22,6 +22,8 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef // XXX: This whole business with 'wrap' is all a bit unsatisfactory public $elements = array('li' => true, 'ul' => true, 'ol' => true); + public $whitespace; + /** * @param array $children * @param HTMLPurifier_Config $config diff --git a/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php b/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php index 9ee7aa84d..42d514447 100644 --- a/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php +++ b/library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php @@ -31,6 +31,16 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In */ private $context; + /** + * @type SplObjectStorage + */ + private $markForDeletion; + + public function __construct() + { + $this->markForDeletion = new SplObjectStorage(); + } + public function prepare($config, $context) { $this->attrValidator = new HTMLPurifier_AttrValidator(); @@ -64,7 +74,7 @@ public function handleElement(&$token) if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') { // Mark closing span tag for deletion - $current->markForDeletion = true; + $this->markForDeletion->attach($current); // Delete open span tag $token = false; } @@ -75,7 +85,8 @@ public function handleElement(&$token) */ public function handleEnd(&$token) { - if ($token->markForDeletion) { + if ($this->markForDeletion->contains($token)) { + $this->markForDeletion->detach($token); $token = false; } } diff --git a/library/HTMLPurifier/Lexer.php b/library/HTMLPurifier/Lexer.php index e79009fda..c21f36491 100644 --- a/library/HTMLPurifier/Lexer.php +++ b/library/HTMLPurifier/Lexer.php @@ -48,6 +48,11 @@ class HTMLPurifier_Lexer */ public $tracksLineNumbers = false; + /** + * @type HTMLPurifier_EntityParser + */ + private $_entity_parser; + // -- STATIC ---------------------------------------------------------- /** diff --git a/tests/HTMLPurifier/AttrTransform/NameSyncTest.php b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php index 989b0ee84..d41ccc707 100644 --- a/tests/HTMLPurifier/AttrTransform/NameSyncTest.php +++ b/tests/HTMLPurifier/AttrTransform/NameSyncTest.php @@ -3,6 +3,11 @@ class HTMLPurifier_AttrTransform_NameSyncTest extends HTMLPurifier_AttrTransformHarness { + /** + * @type HTMLPurifier_IDAccumulator + */ + public $accumulator; + public function setUp() { parent::setUp(); diff --git a/tests/HTMLPurifier/AttrValidator_ErrorsTest.php b/tests/HTMLPurifier/AttrValidator_ErrorsTest.php index 98693afb6..709b3ba23 100644 --- a/tests/HTMLPurifier/AttrValidator_ErrorsTest.php +++ b/tests/HTMLPurifier/AttrValidator_ErrorsTest.php @@ -3,6 +3,11 @@ class HTMLPurifier_AttrValidator_ErrorsTest extends HTMLPurifier_ErrorsHarness { + /** + * @type HTMLPurifier_Language + */ + public $language; + public function setup() { parent::setup(); diff --git a/tests/HTMLPurifier/URIFilterHarness.php b/tests/HTMLPurifier/URIFilterHarness.php index 4c8ad42e5..e86ba3b91 100644 --- a/tests/HTMLPurifier/URIFilterHarness.php +++ b/tests/HTMLPurifier/URIFilterHarness.php @@ -3,6 +3,11 @@ class HTMLPurifier_URIFilterHarness extends HTMLPurifier_URIHarness { + /** + * @type HTMLPurifier_URIFilter + */ + public $filter; + protected function assertFiltering($uri, $expect_uri = true) { $this->prepareURI($uri, $expect_uri); From 3fc193c7553ca9eb3431a48708c17ad081cc1e64 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 27 Jun 2022 22:20:36 +0100 Subject: [PATCH 23/48] Fix #322 - PHP 8.1 deprecation notice in HostBlacklist URIFilter (#323) --- library/HTMLPurifier/URIFilter/HostBlacklist.php | 2 +- tests/HTMLPurifier/URIFilter/HostBlacklistTest.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/library/HTMLPurifier/URIFilter/HostBlacklist.php b/library/HTMLPurifier/URIFilter/HostBlacklist.php index a6645c17e..32197c0e6 100644 --- a/library/HTMLPurifier/URIFilter/HostBlacklist.php +++ b/library/HTMLPurifier/URIFilter/HostBlacklist.php @@ -35,7 +35,7 @@ public function prepare($config) public function filter(&$uri, $config, $context) { foreach ($this->blacklist as $blacklisted_host_fragment) { - if (strpos($uri->host, $blacklisted_host_fragment) !== false) { + if ($uri->host !== null && strpos($uri->host, $blacklisted_host_fragment) !== false) { return false; } } diff --git a/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php b/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php index ffbff0c5d..62a1cefd5 100644 --- a/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php +++ b/tests/HTMLPurifier/URIFilter/HostBlacklistTest.php @@ -28,6 +28,12 @@ public function testPreserveNonBlacklistedHost() $this->assertFiltering('http://google.com'); } + public function testFragment() + { + $this->config->set('URI.HostBlacklist', 'example.com'); + $this->assertFiltering('#foo'); + } + } // vim: et sw=4 sts=4 From dff4746e133777583fbf43d2b95372e8d818df1f Mon Sep 17 00:00:00 2001 From: John Flatness Date: Mon, 15 Aug 2022 22:59:31 -0400 Subject: [PATCH 24/48] Replace 8.1-deprecated utf8_ funcs with mbstring (#326) --- library/HTMLPurifier/Encoder.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/HTMLPurifier/Encoder.php b/library/HTMLPurifier/Encoder.php index 40a24266a..d4791cc1b 100644 --- a/library/HTMLPurifier/Encoder.php +++ b/library/HTMLPurifier/Encoder.php @@ -398,8 +398,8 @@ public static function convertToUTF8($str, $config, $context) // characters to their true byte-wise ASCII/UTF-8 equivalents. $str = strtr($str, self::testEncodingSupportsASCII($encoding)); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_encode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); return $str; } $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); @@ -450,8 +450,8 @@ public static function convertFromUTF8($str, $config, $context) // Normal stuff $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); return $str; - } elseif ($encoding === 'iso-8859-1') { - $str = utf8_decode($str); + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8'); return $str; } trigger_error('Encoding not supported', E_USER_ERROR); From be2a668e81aa4dcb3b8a8b0d16fa0395e278131a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 30 Aug 2022 15:46:59 +0200 Subject: [PATCH 25/48] Treat PHP version numbers as strings in GitHub Actions (#327) YAML will try to interpret numeric values as numbers, leading to `8.0` being interpreted as `8` instead of `'8.0'`. This doesn't result in a functional change, but cleans up the output of the jobs a little (e.g. in the title line). --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebb9e1a32..5cb6ffd2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: [5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1] + php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] name: PHP ${{ matrix.php }} From 6ec13635cee5a6828d94a68160cae9836e90c69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 30 Aug 2022 15:50:18 +0200 Subject: [PATCH 26/48] Update to `actions/checkout@v3` (#328) This does not introduce any functional difference and is intended as a future-proofing change. see https://github.com/actions/checkout/releases/tag/v3.0.0 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cb6ffd2d..9efca65d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 From c60bba1fe44c7715e7b4e89fede3eb9427f8cd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 3 Sep 2022 03:35:32 +0200 Subject: [PATCH 27/48] Fix test selection logic in tests/test_files.php (#329) Selecting the `fstools` tests also executed the `htmlt` tests. --- tests/test_files.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_files.php b/tests/test_files.php index d2b86cdb4..b1e158f01 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -29,6 +29,7 @@ if ($break) break; case 'fstools': $test_dirs[] = 'FSTools'; + if ($break) break; case 'htmlt': $htmlt_dirs[] = 'HTMLPurifier/HTMLT'; if ($break) break; From 1b80051115bba8f3c046c1bd00af9077071d3faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 3 Sep 2022 03:38:58 +0200 Subject: [PATCH 28/48] Fix some more PHP 8.2 deprecations (#330) * Define HTMLPurifier_AttrTransform_SafeParam::$wmode This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$cache This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$mock This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$def This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_EntityParserTest::$_entity_lookup This fixes a PHP 8.2 deprecation. --- library/HTMLPurifier/AttrTransform/SafeParam.php | 5 +++++ tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php | 6 ++++++ tests/HTMLPurifier/EntityParserTest.php | 2 ++ 3 files changed, 13 insertions(+) diff --git a/library/HTMLPurifier/AttrTransform/SafeParam.php b/library/HTMLPurifier/AttrTransform/SafeParam.php index 1143b4b49..1033106b3 100644 --- a/library/HTMLPurifier/AttrTransform/SafeParam.php +++ b/library/HTMLPurifier/AttrTransform/SafeParam.php @@ -24,6 +24,11 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform */ private $uri; + /** + * @type HTMLPurifier_AttrDef_Enum + */ + public $wmode; + public function __construct() { $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded diff --git a/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php b/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php index 43db45afb..5e01bb995 100644 --- a/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php +++ b/tests/HTMLPurifier/DefinitionCache/DecoratorHarness.php @@ -5,6 +5,12 @@ class HTMLPurifier_DefinitionCache_DecoratorHarness extends HTMLPurifier_DefinitionCacheHarness { + public $cache; + + public $mock; + + public $def; + public function setup() { $this->mock = new HTMLPurifier_DefinitionCacheMock(); diff --git a/tests/HTMLPurifier/EntityParserTest.php b/tests/HTMLPurifier/EntityParserTest.php index 989676c14..1af570c9c 100644 --- a/tests/HTMLPurifier/EntityParserTest.php +++ b/tests/HTMLPurifier/EntityParserTest.php @@ -5,6 +5,8 @@ class HTMLPurifier_EntityParserTest extends HTMLPurifier_Harness protected $EntityParser; + protected $_entity_lookup; + public function setUp() { $this->EntityParser = new HTMLPurifier_EntityParser(); From 1c2bae18e313b549a7413bfad97a80cafe300ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 3 Sep 2022 03:43:29 +0200 Subject: [PATCH 29/48] Increase minimum requirement to PHP 5.6 (#331) --- .github/workflows/ci.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9efca65d1..e9c574da9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] name: PHP ${{ matrix.php }} diff --git a/composer.json b/composer.json index 7e1e68086..3c4d3ba69 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ } ], "require": { - "php": ">=5.2" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, From dbbd3e59f914db1477957f7f924aba920cf9bf56 Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 6 Sep 2022 18:04:45 +0100 Subject: [PATCH 30/48] Add contenteditable attribute definition (#332) * Add contenteditable attribute definition * gate behind html.trusted * use enum --- .../AttrDef/HTML/ContentEditable.php | 16 +++++++++++ library/HTMLPurifier/AttrTypes.php | 1 + .../AttrDef/HTML/ContentEditableTest.php | 27 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 library/HTMLPurifier/AttrDef/HTML/ContentEditable.php create mode 100644 tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php diff --git a/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php b/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php new file mode 100644 index 000000000..5b03d3e37 --- /dev/null +++ b/library/HTMLPurifier/AttrDef/HTML/ContentEditable.php @@ -0,0 +1,16 @@ +get('HTML.Trusted')) { + $allowed = array('', 'true', 'false'); + } + + $enum = new HTMLPurifier_AttrDef_Enum($allowed); + + return $enum->validate($string, $config, $context); + } +} diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 3b70520b6..e4429e86d 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -41,6 +41,7 @@ public function __construct() $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); + $this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable(); // unimplemented aliases $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); diff --git a/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php b/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php new file mode 100644 index 000000000..3aa6ec1e5 --- /dev/null +++ b/tests/HTMLPurifier/AttrDef/HTML/ContentEditableTest.php @@ -0,0 +1,27 @@ +def = new HTMLPurifier_AttrDef_HTML_ContentEditable(); + } + + public function test() + { + $this->assertDef('', false); + $this->assertDef('true', false); + $this->assertDef('caret', false); + $this->assertDef('false'); + } + + public function testTrustedHtml() + { + $this->config->set('HTML.Trusted', true); + $this->assertDef(''); + $this->assertDef('true'); + $this->assertDef('false'); + $this->assertDef('caret', false); + } +} From 36e06603a838c22b6bce12bcd1b0a39c0f261dfe Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 6 Sep 2022 18:05:15 +0100 Subject: [PATCH 31/48] Fix creation of dynamic property (#333) --- tests/HTMLPurifier/DefinitionTestable.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/HTMLPurifier/DefinitionTestable.php b/tests/HTMLPurifier/DefinitionTestable.php index 312c57bb4..77020c616 100644 --- a/tests/HTMLPurifier/DefinitionTestable.php +++ b/tests/HTMLPurifier/DefinitionTestable.php @@ -1,7 +1,14 @@ Date: Sat, 10 Sep 2022 19:03:42 +0100 Subject: [PATCH 32/48] Fix creation of dynamic property (#337) --- .../Strategy/MakeWellFormed/EndRewindInjector.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php b/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php index 0e5a8e200..f40987619 100644 --- a/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php +++ b/tests/HTMLPurifier/Strategy/MakeWellFormed/EndRewindInjector.php @@ -4,10 +4,13 @@ class HTMLPurifier_Strategy_MakeWellFormed_EndRewindInjector extends HTMLPurifie { public $name = 'EndRewindInjector'; public $needed = array('span'); + private $deleteElement = false; + public function handleElement(&$token) { - if (isset($token->_InjectorTest_EndRewindInjector_delete)) { + if ($this->deleteElement) { $token = false; + $this->deleteElement = false; } } public function handleText(&$token) @@ -23,7 +26,7 @@ public function handleEnd(&$token) $prev->name == 'span' ) { $token = false; - $prev->_InjectorTest_EndRewindInjector_delete = true; + $this->deleteElement = true; $this->rewindOffset(1); } } From dc27c788712e9c8cbcc016d7378884fcbb6e6a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 12 Sep 2022 01:51:02 +0200 Subject: [PATCH 33/48] Add PHP 8.2 to CI (#335) * Add PHP 8.2 to CI see ezyang/htmlpurifier#334 * Add PHP 8.2 to composer.json --- .github/workflows/ci.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9c574da9..b51d7a95a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: true matrix: - php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] name: PHP ${{ matrix.php }} diff --git a/composer.json b/composer.json index 3c4d3ba69..afce4f8c7 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ } ], "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, From f1d6da13bc8510174055dbffc8497ddef4859989 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 12 Sep 2022 15:53:24 +0100 Subject: [PATCH 34/48] Fix contenteditable attribute definition (#336) --- library/HTMLPurifier/HTMLModule/CommonAttributes.php | 1 + tests/HTMLPurifier/Strategy/ValidateAttributesTest.php | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/library/HTMLPurifier/HTMLModule/CommonAttributes.php b/library/HTMLPurifier/HTMLModule/CommonAttributes.php index a96ab1bef..7220c14cc 100644 --- a/library/HTMLPurifier/HTMLModule/CommonAttributes.php +++ b/library/HTMLPurifier/HTMLModule/CommonAttributes.php @@ -17,6 +17,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule 'class' => 'Class', 'id' => 'ID', 'title' => 'CDATA', + 'contenteditable' => 'ContentEditable', ), 'Lang' => array(), 'I18N' => array( diff --git a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php index a2125522e..f8ebc4c72 100644 --- a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php +++ b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php @@ -258,6 +258,13 @@ public function testRemovePercentCSSWidthAndHeightOnImg() ); } + public function testContentEditableAttribute() + { + $this->assertResult( + '
', + '
' + ); + } } // vim: et sw=4 sts=4 From 25824056ee3d4225af8bc6cd349a43108141a469 Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 15 Sep 2022 04:55:41 +0100 Subject: [PATCH 35/48] Run CSSTidy tests on CI (#338) * Run CSSTidy tests on CI * update dirname * use compopser instead of git clone * use composer * use test-settings.sample.php * enable ext-intl * disable Net_IDNA2 --- .github/workflows/ci.yml | 9 ++-- composer.json | 15 ++++++- smoketests/common.php | 2 + smoketests/extractStyleBlocks.php | 17 -------- test-settings.sample.php | 19 +------- test-settings.travis.php | 72 ------------------------------- tests/common.php | 18 +------- tests/test_files.php | 4 +- 8 files changed, 26 insertions(+), 130 deletions(-) delete mode 100644 test-settings.travis.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b51d7a95a..f0048048d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,12 +22,15 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} + tools: composer:v2 + ini-values: error_reporting=E_ALL + extensions: iconv, bcmath, tidy, mbstring, intl - - name: Clone simpletest - run: git clone --depth=50 https://github.com/ezyang/simpletest.git + - name: Install dependencies + run: composer install - name: Configure simpletest - run: cp test-settings.travis.php test-settings.php + run: cp test-settings.sample.php test-settings.php - name: Execute Unit tests run: php tests/index.php diff --git a/composer.json b/composer.json index afce4f8c7..d75582950 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,10 @@ "require": { "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, "autoload": { "psr-0": { "HTMLPurifier": "library/" }, "files": ["library/HTMLPurifier.composer.php"], @@ -27,5 +31,14 @@ "ext-iconv": "Converts text to and from non-UTF-8 encodings", "ext-bcmath": "Used for unit conversion and imagecrash protection", "ext-tidy": "Used for pretty-printing HTML" - } + }, + "config": { + "sort-packages": true + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/ezyang/simpletest.git" + } + ] } diff --git a/smoketests/common.php b/smoketests/common.php index b2c2b4bb4..eb99ad5ec 100644 --- a/smoketests/common.php +++ b/smoketests/common.php @@ -2,6 +2,8 @@ header('Content-type: text/html; charset=UTF-8'); +require_once __DIR__.'/../vendor/autoload.php'; + if (!isset($_GET['standalone'])) { require_once '../library/HTMLPurifier.auto.php'; } else { diff --git a/smoketests/extractStyleBlocks.php b/smoketests/extractStyleBlocks.php index bb330b5f2..0dff98378 100644 --- a/smoketests/extractStyleBlocks.php +++ b/smoketests/extractStyleBlocks.php @@ -3,23 +3,6 @@ require_once 'common.php'; require_once 'HTMLPurifier/Filter/ExtractStyleBlocks.php'; -// need CSSTidy location -$csstidy_location = false; -if (file_exists('../conf/test-settings.php')) include '../conf/test-settings.php'; -if (file_exists('../test-settings.php')) include '../test-settings.php'; - -if (!$csstidy_location) { -?> -Error: CSSTidy library not -found, please install and configure test-settings.php -accordingly. - true, )); diff --git a/test-settings.sample.php b/test-settings.sample.php index 480b66279..5acc78422 100644 --- a/test-settings.sample.php +++ b/test-settings.sample.php @@ -17,20 +17,6 @@ exit; } -// ----------------------------------------------------------------------------- -// REQUIRED SETTINGS - -// Note on running SimpleTest: -// You want the Git copy of SimpleTest, found here: -// https://github.com/simpletest/simpletest/ -// -// If SimpleTest is borked with HTML Purifier, please contact me or -// the SimpleTest devs; I am a developer for SimpleTest so I should be -// able to quickly assess a fix. SimpleTest's problem is my problem! - -// Where is SimpleTest located? Remember to include a trailing slash! -$simpletest_location = '/path/to/simpletest/'; - // ----------------------------------------------------------------------------- // OPTIONAL SETTINGS @@ -50,9 +36,6 @@ // If PHPT isn't in your Path via PEAR, set that here: // set_include_path('/path/to/phpt/Core/src' . PATH_SEPARATOR . get_include_path()); -// Where is CSSTidy located? (Include trailing slash. Leave false to disable.) -$csstidy_location = false; - // For tests/multitest.php, which versions to test? $versions_to_test = array(); @@ -69,6 +52,6 @@ // If PEAR is enabled, what PEAR tests should be run? (Note: you will // need to ensure these libraries are installed) -$GLOBALS['HTMLPurifierTest']['Net_IDNA2'] = true; +$GLOBALS['HTMLPurifierTest']['Net_IDNA2'] = false; // vim: et sw=4 sts=4 diff --git a/test-settings.travis.php b/test-settings.travis.php deleted file mode 100644 index b1edce4aa..000000000 --- a/test-settings.travis.php +++ /dev/null @@ -1,72 +0,0 @@ -=')) { From 8d9f4c9ec154922ff19690ffade9ed915b27a017 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 18 Sep 2022 02:23:57 -0400 Subject: [PATCH 36/48] Release 4.15.0 Signed-off-by: Edward Z. Yang --- Doxyfile | 2 +- NEWS | 9 +++++++ VERSION | 2 +- WHATSNEW | 7 +++--- configdoc/usage.xml | 33 ++++++++++++++------------ library/HTMLPurifier.includes.php | 3 ++- library/HTMLPurifier.php | 6 ++--- library/HTMLPurifier.safe-includes.php | 1 + library/HTMLPurifier/Config.php | 2 +- 9 files changed, 39 insertions(+), 26 deletions(-) diff --git a/Doxyfile b/Doxyfile index 7d01f31d7..51d1fee4f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 4.14.0 +PROJECT_NUMBER = 4.15.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/NEWS b/NEWS index 92c87218f..a1c98844c 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,15 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== +4.15.0, released 2022-09-18 +! PHP 8.1 and 8.2 support, esp. fixes for deprecation warnings. A joint effort + by David Rans, Tim Düsterhus, Kieran and John Flatness. +! Allow contenteditable="false" (#336), contributed by Kieran. +- Replace PHP 8.1 deprecated utf8_ functions with mbstring (#326), + contributed by John Flatness. +- Enhanced composer suggestions with extensions (#317), contributed by + func0der. + 4.14.0, released 2021-12-24 ! Add "background-size" support (#289), contributed by Václav Smítal ! Transform deprecated width attribute when tidying HTML, contributed by diff --git a/VERSION b/VERSION index 09ce0ce71..f029ee574 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.14.0 \ No newline at end of file +4.15.0 \ No newline at end of file diff --git a/WHATSNEW b/WHATSNEW index 4d5e9291f..32403eb22 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -1,4 +1,3 @@ -HTML Purifier 4.14.x is a maintenance release which improves -PHP7 and PHP8 compatibility. There are also some minor new features -(background-size) and some miscellaneous fixes to remove notices -from recent versions of PHP. +HTML Purifier 4.15.x is a maintenance release which improves +compatibility with PHP8.2. There is also support for +contenteditable="false" added. diff --git a/configdoc/usage.xml b/configdoc/usage.xml index c0df5aba4..9767c7af6 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -5,8 +5,8 @@ 162 - 85 - 326 + 90 + 331 67 @@ -124,7 +124,7 @@ 122 - 308 + 313
@@ -172,8 +172,11 @@ 234 - 313 - 353 + 318 + 358 + + + 8 37 @@ -250,12 +253,12 @@ - 80 + 85 - 84 + 89 62 @@ -263,23 +266,23 @@ - 215 - 337 + 220 + 342 - 324 + 329 - 347 + 352 - 351 + 356 36 @@ -287,12 +290,12 @@ - 352 + 357 - 353 + 358 35 @@ -451,7 +454,7 @@ - 53 + 58 diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index ee81cac68..47ee0133d 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.14.0 + * @version 4.15.0 * * @warning * You must *not* include any other HTML Purifier files before this file, @@ -107,6 +107,7 @@ require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require 'HTMLPurifier/AttrDef/HTML/Class.php'; require 'HTMLPurifier/AttrDef/HTML/Color.php'; +require 'HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require 'HTMLPurifier/AttrDef/HTML/ID.php'; require 'HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index 2177fc851..26f061276 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.14.0 - Standards Compliant HTML Filtering + HTML Purifier 4.15.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.14.0'; + public $version = '4.15.0'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.14.0'; + const VERSION = '4.15.0'; /** * Global configuration object. diff --git a/library/HTMLPurifier.safe-includes.php b/library/HTMLPurifier.safe-includes.php index a3261f8a3..94543f593 100644 --- a/library/HTMLPurifier.safe-includes.php +++ b/library/HTMLPurifier.safe-includes.php @@ -101,6 +101,7 @@ require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php'; +require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ContentEditable.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php'; diff --git a/library/HTMLPurifier/Config.php b/library/HTMLPurifier/Config.php index 16a6b322b..797d26877 100644 --- a/library/HTMLPurifier/Config.php +++ b/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.14.0'; + public $version = '4.15.0'; /** * Whether or not to automatically finalize From db312435cb9d8d73395f75f9642a43ba6de5e903 Mon Sep 17 00:00:00 2001 From: Kieran Date: Sun, 18 Sep 2022 07:44:00 +0100 Subject: [PATCH 37/48] feat: add semantic release (#307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add semantic release * fix typo * split from matrix * remove only on push * remove npm plugin * write changelog to NEWS * list assets to include in git commit * fix update-for-release * lint pr title * split release into separate workflow that runs manually * revert ci.yml changes * remove references to WHATSNEW * Fix #322 - PHP 8.1 deprecation notice in HostBlacklist URIFilter (#323) * Replace 8.1-deprecated utf8_ funcs with mbstring (#326) * Treat PHP version numbers as strings in GitHub Actions (#327) YAML will try to interpret numeric values as numbers, leading to `8.0` being interpreted as `8` instead of `'8.0'`. This doesn't result in a functional change, but cleans up the output of the jobs a little (e.g. in the title line). * Update to `actions/checkout@v3` (#328) This does not introduce any functional difference and is intended as a future-proofing change. see https://github.com/actions/checkout/releases/tag/v3.0.0 * Fix test selection logic in tests/test_files.php (#329) Selecting the `fstools` tests also executed the `htmlt` tests. * Fix some more PHP 8.2 deprecations (#330) * Define HTMLPurifier_AttrTransform_SafeParam::$wmode This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$cache This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$mock This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_DefinitionCache_DecoratorHarness::$def This fixes a PHP 8.2 deprecation. * Define HTMLPurifier_EntityParserTest::$_entity_lookup This fixes a PHP 8.2 deprecation. * Increase minimum requirement to PHP 5.6 (#331) * Add contenteditable attribute definition (#332) * Add contenteditable attribute definition * gate behind html.trusted * use enum * Fix creation of dynamic property (#333) * Fix creation of dynamic property (#337) * Add PHP 8.2 to CI (#335) * Add PHP 8.2 to CI see ezyang/htmlpurifier#334 * Add PHP 8.2 to composer.json * Fix contenteditable attribute definition (#336) * Run CSSTidy tests on CI (#338) * Run CSSTidy tests on CI * update dirname * use compopser instead of git clone * use composer * use test-settings.sample.php * enable ext-intl * disable Net_IDNA2 * Release 4.15.0 Signed-off-by: Edward Z. Yang Signed-off-by: Edward Z. Yang Co-authored-by: John Flatness Co-authored-by: Tim Düsterhus Co-authored-by: Tim Düsterhus Co-authored-by: Edward Z. Yang --- .gitattributes | 2 +- .github/workflows/lint-pr.yml | 19 +++++++++++++++++++ .github/workflows/release.yml | 29 +++++++++++++++++++++++++++++ WHATSNEW | 3 --- maintenance/add-vimline.php | 1 - package.php | 1 - release.config.js | 29 +++++++++++++++++++++++++++++ update-for-release | 34 +++++++++++++++------------------- 8 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/lint-pr.yml create mode 100644 .github/workflows/release.yml delete mode 100644 WHATSNEW create mode 100644 release.config.js diff --git a/.gitattributes b/.gitattributes index 7542171d4..6b39d9fee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -19,5 +19,5 @@ /tests export-ignore /TODO export-ignore /update-for-release export-ignore -/WHATSNEW export-ignore /WYSIWYG export-ignore +/release.config.js export-ignore diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml new file mode 100644 index 000000000..597a6ed7d --- /dev/null +++ b/.github/workflows/lint-pr.yml @@ -0,0 +1,19 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + + runs-on: ubuntu-latest + + steps: + - uses: amannn/action-semantic-pull-request@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..eb2308a62 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: release + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + + name: Release + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 5.5 + + - name: Run automated release process with semantic-release + uses: cycjimmy/semantic-release-action@v2 + with: + extra_plugins: | + @semantic-release/changelog + @semantic-release/git + @semantic-release/exec + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/WHATSNEW b/WHATSNEW deleted file mode 100644 index 32403eb22..000000000 --- a/WHATSNEW +++ /dev/null @@ -1,3 +0,0 @@ -HTML Purifier 4.15.x is a maintenance release which improves -compatibility with PHP8.2. There is also support for -contenteditable="false" added. diff --git a/maintenance/add-vimline.php b/maintenance/add-vimline.php index d6a8eb202..69882c67e 100644 --- a/maintenance/add-vimline.php +++ b/maintenance/add-vimline.php @@ -34,7 +34,6 @@ postfix_is('.svg', $file) || postfix_is('.phpt', $file) || postfix_is('VERSION', $file) || - postfix_is('WHATSNEW', $file) || postfix_is('configdoc/usage.xml', $file) || postfix_is('library/HTMLPurifier.includes.php', $file) || postfix_is('library/HTMLPurifier.safe-includes.php', $file) || diff --git a/package.php b/package.php index bfef93622..a4fd2df9c 100644 --- a/package.php +++ b/package.php @@ -48,7 +48,6 @@ $pkg->addRelease(); -$pkg->setNotes(file_get_contents('WHATSNEW')); $pkg->setPackageType('php'); $pkg->setPhpDep('5.0.0'); diff --git a/release.config.js b/release.config.js new file mode 100644 index 000000000..3f73ace87 --- /dev/null +++ b/release.config.js @@ -0,0 +1,29 @@ +module.exports = { + debug: true, + branch: 'master', + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + ['@semantic-release/changelog', {'changelogFile': 'NEWS'}], + '@semantic-release/exec', + ['@semantic-release/git', { + 'assets': ['VERSION', 'NEWS', 'Doxyfile', 'library/HTMLPurifier.php', 'library/HTMLPurifier/Config.php', 'library/HTMLPurifier.includes.php'], + }], + '@semantic-release/github' + ], + verifyConditions: [ + '@semantic-release/changelog', + '@semantic-release/github', + ], + prepare: [ + { + path: '@semantic-release/exec', + cmd: 'php update-for-release ${nextRelease.version}' + }, + '@semantic-release/changelog', + '@semantic-release/git', + ], + publish: [ + '@semantic-release/github', + ] +} diff --git a/update-for-release b/update-for-release index 2b9662a76..ec5ec03dd 100644 --- a/update-for-release +++ b/update-for-release @@ -23,24 +23,7 @@ $version = trim($argv[1]); // ...in VERSION file_put_contents('VERSION', $version); -// ...in NEWS -if ($is_dev = (strpos($version, 'dev') === false)) { - $date = date('Y-m-d'); - $news_c = str_replace( - $l = "$version, unknown release date", - "$version, released $date", - file_get_contents('NEWS'), - $c - ); - if (!$c) { - echo 'Could not update NEWS, missing ' . $l . PHP_EOL; - exit; - } elseif ($c > 1) { - echo 'More than one release declaration in NEWS replaced' . PHP_EOL; - exit; - } - file_put_contents('NEWS', $news_c); -} +$is_dev = strpos($version, 'dev') === false; // ...in Doxyfile $doxyfile_c = preg_replace( @@ -102,9 +85,22 @@ if (!$c) { } file_put_contents('library/HTMLPurifier/Config.php', $config_c); +$includes = file_get_contents('library/HTMLPurifier.includes.php'); +$includes = preg_replace( + '/@version .+?/', + "@version $version", + $includes, + 1, $c +); +if (!$c) { + echo 'Could not update HTMLPurifier.includes.php, missing @version docblock.' . PHP_EOL; + exit; +} +file_put_contents('HTMLPurifier.includes.php', $includes); + passthru('maintenance/flush.sh'); -if ($is_dev) echo "Review changes, write something in WHATSNEW, and then commit with log 'Release $version.'" . PHP_EOL; +if ($is_dev) echo "Review changes, and then commit with log 'Release $version.'" . PHP_EOL; else echo "Numbers updated to dev, no other modifications necessary!"; // vim: et sw=4 sts=4 From 523407fb06eb9e5f3d59889b3978d5bfe94299c8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 18 Sep 2022 07:06:19 +0000 Subject: [PATCH 38/48] chore(release): 4.16.0 [skip ci] # [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) ### Features * add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..55cb9029c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) + + +### Features + +* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) From d82f3d996a0d9b0f23364946d9a14408c1ad72c5 Mon Sep 17 00:00:00 2001 From: Kieran Date: Sun, 18 Sep 2022 20:15:38 +0100 Subject: [PATCH 39/48] fix: semantic release (#339) * fix: semantic release * update git assets --- CHANGELOG.md | 6 ------ release.config.js | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 26 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 55cb9029c..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) - - -### Features - -* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) diff --git a/release.config.js b/release.config.js index 3f73ace87..93210a1ad 100644 --- a/release.config.js +++ b/release.config.js @@ -4,26 +4,30 @@ module.exports = { plugins: [ '@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', - ['@semantic-release/changelog', {'changelogFile': 'NEWS'}], - '@semantic-release/exec', - ['@semantic-release/git', { - 'assets': ['VERSION', 'NEWS', 'Doxyfile', 'library/HTMLPurifier.php', 'library/HTMLPurifier/Config.php', 'library/HTMLPurifier.includes.php'], - }], + [ + '@semantic-release/changelog', + { + 'changelogFile': 'NEWS' + } + ], + [ + '@semantic-release/exec', + { + 'prepareCmd': 'php update-for-release ${nextRelease.version}' + } + ], + [ + '@semantic-release/git', + { + 'assets': [ + 'VERSION', + 'NEWS', + 'Doxyfile', + 'library/**/*', + 'configdoc/**/*', + ], + } + ], '@semantic-release/github' ], - verifyConditions: [ - '@semantic-release/changelog', - '@semantic-release/github', - ], - prepare: [ - { - path: '@semantic-release/exec', - cmd: 'php update-for-release ${nextRelease.version}' - }, - '@semantic-release/changelog', - '@semantic-release/git', - ], - publish: [ - '@semantic-release/github', - ] } From 3e832152a6173f880c6495a3ab2b0e5235e253a6 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 18 Sep 2022 15:21:20 -0400 Subject: [PATCH 40/48] Revert "fix: semantic release (#339)" (#340) This reverts commit d82f3d996a0d9b0f23364946d9a14408c1ad72c5. --- CHANGELOG.md | 6 ++++++ release.config.js | 44 ++++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..55cb9029c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6 @@ +# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) + + +### Features + +* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) diff --git a/release.config.js b/release.config.js index 93210a1ad..3f73ace87 100644 --- a/release.config.js +++ b/release.config.js @@ -4,30 +4,26 @@ module.exports = { plugins: [ '@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', - [ - '@semantic-release/changelog', - { - 'changelogFile': 'NEWS' - } - ], - [ - '@semantic-release/exec', - { - 'prepareCmd': 'php update-for-release ${nextRelease.version}' - } - ], - [ - '@semantic-release/git', - { - 'assets': [ - 'VERSION', - 'NEWS', - 'Doxyfile', - 'library/**/*', - 'configdoc/**/*', - ], - } - ], + ['@semantic-release/changelog', {'changelogFile': 'NEWS'}], + '@semantic-release/exec', + ['@semantic-release/git', { + 'assets': ['VERSION', 'NEWS', 'Doxyfile', 'library/HTMLPurifier.php', 'library/HTMLPurifier/Config.php', 'library/HTMLPurifier.includes.php'], + }], '@semantic-release/github' ], + verifyConditions: [ + '@semantic-release/changelog', + '@semantic-release/github', + ], + prepare: [ + { + path: '@semantic-release/exec', + cmd: 'php update-for-release ${nextRelease.version}' + }, + '@semantic-release/changelog', + '@semantic-release/git', + ], + publish: [ + '@semantic-release/github', + ] } From e55fead09f39430d30f48438f06e7bc2326efc94 Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 20 Sep 2022 17:45:11 +0100 Subject: [PATCH 41/48] fix: semantic release (#341) Same as #339 but stops library/standalone and library/HTMLPurifier.standalone.phpfrom being commit --- CHANGELOG.md | 6 ------ release.config.js | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 26 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 55cb9029c..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18) - - -### Features - -* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338) diff --git a/release.config.js b/release.config.js index 3f73ace87..dcf13c6bc 100644 --- a/release.config.js +++ b/release.config.js @@ -4,26 +4,30 @@ module.exports = { plugins: [ '@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', - ['@semantic-release/changelog', {'changelogFile': 'NEWS'}], - '@semantic-release/exec', - ['@semantic-release/git', { - 'assets': ['VERSION', 'NEWS', 'Doxyfile', 'library/HTMLPurifier.php', 'library/HTMLPurifier/Config.php', 'library/HTMLPurifier.includes.php'], - }], + [ + '@semantic-release/changelog', + { + 'changelogFile': 'NEWS' + } + ], + [ + '@semantic-release/exec', + { + 'prepareCmd': 'php update-for-release ${nextRelease.version}' + } + ], + [ + '@semantic-release/git', + { + 'assets': [ + 'VERSION', + 'NEWS', + 'Doxyfile', + ['library/**/*', '!library/standalone/**/*', '!library/HTMLPurifier.standalone.php'], + 'configdoc/**/*', + ], + } + ], '@semantic-release/github' ], - verifyConditions: [ - '@semantic-release/changelog', - '@semantic-release/github', - ], - prepare: [ - { - path: '@semantic-release/exec', - cmd: 'php update-for-release ${nextRelease.version}' - }, - '@semantic-release/changelog', - '@semantic-release/git', - ], - publish: [ - '@semantic-release/github', - ] } From d567de85e688f6dcb670f933cdb197470c0602c2 Mon Sep 17 00:00:00 2001 From: Michael Kliewe Date: Sat, 19 Nov 2022 05:42:06 +0100 Subject: [PATCH 42/48] Fixed undefined property (#346) --- library/HTMLPurifier/Printer/ConfigForm.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/HTMLPurifier/Printer/ConfigForm.php b/library/HTMLPurifier/Printer/ConfigForm.php index 33ae11397..4c3ce1758 100644 --- a/library/HTMLPurifier/Printer/ConfigForm.php +++ b/library/HTMLPurifier/Printer/ConfigForm.php @@ -32,6 +32,11 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer */ protected $compress = false; + /** + * @var HTMLPurifier_Config + */ + protected $genConfig; + /** * @param string $name Form element name for directives to be stuffed into * @param string $doc_url String documentation URL, will have fragment tagged on From 2d1314820e47f95d7c1be542d2c12eec4b2b724e Mon Sep 17 00:00:00 2001 From: Michael Kliewe Date: Sat, 19 Nov 2022 05:56:21 +0100 Subject: [PATCH 43/48] Added class_exists('Net_IDNA2') around optional external class (#351) --- library/HTMLPurifier/AttrDef/URI/Host.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/HTMLPurifier/AttrDef/URI/Host.php b/library/HTMLPurifier/AttrDef/URI/Host.php index 1beeaa5d2..ddc5dfbea 100644 --- a/library/HTMLPurifier/AttrDef/URI/Host.php +++ b/library/HTMLPurifier/AttrDef/URI/Host.php @@ -106,7 +106,7 @@ public function validate($string, $config, $context) // If we have Net_IDNA2 support, we can support IRIs by // punycoding them. (This is the most portable thing to do, // since otherwise we have to assume browsers support - } elseif ($config->get('Core.EnableIDNA')) { + } elseif ($config->get('Core.EnableIDNA') && class_exists('Net_IDNA2')) { $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); // we need to encode each period separately $parts = explode('.', $string); From 909dda6621cf06eb5ac1ea80955306c818d7122f Mon Sep 17 00:00:00 2001 From: Michael Kliewe Date: Sat, 19 Nov 2022 06:03:18 +0100 Subject: [PATCH 44/48] Fixed wrong return PHPDoc (#348) --- library/HTMLPurifier/Lexer/DOMLex.php | 1 - 1 file changed, 1 deletion(-) diff --git a/library/HTMLPurifier/Lexer/DOMLex.php b/library/HTMLPurifier/Lexer/DOMLex.php index ca5f25b84..5e8104be9 100644 --- a/library/HTMLPurifier/Lexer/DOMLex.php +++ b/library/HTMLPurifier/Lexer/DOMLex.php @@ -104,7 +104,6 @@ public function tokenizeHTML($html, $config, $context) * To iterate is human, to recurse divine - L. Peter Deutsch * @param DOMNode $node DOMNode to be tokenized. * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. - * @return HTMLPurifier_Token of node appended to previously passed tokens. */ protected function tokenizeDOM($node, &$tokens, $config) { From becc9d40cf3c9e37bf70065730c67d1519b4d7e8 Mon Sep 17 00:00:00 2001 From: Michael Kliewe Date: Sat, 19 Nov 2022 23:26:34 +0100 Subject: [PATCH 45/48] Fixed missing return value (#349) --- library/HTMLPurifier/HTMLModule/Tidy.php | 1 + 1 file changed, 1 insertion(+) diff --git a/library/HTMLPurifier/HTMLModule/Tidy.php b/library/HTMLPurifier/HTMLModule/Tidy.php index 12173ba70..76fd93a6c 100644 --- a/library/HTMLPurifier/HTMLModule/Tidy.php +++ b/library/HTMLPurifier/HTMLModule/Tidy.php @@ -221,6 +221,7 @@ public function getFixType($name) */ public function makeFixes() { + return array(); } } From 1424f17cf37a41a227e7c58a7b9a67d1878501b0 Mon Sep 17 00:00:00 2001 From: Michael S <9484406+codebymikey@users.noreply.github.com> Date: Thu, 24 Nov 2022 21:31:20 +0000 Subject: [PATCH 46/48] Add support for encoded tel URI schemes. (#354) --- library/HTMLPurifier/URIScheme/tel.php | 2 +- tests/HTMLPurifier/AttrDef/URITest.php | 2 ++ tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php | 2 ++ tests/HTMLPurifier/URIParserTest.php | 4 ++++ tests/HTMLPurifier/URISchemeTest.php | 7 +++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/library/HTMLPurifier/URIScheme/tel.php b/library/HTMLPurifier/URIScheme/tel.php index 8cd193352..1ea122269 100644 --- a/library/HTMLPurifier/URIScheme/tel.php +++ b/library/HTMLPurifier/URIScheme/tel.php @@ -37,7 +37,7 @@ public function doValidate(&$uri, $config, $context) // from phone number, EXCEPT for a leading plus sign. $uri->path = preg_replace('/(?!^\+)[^\dx]/', '', // Normalize e(x)tension to lower-case - str_replace('X', 'x', $uri->path)); + str_replace('X', 'x', rawurldecode($uri->path))); return true; } diff --git a/tests/HTMLPurifier/AttrDef/URITest.php b/tests/HTMLPurifier/AttrDef/URITest.php index f40021732..1309f3c20 100644 --- a/tests/HTMLPurifier/AttrDef/URITest.php +++ b/tests/HTMLPurifier/AttrDef/URITest.php @@ -23,6 +23,8 @@ public function testIntegration() $this->assertDef('nntp://news.example.com/324234'); $this->assertDef('mailto:bob@example.com'); $this->assertDef('tel:+15555555555'); + $this->assertDef('tel:+15555 555 555', 'tel:+15555555555'); + $this->assertDef('tel:+15555%20555%20555', 'tel:+15555555555'); } public function testIntegrationWithPercentEncoder() diff --git a/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php b/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php index 19b65b3b0..4a4c2363d 100644 --- a/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php +++ b/tests/HTMLPurifier/URIFilter/MakeAbsoluteTest.php @@ -40,6 +40,8 @@ public function testPreserveAltScheme() public function testPreserveAltSchemeWithTel() { $this->assertFiltering('tel:+15555555555'); + $this->assertFiltering('tel:+15555 555 555'); + $this->assertFiltering('tel:+15555%20555%20555'); } public function testFilterIgnoreHTTPSpecialCase() diff --git a/tests/HTMLPurifier/URIParserTest.php b/tests/HTMLPurifier/URIParserTest.php index 4bc21b760..6b9712b37 100644 --- a/tests/HTMLPurifier/URIParserTest.php +++ b/tests/HTMLPurifier/URIParserTest.php @@ -75,6 +75,10 @@ public function testTelURI() 'tel:+1 (555) 555-5555', 'tel', null, null, null, '+1 (555) 555-5555', null, null ); + $this->assertParsing( + 'tel:+1%20(555)%20555-5555', + 'tel', null, null, null, '+1%20(555)%20555-5555', null, null + ); } public function testIPv4Address() diff --git a/tests/HTMLPurifier/URISchemeTest.php b/tests/HTMLPurifier/URISchemeTest.php index cae6edd05..ade89cc83 100644 --- a/tests/HTMLPurifier/URISchemeTest.php +++ b/tests/HTMLPurifier/URISchemeTest.php @@ -179,6 +179,13 @@ public function test_tel_strip_punctuation() ); } + public function test_tel_with_url_encoding() + { + $this->assertValidation( + 'tel:+1%20(555)%20555-5555', 'tel:+15555555555' + ); + } + public function test_tel_regular() { $this->assertValidation( From da35a5e0d745184c010359d9182cbac5049fe9b5 Mon Sep 17 00:00:00 2001 From: "jw2(kit rio)" Date: Mon, 5 Dec 2022 04:22:17 +0900 Subject: [PATCH 47/48] Drop supporting PHP 5.2 (#335) (#356) --- library/HTMLPurifier/Bootstrap.php | 41 +++--------------------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/library/HTMLPurifier/Bootstrap.php b/library/HTMLPurifier/Bootstrap.php index 707122bb2..bd8f9984f 100644 --- a/library/HTMLPurifier/Bootstrap.php +++ b/library/HTMLPurifier/Bootstrap.php @@ -79,44 +79,11 @@ public static function getPath($class) public static function registerAutoload() { $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); - if (($funcs = spl_autoload_functions()) === false) { + if (spl_autoload_functions() === false) { spl_autoload_register($autoload); - } elseif (function_exists('spl_autoload_unregister')) { - if (version_compare(PHP_VERSION, '5.3.0', '>=')) { - // prepend flag exists, no need for shenanigans - spl_autoload_register($autoload, true, true); - } else { - $buggy = version_compare(PHP_VERSION, '5.2.11', '<'); - $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && - version_compare(PHP_VERSION, '5.1.0', '>='); - foreach ($funcs as $func) { - if ($buggy && is_array($func)) { - // :TRICKY: There are some compatibility issues and some - // places where we need to error out - $reflector = new ReflectionMethod($func[0], $func[1]); - if (!$reflector->isStatic()) { - throw new Exception( - 'HTML Purifier autoloader registrar is not compatible - with non-static object methods due to PHP Bug #44144; - Please do not use HTMLPurifier.autoload.php (or any - file that includes this file); instead, place the code: - spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\')) - after your own autoloaders.' - ); - } - // Suprisingly, spl_autoload_register supports the - // Class::staticMethod callback format, although call_user_func doesn't - if ($compat) { - $func = implode('::', $func); - } - } - spl_autoload_unregister($func); - } - spl_autoload_register($autoload); - foreach ($funcs as $func) { - spl_autoload_register($func); - } - } + } else { + // prepend flag exists, no need for shenanigans + spl_autoload_register($autoload, true, true); } } } From 2d775c01874e2f676ba1a2d9fe69b47c2a823061 Mon Sep 17 00:00:00 2001 From: Raheel Hsn Date: Fri, 13 Jan 2023 00:41:13 +1100 Subject: [PATCH 48/48] feat: Add support for all text-decoration properties (#360) * CSS: add support for all text-decoration related properties * updated arrays to use short syntex Co-authored-by: Raheel Hasan --- library/HTMLPurifier/CSSDefinition.php | 199 ++++++++++++++----------- tests/HTMLPurifier/AttrDef/CSSTest.php | 4 + 2 files changed, 112 insertions(+), 91 deletions(-) diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php index 3f08b81c5..1bc419c53 100644 --- a/library/HTMLPurifier/CSSDefinition.php +++ b/library/HTMLPurifier/CSSDefinition.php @@ -13,7 +13,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition * Assoc array of attribute name to definition object. * @type HTMLPurifier_AttrDef[] */ - public $info = array(); + public $info = []; /** * Constructs the info array. The meat of this class. @@ -22,7 +22,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition protected function doSetup($config) { $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( - array('left', 'right', 'center', 'justify'), + ['left', 'right', 'center', 'justify'], false ); @@ -31,7 +31,7 @@ protected function doSetup($config) $this->info['border-right-style'] = $this->info['border-left-style'] = $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'none', 'hidden', 'dotted', @@ -42,42 +42,42 @@ protected function doSetup($config) 'ridge', 'inset', 'outset' - ), + ], false ); $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'left', 'right', 'both'), + ['none', 'left', 'right', 'both'], false ); $this->info['float'] = new HTMLPurifier_AttrDef_Enum( - array('none', 'left', 'right'), + ['none', 'left', 'right'], false ); $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'italic', 'oblique'), + ['normal', 'italic', 'oblique'], false ); $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( - array('normal', 'small-caps'), + ['normal', 'small-caps'], false ); $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('none')), + [ + new HTMLPurifier_AttrDef_Enum(['none']), new HTMLPurifier_AttrDef_CSS_URI() - ) + ] ); $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( - array('inside', 'outside'), + ['inside', 'outside'], false ); $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'disc', 'circle', 'square', @@ -87,7 +87,7 @@ protected function doSetup($config) 'lower-alpha', 'upper-alpha', 'none' - ), + ], false ); $this->info['list-style-image'] = $uri_or_none; @@ -95,34 +95,34 @@ protected function doSetup($config) $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( - array('capitalize', 'uppercase', 'lowercase', 'none'), + ['capitalize', 'uppercase', 'lowercase', 'none'], false ); $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['background-image'] = $uri_or_none; $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( - array('repeat', 'repeat-x', 'repeat-y', 'no-repeat') + ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] ); $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( - array('scroll', 'fixed') + ['scroll', 'fixed'] ); $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Enum( - array( + [ 'auto', 'cover', 'contain', 'initial', 'inherit', - ) + ] ), new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Length() - ) + ] ); $border_color = @@ -131,10 +131,10 @@ protected function doSetup($config) $this->info['border-left-color'] = $this->info['border-right-color'] = $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('transparent')), + [ + new HTMLPurifier_AttrDef_Enum(['transparent']), new HTMLPurifier_AttrDef_CSS_Color() - ) + ] ); $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); @@ -146,32 +146,32 @@ protected function doSetup($config) $this->info['border-bottom-width'] = $this->info['border-left-width'] = $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), + [ + new HTMLPurifier_AttrDef_Enum(['thin', 'medium', 'thick']), new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative - ) + ] ); $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('normal')), + [ + new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_CSS_Length() - ) + ] ); $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('normal')), + [ + new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_CSS_Length() - ) + ] ); $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Enum( - array( + [ 'xx-small', 'x-small', 'small', @@ -181,20 +181,20 @@ protected function doSetup($config) 'xx-large', 'larger', 'smaller' - ) + ] ), new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Length() - ) + ] ); $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( - new HTMLPurifier_AttrDef_Enum(array('normal')), + [ + new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) - ) + ] ); $margin = @@ -202,11 +202,11 @@ protected function doSetup($config) $this->info['margin-bottom'] = $this->info['margin-left'] = $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_Enum(array('auto')) - ) + new HTMLPurifier_AttrDef_Enum(['auto']) + ] ); $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); @@ -217,41 +217,41 @@ protected function doSetup($config) $this->info['padding-bottom'] = $this->info['padding-left'] = $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) - ) + ] ); $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage() - ) + ] ); $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('auto', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['auto', 'initial', 'inherit']) + ] ); $trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['initial', 'inherit']) + ] ); $trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit']) + ] ); $max = $config->get('CSS.MaxImgLength'); @@ -263,10 +263,10 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('auto')) - ) + new HTMLPurifier_AttrDef_Enum(['auto']) + ] ), // For everyone else: $trusted_wh @@ -279,10 +279,10 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['initial', 'inherit']) + ] ), // For everyone else: $trusted_min_wh @@ -295,22 +295,39 @@ protected function doSetup($config) 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length('0', $max), - new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')) - ) + new HTMLPurifier_AttrDef_Enum(['none', 'initial', 'inherit']) + ] ), // For everyone else: $trusted_max_wh ); + // text-decoration and related shorthands $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); + $this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum( + ['none', 'underline', 'overline', 'line-through', 'initial', 'inherit'] + ); + + $this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum( + ['solid', 'double', 'dotted', 'dashed', 'wavy', 'initial', 'inherit'] + ); + + $this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(['auto', 'from-font', 'initial', 'inherit']) + ]); + $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); // this could use specialized code $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'normal', 'bold', 'bolder', @@ -324,7 +341,7 @@ protected function doSetup($config) '700', '800', '900' - ), + ], false ); @@ -340,21 +357,21 @@ protected function doSetup($config) $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( - array('collapse', 'separate') + ['collapse', 'separate'] ); $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( - array('top', 'bottom') + ['top', 'bottom'] ); $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( - array('auto', 'fixed') + ['auto', 'fixed'] ); $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Enum( - array( + [ 'baseline', 'sub', 'super', @@ -363,11 +380,11 @@ protected function doSetup($config) 'middle', 'bottom', 'text-bottom' - ) + ] ), new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage() - ) + ] ); $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); @@ -375,7 +392,7 @@ protected function doSetup($config) // These CSS properties don't work on many browsers, but we live // in THE FUTURE! $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( - array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') + ['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line'] ); if ($config->get('CSS.Proprietary')) { @@ -422,21 +439,21 @@ protected function doSetupProprietary($config) // more CSS3 $this->info['page-break-after'] = $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'auto', 'always', 'avoid', 'left', 'right' - ) + ] ); - $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); + $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']); $border_radius = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative - )); + ]); $this->info['border-top-left-radius'] = $this->info['border-top-right-radius'] = @@ -453,7 +470,7 @@ protected function doSetupProprietary($config) protected function doSetupTricky($config) { $this->info['display'] = new HTMLPurifier_AttrDef_Enum( - array( + [ 'inline', 'block', 'list-item', @@ -472,12 +489,12 @@ protected function doSetupTricky($config) 'table-cell', 'table-caption', 'none' - ) + ] ); $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( - array('visible', 'hidden', 'collapse') + ['visible', 'hidden', 'collapse'] ); - $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); + $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']); $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); } @@ -487,23 +504,23 @@ protected function doSetupTricky($config) protected function doSetupTrusted($config) { $this->info['position'] = new HTMLPurifier_AttrDef_Enum( - array('static', 'relative', 'absolute', 'fixed') + ['static', 'relative', 'absolute', 'fixed'] ); $this->info['top'] = $this->info['left'] = $this->info['right'] = $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - ) + new HTMLPurifier_AttrDef_Enum(['auto']), + ] ); $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( - array( + [ new HTMLPurifier_AttrDef_Integer(), - new HTMLPurifier_AttrDef_Enum(array('auto')), - ) + new HTMLPurifier_AttrDef_Enum(['auto']), + ] ); } diff --git a/tests/HTMLPurifier/AttrDef/CSSTest.php b/tests/HTMLPurifier/AttrDef/CSSTest.php index 17a56581b..2367c187f 100644 --- a/tests/HTMLPurifier/AttrDef/CSSTest.php +++ b/tests/HTMLPurifier/AttrDef/CSSTest.php @@ -73,6 +73,10 @@ public function test() $this->assertDef('min-width:50vw;'); $this->assertDef('min-width:-50vw;', false); $this->assertDef('text-decoration:underline;'); + $this->assertDef('text-decoration-line:overline;'); + $this->assertDef('text-decoration-style:dashed;'); + $this->assertDef('text-decoration-color:#F00;'); + $this->assertDef('text-decoration-thickness:5%;'); $this->assertDef('font-family:sans-serif;'); $this->assertDef("font-family:Gill, 'Times New Roman', sans-serif;"); $this->assertDef('font:12px serif;');
a
a
a
a