diff --git a/Text/HTML/SanitizeXSS.hs b/Text/HTML/SanitizeXSS.hs
index e701fe0..4e9f54a 100644
--- a/Text/HTML/SanitizeXSS.hs
+++ b/Text/HTML/SanitizeXSS.hs
@@ -12,7 +12,7 @@ import Text.HTML.SanitizeXSS.Css
import Text.HTML.TagSoup
-import Data.Set (Set(), member, notMember, (\\), fromList)
+import Data.Set (Set(), member, notMember, (\\), fromList, fromAscList)
import Data.Char ( toLower )
import Data.Text (Text)
import qualified Data.Text as T
@@ -41,9 +41,12 @@ sanitizeBalance = filterTags (balance Map.empty . safeTags)
-- | insert custom tag filtering. Don't forget to compose your filter with safeTags!
filterTags :: ([Tag Text] -> [Tag Text]) -> Text -> Text
filterTags f = renderTagsOptions renderOptions {
- optMinimize = \x -> x `elem` ["br","img"] -- converts to
, converts to
+ optMinimize = \x -> x `member` voidElems --
converts to
, converts to
} . f . canonicalizeTags . parseTags
+voidElems :: Set T.Text
+voidElems = fromAscList $ T.words $ T.pack "area base br col command embed hr img input keygen link meta param source track wbr"
+
balance :: Map.Map Text Int -> [Tag Text] -> [Tag Text]
balance m [] =
concatMap go $ Map.toList m
@@ -51,7 +54,7 @@ balance m [] =
go (name, i)
| noClosing name = []
| otherwise = replicate i $ TagClose name
- noClosing = flip elem ["br", "img"]
+ noClosing = flip member voidElems
balance m (t@(TagClose name):tags) =
case Map.lookup name m of
Nothing -> TagOpen name [] : TagClose name : balance m tags
diff --git a/test/main.hs b/test/main.hs
index 6ec99f3..747efe1 100644
--- a/test/main.hs
+++ b/test/main.hs
@@ -14,6 +14,7 @@ test f actual expected = do
result @?= expected
sanitized = test sanitize
+sanitizedB = test sanitizeBalance
main = hspecX $ do
describe "html sanitizing" $ do
@@ -76,3 +77,11 @@ main = hspecX $ do
it "allows valid units for grey-listed css" $ do
let grey2Css = "