diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2024-02-25 18:45:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-25 10:45:56 +0000 |
commit | f9207b09479df964872d68842469991042b5497f (patch) | |
tree | 78db3a0b9146be056a518bcd012b106f77095ecc /modules | |
parent | 2e33671f2c1e98759e4fd2a90944c534cfdf5776 (diff) | |
download | gitea-f9207b09479df964872d68842469991042b5497f.tar.gz gitea-f9207b09479df964872d68842469991042b5497f.zip |
Refactor Safe modifier (#29392)
After this PR: no need to play with the Safe/Escape tricks anymore. See
the changes for more details.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/templates/helper.go | 25 | ||||
-rw-r--r-- | modules/templates/helper_test.go | 5 |
2 files changed, 27 insertions, 3 deletions
diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 691f754748..5679487498 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -9,6 +9,7 @@ import ( "html" "html/template" "net/url" + "slices" "strings" "time" @@ -34,7 +35,8 @@ func NewFuncMap() template.FuncMap { // html/template related functions "dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names. "Eval": Eval, - "Safe": Safe, + "SafeHTML": SafeHTML, + "HTMLFormat": HTMLFormat, "Escape": Escape, "QueryEscape": url.QueryEscape, "JSEscape": JSEscapeSafe, @@ -177,8 +179,25 @@ func NewFuncMap() template.FuncMap { } } -// Safe render raw as HTML -func Safe(s any) template.HTML { +func HTMLFormat(s string, rawArgs ...any) template.HTML { + args := slices.Clone(rawArgs) + for i, v := range args { + switch v := v.(type) { + case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML: + // for most basic types (including template.HTML which is safe), just do nothing and use it + case string: + args[i] = template.HTMLEscapeString(v) + case fmt.Stringer: + args[i] = template.HTMLEscapeString(v.String()) + default: + args[i] = template.HTMLEscapeString(fmt.Sprint(v)) + } + } + return template.HTML(fmt.Sprintf(s, args...)) +} + +// SafeHTML render raw as HTML +func SafeHTML(s any) template.HTML { switch v := s.(type) { case string: return template.HTML(v) diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go index 739a92f34f..8f5d633d4f 100644 --- a/modules/templates/helper_test.go +++ b/modules/templates/helper_test.go @@ -4,6 +4,7 @@ package templates import ( + "html/template" "testing" "github.com/stretchr/testify/assert" @@ -56,3 +57,7 @@ func TestSubjectBodySeparator(t *testing.T) { func TestJSEscapeSafe(t *testing.T) { assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`)) } + +func TestHTMLFormat(t *testing.T) { + assert.Equal(t, template.HTML("<a>< < 1</a>"), HTMLFormat("<a>%s %s %d</a>", "<", template.HTML("<"), 1)) +} |