Browse Source

Fix escaping in post summary

Unescaping post content after sanitizing it. This will prevent double
escaping when summary is rendered by html/template package which does
escaping by default.
Fixes #340
pull/382/head
Josip Antoliš 3 years ago
parent
commit
eb76faa129
3 changed files with 44 additions and 8 deletions
  1. +8
    -6
      postrender.go
  2. +1
    -2
      posts.go
  3. +35
    -0
      posts_test.go

+ 8
- 6
postrender.go View File

@@ -140,9 +140,7 @@ func applyBasicMarkdown(data []byte) string {
func postTitle(content, friendlyId string) string {
const maxTitleLen = 80

// Strip HTML tags with bluemonday's StrictPolicy, then unescape the HTML
// entities added in by sanitizing the content.
content = html.UnescapeString(bluemonday.StrictPolicy().Sanitize(content))
content = stripHTMLWithoutEscaping(content)

content = strings.TrimLeftFunc(stripmd.Strip(content), unicode.IsSpace)
eol := strings.IndexRune(content, '\n')
@@ -160,9 +158,7 @@ func postTitle(content, friendlyId string) string {
func friendlyPostTitle(content, friendlyId string) string {
const maxTitleLen = 80

// Strip HTML tags with bluemonday's StrictPolicy, then unescape the HTML
// entities added in by sanitizing the content.
content = html.UnescapeString(bluemonday.StrictPolicy().Sanitize(content))
content = stripHTMLWithoutEscaping(content)

content = strings.TrimLeftFunc(stripmd.Strip(content), unicode.IsSpace)
eol := strings.IndexRune(content, '\n')
@@ -179,6 +175,12 @@ func friendlyPostTitle(content, friendlyId string) string {
return title
}

// Strip HTML tags with bluemonday's StrictPolicy, then unescape the HTML
// entities added in by sanitizing the content.
func stripHTMLWithoutEscaping(content string) string {
return html.UnescapeString(bluemonday.StrictPolicy().Sanitize(content))
}

func getSanitizationPolicy() *bluemonday.Policy {
policy := bluemonday.UGCPolicy()
policy.AllowAttrs("src", "style").OnElements("iframe", "video", "audio")


+ 1
- 2
posts.go View File

@@ -211,8 +211,7 @@ func (p Post) Summary() string {
if p.Content == "" {
return ""
}
// Strip out HTML
p.Content = bluemonday.StrictPolicy().Sanitize(p.Content)
p.Content = stripHTMLWithoutEscaping(p.Content)
// and Markdown
p.Content = stripmd.Strip(p.Content)



+ 35
- 0
posts_test.go View File

@@ -0,0 +1,35 @@
package writefreely_test

import (
"testing"

"github.com/guregu/null/zero"
"github.com/stretchr/testify/assert"
"github.com/writeas/writefreely"
)

func TestPostSummary(t *testing.T) {
testCases := map[string]struct {
given writefreely.Post
expected string
}{
"no special chars": {givenPost("Content."), "Content."},
"HTML content": {givenPost("Content <p>with a</p> paragraph."), "Content with a paragraph."},
"content with escaped char": {givenPost("Content&#39;s all OK."), "Content's all OK."},
"multiline content": {givenPost(`Content
in
multiple
lines.`), "Content in multiple lines."},
}

for name, test := range testCases {
t.Run(name, func(t *testing.T) {
actual := test.given.Summary()
assert.Equal(t, test.expected, actual)
})
}
}

func givenPost(content string) writefreely.Post {
return writefreely.Post{Title: zero.StringFrom("Title"), Content: content}
}

Loading…
Cancel
Save