aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-02-25 18:45:56 +0800
committerGitHub <noreply@github.com>2024-02-25 10:45:56 +0000
commitf9207b09479df964872d68842469991042b5497f (patch)
tree78db3a0b9146be056a518bcd012b106f77095ecc /modules
parent2e33671f2c1e98759e4fd2a90944c534cfdf5776 (diff)
downloadgitea-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.go25
-rw-r--r--modules/templates/helper_test.go5
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>&lt; < 1</a>"), HTMLFormat("<a>%s %s %d</a>", "<", template.HTML("<"), 1))
+}