mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
- CSS sanitizer allows a limited set of properties in a style attribute. - Added a CSS inlined version of the tutsplus responsive test mail. - Linter fixes in inbucket.go
89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package sanitize
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/microcosm-cc/bluemonday"
|
|
"golang.org/x/net/html"
|
|
)
|
|
|
|
var (
|
|
cssSafe = regexp.MustCompile(".*")
|
|
policy = bluemonday.UGCPolicy().
|
|
AllowElements("center").
|
|
AllowAttrs("style").Matching(cssSafe).Globally()
|
|
)
|
|
|
|
func HTML(html string) (output string, err error) {
|
|
output, err = sanitizeStyleTags(html)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
output = policy.Sanitize(output)
|
|
return
|
|
}
|
|
|
|
func sanitizeStyleTags(input string) (string, error) {
|
|
r := strings.NewReader(input)
|
|
b := &bytes.Buffer{}
|
|
if err := styleTagFilter(b, r); err != nil {
|
|
return "", err
|
|
}
|
|
return b.String(), nil
|
|
}
|
|
|
|
func styleTagFilter(w io.Writer, r io.Reader) error {
|
|
bw := bufio.NewWriter(w)
|
|
b := make([]byte, 256)
|
|
z := html.NewTokenizer(r)
|
|
for {
|
|
b = b[:0]
|
|
tt := z.Next()
|
|
switch tt {
|
|
case html.ErrorToken:
|
|
err := z.Err()
|
|
if err == io.EOF {
|
|
return bw.Flush()
|
|
}
|
|
return err
|
|
case html.StartTagToken, html.SelfClosingTagToken:
|
|
name, hasAttr := z.TagName()
|
|
if !hasAttr {
|
|
bw.Write(z.Raw())
|
|
continue
|
|
}
|
|
b = append(b, '<')
|
|
b = append(b, name...)
|
|
for {
|
|
key, val, more := z.TagAttr()
|
|
strval := string(val)
|
|
style := false
|
|
if strings.ToLower(string(key)) == "style" {
|
|
style = true
|
|
strval = sanitizeStyle(strval)
|
|
}
|
|
if !style || strval != "" {
|
|
b = append(b, ' ')
|
|
b = append(b, key...)
|
|
b = append(b, '=', '"')
|
|
b = append(b, []byte(html.EscapeString(strval))...)
|
|
b = append(b, '"')
|
|
}
|
|
if !more {
|
|
break
|
|
}
|
|
}
|
|
if tt == html.SelfClosingTagToken {
|
|
b = append(b, '/')
|
|
}
|
|
bw.Write(append(b, '>'))
|
|
default:
|
|
bw.Write(z.Raw())
|
|
}
|
|
}
|
|
}
|