Refactor Safe modifier (#29392)

After this PR: no need to play with the Safe/Escape tricks anymore. See
the changes for more details.
This commit is contained in:
wxiaoguang 2024-02-25 18:45:56 +08:00 committed by GitHub
parent 2e33671f2c
commit f9207b0947
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 89 additions and 65 deletions

View File

@ -266,7 +266,7 @@ the messages. Here's a list of some of them:
| `AppDomain` | - | Any | Gitea's host name | | `AppDomain` | - | Any | Gitea's host name |
| `EllipsisString` | string, int | Any | Truncates a string to the specified length; adds ellipsis as needed | | `EllipsisString` | string, int | Any | Truncates a string to the specified length; adds ellipsis as needed |
| `Str2html` | string | Body only | Sanitizes text by removing any HTML tags from it. | | `Str2html` | string | Body only | Sanitizes text by removing any HTML tags from it. |
| `Safe` | string | Body only | Takes the input as HTML; can be used for `.ReviewComments.RenderedContent`. | | `SafeHTML` | string | Body only | Takes the input as HTML; can be used for `.ReviewComments.RenderedContent`. |
These are _functions_, not metadata, so they have to be used: These are _functions_, not metadata, so they have to be used:

View File

@ -242,14 +242,14 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://go.dev/pkg/text/
模板系统包含一些函数,可用于进一步处理和格式化消息。以下是其中一些函数的列表: 模板系统包含一些函数,可用于进一步处理和格式化消息。以下是其中一些函数的列表:
| 函数名 | 参数 | 可用于 | 用法 | | 函数名 | 参数 | 可用于 | 用法 |
| ----------------- | ----------- | ------------ | --------------------------------------------------------------------------------- | |------------------| ----------- | ------------ | --------------------------------------------------------------------------------- |
| `AppUrl` | - | 任何地方 | Gitea 的 URL | | `AppUrl` | - | 任何地方 | Gitea 的 URL |
| `AppName` | - | 任何地方 | 从 `app.ini` 中设置,通常为 "Gitea" | | `AppName` | - | 任何地方 | 从 `app.ini` 中设置,通常为 "Gitea" |
| `AppDomain` | - | 任何地方 | Gitea 的主机名 | | `AppDomain` | - | 任何地方 | Gitea 的主机名 |
| `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 | | `EllipsisString` | string, int | 任何地方 | 将字符串截断为指定长度;根据需要添加省略号 |
| `Str2html` | string | 仅正文部分 | 通过删除其中的 HTML 标签对文本进行清理 | | `Str2html` | string | 仅正文部分 | 通过删除其中的 HTML 标签对文本进行清理 |
| `Safe` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 | | `SafeHTML` | string | 仅正文部分 | 将输入作为 HTML 处理;可用于 `.ReviewComments.RenderedContent` 等字段 |
这些都是 _函数_,而不是元数据,因此必须按以下方式使用: 这些都是 _函数_,而不是元数据,因此必须按以下方式使用:

View File

@ -9,6 +9,7 @@ import (
"html" "html"
"html/template" "html/template"
"net/url" "net/url"
"slices"
"strings" "strings"
"time" "time"
@ -34,7 +35,8 @@ func NewFuncMap() template.FuncMap {
// html/template related functions // html/template related functions
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names. "dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
"Eval": Eval, "Eval": Eval,
"Safe": Safe, "SafeHTML": SafeHTML,
"HTMLFormat": HTMLFormat,
"Escape": Escape, "Escape": Escape,
"QueryEscape": url.QueryEscape, "QueryEscape": url.QueryEscape,
"JSEscape": JSEscapeSafe, "JSEscape": JSEscapeSafe,
@ -177,8 +179,25 @@ func NewFuncMap() template.FuncMap {
} }
} }
// Safe render raw as HTML func HTMLFormat(s string, rawArgs ...any) template.HTML {
func Safe(s 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) { switch v := s.(type) {
case string: case string:
return template.HTML(v) return template.HTML(v)

View File

@ -4,6 +4,7 @@
package templates package templates
import ( import (
"html/template"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -56,3 +57,7 @@ func TestSubjectBodySeparator(t *testing.T) {
func TestJSEscapeSafe(t *testing.T) { func TestJSEscapeSafe(t *testing.T) {
assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`)) 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))
}

View File

@ -88,7 +88,7 @@
{{ctx.Locale.Tr "packages.settings.delete"}} {{ctx.Locale.Tr "packages.settings.delete"}}
</div> </div>
<div class="content"> <div class="content">
{{ctx.Locale.Tr "packages.settings.delete.notice" (`<span class="name"></span>`|Safe) (`<span class="dataVersion"></span>`|Safe)}} {{ctx.Locale.Tr "packages.settings.delete.notice" (`<span class="name"></span>`|SafeHTML) (`<span class="dataVersion"></span>`|SafeHTML)}}
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>

View File

@ -101,7 +101,7 @@
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "repo.settings.delete_desc"}}</p> <p>{{ctx.Locale.Tr "repo.settings.delete_desc"}}</p>
{{ctx.Locale.Tr "repo.settings.delete_notices_2" (`<span class="name"></span>`|Safe)}}<br> {{ctx.Locale.Tr "repo.settings.delete_notices_2" (`<span class="name"></span>`|SafeHTML)}}<br>
{{ctx.Locale.Tr "repo.settings.delete_notices_fork_1"}}<br> {{ctx.Locale.Tr "repo.settings.delete_notices_fork_1"}}<br>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}

View File

@ -39,7 +39,7 @@
{{ctx.Locale.Tr "admin.monitor.process.cancel"}} {{ctx.Locale.Tr "admin.monitor.process.cancel"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "admin.monitor.process.cancel_notices" (`<span class="name"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "admin.monitor.process.cancel_notices" (`<span class="name"></span>`|SafeHTML)}}</p>
<p>{{ctx.Locale.Tr "admin.monitor.process.cancel_desc"}}</p> <p>{{ctx.Locale.Tr "admin.monitor.process.cancel_desc"}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}

View File

@ -8,14 +8,14 @@
<title>{{.Subject}}</title> <title>{{.Subject}}</title>
</head> </head>
{{$repo_url := printf "<a href='%s'>%s</a>" (Escape .Issue.Repo.HTMLURL) (Escape .Issue.Repo.FullName)}} {{$repo_url := HTMLFormat "<a href='%s'>%s</a>" .Issue.Repo.HTMLURL .Issue.Repo.FullName}}
{{$link := printf "<a href='%s'>#%d</a>" (Escape .Link) .Issue.Index}} {{$link := HTMLFormat "<a href='%s'>#%d</a>" .Link .Issue.Index}}
<body> <body>
<p> <p>
{{if .IsPull}} {{if .IsPull}}
{{.locale.Tr "mail.issue_assigned.pull" .Doer.Name ($link|Safe) ($repo_url|Safe)}} {{.locale.Tr "mail.issue_assigned.pull" .Doer.Name $link $repo_url}}
{{else}} {{else}}
{{.locale.Tr "mail.issue_assigned.issue" .Doer.Name ($link|Safe) ($repo_url|Safe)}} {{.locale.Tr "mail.issue_assigned.issue" .Doer.Name $link $repo_url}}
{{end}} {{end}}
</p> </p>
<div class="footer"> <div class="footer">

View File

@ -22,13 +22,13 @@
{{if .Comment.IsForcePush}} {{if .Comment.IsForcePush}}
{{$oldCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.OldCommit}} {{$oldCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.OldCommit}}
{{$oldShortSha := ShortSha .Comment.OldCommit}} {{$oldShortSha := ShortSha .Comment.OldCommit}}
{{$oldCommitLink := printf "<a href='%[1]s'><b>%[2]s</b></a>" (Escape $oldCommitUrl) (Escape $oldShortSha)}} {{$oldCommitLink := HTMLFormat "<a href='%[1]s'><b>%[2]s</b></a>" $oldCommitUrl $oldShortSha}}
{{$newCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.NewCommit}} {{$newCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.NewCommit}}
{{$newShortSha := ShortSha .Comment.NewCommit}} {{$newShortSha := ShortSha .Comment.NewCommit}}
{{$newCommitLink := printf "<a href='%[1]s'><b>%[2]s</b></a>" (Escape $newCommitUrl) (Escape $newShortSha)}} {{$newCommitLink := HTMLFormat "<a href='%[1]s'><b>%[2]s</b></a>" $newCommitUrl $newShortSha}}
{{.locale.Tr "mail.issue.action.force_push" .Doer.Name .Comment.Issue.PullRequest.HeadBranch ($oldCommitLink|Safe) ($newCommitLink|Safe)}} {{.locale.Tr "mail.issue.action.force_push" .Doer.Name .Comment.Issue.PullRequest.HeadBranch $oldCommitLink $newCommitLink}}
{{else}} {{else}}
{{.locale.TrN (len .Comment.Commits) "mail.issue.action.push_1" "mail.issue.action.push_n" .Doer.Name .Comment.Issue.PullRequest.HeadBranch (len .Comment.Commits)}} {{.locale.TrN (len .Comment.Commits) "mail.issue.action.push_1" "mail.issue.action.push_n" .Doer.Name .Comment.Issue.PullRequest.HeadBranch (len .Comment.Commits)}}
{{end}} {{end}}
@ -65,7 +65,7 @@
{{$.locale.Tr "mail.issue.in_tree_path" .TreePath}} {{$.locale.Tr "mail.issue.in_tree_path" .TreePath}}
<div class="review"> <div class="review">
<pre>{{.Patch}}</pre> <pre>{{.Patch}}</pre>
<div>{{.RenderedContent | Safe}}</div> <div>{{.RenderedContent | SafeHTML}}</div>
</div> </div>
{{end -}} {{end -}}
{{if eq .ActionName "push"}} {{if eq .ActionName "push"}}

View File

@ -5,10 +5,10 @@
<title>{{.Subject}}</title> <title>{{.Subject}}</title>
</head> </head>
{{$url := printf "<a href='%[1]s'>%[2]s</a>" (Escape .Link) (Escape .Repo)}} {{$url := HTMLFormat "<a href='%[1]s'>%[2]s</a>" .Link .Repo)}}
<body> <body>
<p>{{.Subject}}. <p>{{.Subject}}.
{{.locale.Tr "mail.repo.transfer.body" ($url|Safe)}} {{.locale.Tr "mail.repo.transfer.body" $url}}
</p> </p>
<p> <p>
--- ---

View File

@ -11,11 +11,11 @@
</head> </head>
{{$release_url := printf "<a href='%s'>%s</a>" (.Release.HTMLURL | Escape) (.Release.TagName | Escape)}} {{$release_url := HTMLFormat "<a href='%s'>%s</a>" .Release.HTMLURL .Release.TagName}}
{{$repo_url := printf "<a href='%s'>%s</a>" (.Release.Repo.HTMLURL | Escape) (.Release.Repo.FullName | Escape)}} {{$repo_url := HTMLFormat "<a href='%s'>%s</a>" .Release.Repo.HTMLURL .Release.Repo.FullName}}
<body> <body>
<p> <p>
{{.locale.Tr "mail.release.new.text" .Release.Publisher.Name ($release_url|Safe) ($repo_url|Safe)}} {{.locale.Tr "mail.release.new.text" .Release.Publisher.Name $release_url $repo_url}}
</p> </p>
<h4>{{.locale.Tr "mail.release.title" .Release.Title}}</h4> <h4>{{.locale.Tr "mail.release.title" .Release.Title}}</h4>
<p> <p>

View File

@ -73,7 +73,7 @@
{{ctx.Locale.Tr "org.members.leave"}} {{ctx.Locale.Tr "org.members.leave"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.members.leave.detail" (`<span class="dataOrganizationName"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.members.leave.detail" (`<span class="dataOrganizationName"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>
@ -82,7 +82,7 @@
{{ctx.Locale.Tr "org.members.remove"}} {{ctx.Locale.Tr "org.members.remove"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.members.remove.detail" (`<span class="name"></span>`|Safe) (`<span class="dataOrganizationName"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.members.remove.detail" (`<span class="name"></span>`|SafeHTML) (`<span class="dataOrganizationName"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>

View File

@ -81,7 +81,7 @@
{{ctx.Locale.Tr "org.members.remove"}} {{ctx.Locale.Tr "org.members.remove"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.members.remove.detail" (`<span class="name"></span>`|Safe) (`<span class="dataTeamName"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.members.remove.detail" (`<span class="name"></span>`|SafeHTML) (`<span class="dataTeamName"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>

View File

@ -88,7 +88,7 @@
{{ctx.Locale.Tr "org.teams.leave"}} {{ctx.Locale.Tr "org.teams.leave"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.teams.leave.detail" (`<span class="name"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.teams.leave.detail" (`<span class="name"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>

View File

@ -49,7 +49,7 @@
{{ctx.Locale.Tr "org.teams.leave"}} {{ctx.Locale.Tr "org.teams.leave"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.teams.leave.detail" (`<span class="name"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.teams.leave.detail" (`<span class="name"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>

View File

@ -88,7 +88,7 @@
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<div class="field"> <div class="field">
<label> <label>
{{ctx.Locale.Tr "repo.branch.new_branch_from" (`<span class="text" id="modal-create-branch-from-span"></span>`|Safe)}} {{ctx.Locale.Tr "repo.branch.new_branch_from" (`<span class="text" id="modal-create-branch-from-span"></span>`|SafeHTML)}}
</label> </label>
</div> </div>
<div class="required field"> <div class="required field">
@ -113,7 +113,7 @@
<input type="hidden" name="create_tag" value="true"> <input type="hidden" name="create_tag" value="true">
<div class="field"> <div class="field">
<label> <label>
{{ctx.Locale.Tr "repo.tag.create_tag_from" (`<span class="text" id="modal-create-tag-from-span"></span>`|Safe)}} {{ctx.Locale.Tr "repo.tag.create_tag_from" (`<span class="text" id="modal-create-tag-from-span"></span>`|SafeHTML)}}
</label> </label>
</div> </div>
<div class="required field"> <div class="required field">

View File

@ -11,11 +11,11 @@
<div class="repo-editor-header"> <div class="repo-editor-header">
<div class="ui breadcrumb field {{if .Err_TreePath}}error{{end}}"> <div class="ui breadcrumb field {{if .Err_TreePath}}error{{end}}">
{{$shaurl := printf "%s/commit/%s" $.RepoLink (PathEscape .SHA)}} {{$shaurl := printf "%s/commit/%s" $.RepoLink (PathEscape .SHA)}}
{{$shalink := printf `<a class="ui primary sha label" href="%s">%s</a>` (Escape $shaurl) (ShortSha .SHA)}} {{$shalink := HTMLFormat `<a class="ui primary sha label" href="%s">%s</a>` $shaurl (ShortSha .SHA)}}
{{if eq .CherryPickType "revert"}} {{if eq .CherryPickType "revert"}}
{{ctx.Locale.Tr "repo.editor.revert" ($shalink|Safe)}} {{ctx.Locale.Tr "repo.editor.revert" $shalink}}
{{else}} {{else}}
{{ctx.Locale.Tr "repo.editor.cherry_pick" ($shalink|Safe)}} {{ctx.Locale.Tr "repo.editor.cherry_pick" $shalink}}
{{end}} {{end}}
<a class="section" href="{{$.RepoLink}}">{{.Repository.FullName}}</a> <a class="section" href="{{$.RepoLink}}">{{.Repository.FullName}}</a>
<div class="breadcrumb-divider">:</div> <div class="breadcrumb-divider">:</div>

View File

@ -112,9 +112,9 @@
{{template "shared/user/authorlink" .Poster}} {{template "shared/user/authorlink" .Poster}}
{{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}} {{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}}
{{if eq $.Issue.PullRequest.Status 3}} {{if eq $.Issue.PullRequest.Status 3}}
{{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (printf `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID) | Safe) (printf "<b>%[1]s</b>" ($.BaseTarget|Escape) | Safe) $createdStr}} {{ctx.Locale.Tr "repo.issues.comment_manually_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
{{else}} {{else}}
{{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (printf `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` ($link|Escape) (ShortSha $.Issue.PullRequest.MergedCommitID) | Safe) (printf "<b>%[1]s</b>" ($.BaseTarget|Escape) | Safe) $createdStr}} {{ctx.Locale.Tr "repo.issues.comment_pull_merged_at" (HTMLFormat `<a class="ui sha" href="%[1]s"><b>%[2]s</b></a>` $link (ShortSha $.Issue.PullRequest.MergedCommitID)) (HTMLFormat "<b>%[1]s</b>" $.BaseTarget) $createdStr}}
{{end}} {{end}}
</span> </span>
</div> </div>
@ -595,19 +595,19 @@
{{$oldProjectDisplayHtml := "Unknown Project"}} {{$oldProjectDisplayHtml := "Unknown Project"}}
{{if .OldProject}} {{if .OldProject}}
{{$trKey := printf "projects.type-%d.display_name" .OldProject.Type}} {{$trKey := printf "projects.type-%d.display_name" .OldProject.Type}}
{{$oldProjectDisplayHtml = printf `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey | Escape) (.OldProject.Title | Escape)}} {{$oldProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey) .OldProject.Title}}
{{end}} {{end}}
{{$newProjectDisplayHtml := "Unknown Project"}} {{$newProjectDisplayHtml := "Unknown Project"}}
{{if .Project}} {{if .Project}}
{{$trKey := printf "projects.type-%d.display_name" .Project.Type}} {{$trKey := printf "projects.type-%d.display_name" .Project.Type}}
{{$newProjectDisplayHtml = printf `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey | Escape) (.Project.Title | Escape)}} {{$newProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` (ctx.Locale.Tr $trKey) .Project.Title}}
{{end}} {{end}}
{{if and (gt .OldProjectID 0) (gt .ProjectID 0)}} {{if and (gt .OldProjectID 0) (gt .ProjectID 0)}}
{{ctx.Locale.Tr "repo.issues.change_project_at" ($oldProjectDisplayHtml|Safe) ($newProjectDisplayHtml|Safe) $createdStr}} {{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}}
{{else if gt .OldProjectID 0}} {{else if gt .OldProjectID 0}}
{{ctx.Locale.Tr "repo.issues.remove_project_at" ($oldProjectDisplayHtml|Safe) $createdStr}} {{ctx.Locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr}}
{{else if gt .ProjectID 0}} {{else if gt .ProjectID 0}}
{{ctx.Locale.Tr "repo.issues.add_project_at" ($newProjectDisplayHtml|Safe) $createdStr}} {{ctx.Locale.Tr "repo.issues.add_project_at" $newProjectDisplayHtml $createdStr}}
{{end}} {{end}}
</span> </span>
</div> </div>

View File

@ -39,7 +39,7 @@
{{ctx.Locale.Tr "repo.pulls.merged_success"}} {{ctx.Locale.Tr "repo.pulls.merged_success"}}
</h3> </h3>
<div class="merge-section-info"> <div class="merge-section-info">
{{ctx.Locale.Tr "repo.pulls.merged_info_text" (printf "<code>%s</code>" (.HeadTarget | Escape) | Safe)}} {{ctx.Locale.Tr "repo.pulls.merged_info_text" (HTMLFormat "<code>%s</code>" .HeadTarget)}}
</div> </div>
</div> </div>
<div class="item-section-right"> <div class="item-section-right">

View File

@ -43,31 +43,31 @@
{{end}} {{end}}
<div class="gt-ml-3"> <div class="gt-ml-3">
{{if .Issue.IsPull}} {{if .Issue.IsPull}}
{{$headHref := .HeadTarget|Escape}} {{$headHref := .HeadTarget}}
{{if .HeadBranchLink}} {{if .HeadBranchLink}}
{{$headHref = printf `<a href="%s">%s</a>` (.HeadBranchLink | Escape) $headHref}} {{$headHref = HTMLFormat `<a href="%s">%s</a>` .HeadBranchLink $headHref}}
{{end}} {{end}}
{{$headHref = printf `%s <button class="btn interact-fg" data-tooltip-content="%s" data-clipboard-text="%s">%s</button>` $headHref (ctx.Locale.Tr "copy_branch") (.HeadTarget | Escape) (svg "octicon-copy" 14)}} {{$headHref = HTMLFormat `%s <button class="btn interact-fg" data-tooltip-content="%s" data-clipboard-text="%s">%s</button>` $headHref (ctx.Locale.Tr "copy_branch") .HeadTarget (svg "octicon-copy" 14)}}
{{$baseHref := .BaseTarget|Escape}} {{$baseHref := .BaseTarget}}
{{if .BaseBranchLink}} {{if .BaseBranchLink}}
{{$baseHref = printf `<a href="%s">%s</a>` (.BaseBranchLink | Escape) $baseHref}} {{$baseHref = HTMLFormat `<a href="%s">%s</a>` .BaseBranchLink $baseHref}}
{{end}} {{end}}
{{if .Issue.PullRequest.HasMerged}} {{if .Issue.PullRequest.HasMerged}}
{{$mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix ctx.Locale}} {{$mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix ctx.Locale}}
{{if .Issue.OriginalAuthor}} {{if .Issue.OriginalAuthor}}
{{.Issue.OriginalAuthor}} {{.Issue.OriginalAuthor}}
<span class="pull-desc">{{ctx.Locale.Tr "repo.pulls.merged_title_desc" .NumCommits ($headHref|Safe) ($baseHref|Safe) $mergedStr}}</span> <span class="pull-desc">{{ctx.Locale.Tr "repo.pulls.merged_title_desc" .NumCommits $headHref $baseHref $mergedStr}}</span>
{{else}} {{else}}
<a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.GetDisplayName}}</a> <a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.GetDisplayName}}</a>
<span class="pull-desc">{{ctx.Locale.Tr "repo.pulls.merged_title_desc" .NumCommits ($headHref|Safe) ($baseHref|Safe) $mergedStr}}</span> <span class="pull-desc">{{ctx.Locale.Tr "repo.pulls.merged_title_desc" .NumCommits $headHref $baseHref $mergedStr}}</span>
{{end}} {{end}}
{{else}} {{else}}
{{if .Issue.OriginalAuthor}} {{if .Issue.OriginalAuthor}}
<span id="pull-desc" class="pull-desc">{{.Issue.OriginalAuthor}} {{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits ($headHref|Safe) ($baseHref|Safe)}}</span> <span id="pull-desc" class="pull-desc">{{.Issue.OriginalAuthor}} {{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref}}</span>
{{else}} {{else}}
<span id="pull-desc" class="pull-desc"> <span id="pull-desc" class="pull-desc">
<a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.GetDisplayName}}</a> <a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.GetDisplayName}}</a>
{{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits ($headHref|Safe) ($baseHref|Safe)}} {{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref}}
</span> </span>
{{end}} {{end}}
<span id="pull-desc-edit" class="gt-hidden flex-text-block"> <span id="pull-desc-edit" class="gt-hidden flex-text-block">

View File

@ -20,7 +20,7 @@
{{.Title}} {{.Title}}
</div> </div>
<div class="description gt-text-center"> <div class="description gt-text-center">
{{(printf "repo.migrate.%s.description" .Name) | ctx.Locale.Tr}} {{ctx.Locale.Tr (printf "repo.migrate.%s.description" .Name)}}
</div> </div>
</div> </div>
</a> </a>

View File

@ -15,9 +15,9 @@
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}} {{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
<div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}"> <div class="file-view{{if .IsMarkup}} markup {{.MarkupType}}{{else if .IsPlainText}} plain-text{{else if .IsTextFile}} code-view{{end}}">
{{if .IsMarkup}} {{if .IsMarkup}}
{{if .FileContent}}{{.FileContent | Safe}}{{end}} {{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}
{{else if .IsPlainText}} {{else if .IsPlainText}}
<pre>{{if .FileContent}}{{.FileContent | Safe}}{{end}}</pre> <pre>{{if .FileContent}}{{.FileContent | SafeHTML}}{{end}}</pre>
{{else if not .IsTextFile}} {{else if not .IsTextFile}}
<div class="view-raw"> <div class="view-raw">
{{if .IsImageFile}} {{if .IsImageFile}}

View File

@ -263,7 +263,7 @@
<label for="authorization_header">{{ctx.Locale.Tr "repo.settings.authorization_header"}}</label> <label for="authorization_header">{{ctx.Locale.Tr "repo.settings.authorization_header"}}</label>
<input id="authorization_header" name="authorization_header" type="text" value="{{.Webhook.HeaderAuthorization}}"{{if eq .HookType "matrix"}} placeholder="Bearer $access_token" required{{end}}> <input id="authorization_header" name="authorization_header" type="text" value="{{.Webhook.HeaderAuthorization}}"{{if eq .HookType "matrix"}} placeholder="Bearer $access_token" required{{end}}>
{{if ne .HookType "matrix"}}{{/* Matrix doesn't make the authorization optional but it is implied by the help string, should be changed.*/}} {{if ne .HookType "matrix"}}{{/* Matrix doesn't make the authorization optional but it is implied by the help string, should be changed.*/}}
<span class="help">{{ctx.Locale.Tr "repo.settings.authorization_header_desc" ("<code>Bearer token123456</code>, <code>Basic YWxhZGRpbjpvcGVuc2VzYW1l</code>" | Safe)}}</span> <span class="help">{{ctx.Locale.Tr "repo.settings.authorization_header_desc" ("<code>Bearer token123456</code>, <code>Basic YWxhZGRpbjpvcGVuc2VzYW1l</code>" | SafeHTML)}}</span>
{{end}} {{end}}
</div> </div>

View File

@ -67,13 +67,13 @@
<div class="wiki-content-parts"> <div class="wiki-content-parts">
{{if .sidebarTocContent}} {{if .sidebarTocContent}}
<div class="markup wiki-content-sidebar wiki-content-toc"> <div class="markup wiki-content-sidebar wiki-content-toc">
{{.sidebarTocContent | Safe}} {{.sidebarTocContent | SafeHTML}}
</div> </div>
{{end}} {{end}}
<div class="markup wiki-content-main {{if or .sidebarTocContent .sidebarPresent}}with-sidebar{{end}}"> <div class="markup wiki-content-main {{if or .sidebarTocContent .sidebarPresent}}with-sidebar{{end}}">
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}} {{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
{{.content | Safe}} {{.content | SafeHTML}}
</div> </div>
{{if .sidebarPresent}} {{if .sidebarPresent}}
@ -82,7 +82,7 @@
<a class="gt-float-right muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> <a class="gt-float-right muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a>
{{end}} {{end}}
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .sidebarEscapeStatus "root" $}} {{template "repo/unicode_escape_prompt" dict "EscapeStatus" .sidebarEscapeStatus "root" $}}
{{.sidebarContent | Safe}} {{.sidebarContent | SafeHTML}}
</div> </div>
{{end}} {{end}}
@ -94,7 +94,7 @@
<a class="gt-float-right muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> <a class="gt-float-right muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a>
{{end}} {{end}}
{{template "repo/unicode_escape_prompt" dict "footerEscapeStatus" .sidebarEscapeStatus "root" $}} {{template "repo/unicode_escape_prompt" dict "footerEscapeStatus" .sidebarEscapeStatus "root" $}}
{{.footerContent | Safe}} {{.footerContent | SafeHTML}}
</div> </div>
{{end}} {{end}}
</div> </div>

View File

@ -75,7 +75,7 @@
{{ctx.Locale.Tr "settings.select_permissions"}} {{ctx.Locale.Tr "settings.select_permissions"}}
</summary> </summary>
<p class="activity meta"> <p class="activity meta">
<i>{{ctx.Locale.Tr "settings.access_token_desc" (printf `href="/api/swagger" target="_blank"`) (printf `href="https://docs.gitea.com/development/oauth2-provider#scopes" target="_blank"`)}}</i> <i>{{ctx.Locale.Tr "settings.access_token_desc" (`href="/api/swagger" target="_blank"`|SafeHTML) (`href="https://docs.gitea.com/development/oauth2-provider#scopes" target="_blank"`|SafeHTML)}}</i>
</p> </p>
<div class="scoped-access-token-mount"> <div class="scoped-access-token-mount">
<scoped-access-token-selector <scoped-access-token-selector

View File

@ -47,7 +47,7 @@
{{ctx.Locale.Tr "org.members.leave"}} {{ctx.Locale.Tr "org.members.leave"}}
</div> </div>
<div class="content"> <div class="content">
<p>{{ctx.Locale.Tr "org.members.leave.detail" (`<span class="dataOrganizationName"></span>`|Safe)}}</p> <p>{{ctx.Locale.Tr "org.members.leave.detail" (`<span class="dataOrganizationName"></span>`|SafeHTML)}}</p>
</div> </div>
{{template "base/modal_actions_confirm" .}} {{template "base/modal_actions_confirm" .}}
</div> </div>