123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import tinycss2
- ALLOWED_CSS_PROPERTIES = frozenset(
- (
- "azimuth",
- "background-color",
- "border-bottom-color",
- "border-collapse",
- "border-color",
- "border-left-color",
- "border-right-color",
- "border-top-color",
- "clear",
- "color",
- "cursor",
- "direction",
- "display",
- "elevation",
- "float",
- "font",
- "font-family",
- "font-size",
- "font-style",
- "font-variant",
- "font-weight",
- "height",
- "letter-spacing",
- "line-height",
- "overflow",
- "pause",
- "pause-after",
- "pause-before",
- "pitch",
- "pitch-range",
- "richness",
- "speak",
- "speak-header",
- "speak-numeral",
- "speak-punctuation",
- "speech-rate",
- "stress",
- "text-align",
- "text-decoration",
- "text-indent",
- "unicode-bidi",
- "vertical-align",
- "voice-family",
- "volume",
- "white-space",
- "width",
- )
- )
- ALLOWED_SVG_PROPERTIES = frozenset(
- (
- "fill",
- "fill-opacity",
- "fill-rule",
- "stroke",
- "stroke-width",
- "stroke-linecap",
- "stroke-linejoin",
- "stroke-opacity",
- )
- )
- class CSSSanitizer:
- def __init__(
- self,
- allowed_css_properties=ALLOWED_CSS_PROPERTIES,
- allowed_svg_properties=ALLOWED_SVG_PROPERTIES,
- ):
- self.allowed_css_properties = allowed_css_properties
- self.allowed_svg_properties = allowed_svg_properties
- def sanitize_css(self, style):
- """Sanitizes css in style tags"""
- parsed = tinycss2.parse_declaration_list(style)
- if not parsed:
- return ""
- new_tokens = []
- for token in parsed:
- if token.type == "declaration":
- if (
- token.lower_name in self.allowed_css_properties
- or token.lower_name in self.allowed_svg_properties
- ):
- new_tokens.append(token)
- elif token.type in ("comment", "whitespace"):
- if new_tokens and new_tokens[-1].type != token.type:
- new_tokens.append(token)
- # NOTE(willkg): We currently don't handle AtRule or ParseError and
- # so both get silently thrown out
- if not new_tokens:
- return ""
- return tinycss2.serialize(new_tokens).strip()
|