@@ -31,6 +31,7 @@ import (
31
31
repo_model "code.gitea.io/gitea/models/repo"
32
32
user_model "code.gitea.io/gitea/models/user"
33
33
"code.gitea.io/gitea/modules/base"
34
+ "code.gitea.io/gitea/modules/charset"
34
35
"code.gitea.io/gitea/modules/emoji"
35
36
"code.gitea.io/gitea/modules/git"
36
37
giturl "code.gitea.io/gitea/modules/git/url"
@@ -42,6 +43,7 @@ import (
42
43
"code.gitea.io/gitea/modules/setting"
43
44
"code.gitea.io/gitea/modules/svg"
44
45
"code.gitea.io/gitea/modules/timeutil"
46
+ "code.gitea.io/gitea/modules/translation"
45
47
"code.gitea.io/gitea/modules/util"
46
48
"code.gitea.io/gitea/services/gitdiff"
47
49
@@ -343,12 +345,15 @@ func NewFuncMap() []template.FuncMap {
343
345
}
344
346
return false
345
347
},
346
- "svg" : SVG ,
347
- "avatar" : Avatar ,
348
- "avatarHTML" : AvatarHTML ,
349
- "avatarByAction" : AvatarByAction ,
350
- "avatarByEmail" : AvatarByEmail ,
351
- "repoAvatar" : RepoAvatar ,
348
+ "svg" : SVG ,
349
+ "avatar" : Avatar ,
350
+ "avatarHTML" : AvatarHTML ,
351
+ "avatarByAction" : AvatarByAction ,
352
+ "avatarByEmail" : AvatarByEmail ,
353
+ "escapeAmbiguous" : EscapeAmbiguous ,
354
+ "escapeAmbiguousHTML" : EscapeAmbiguousHTML ,
355
+ "escapeAmbiguousLink" : EscapeAmbiguousLink ,
356
+ "repoAvatar" : RepoAvatar ,
352
357
"SortArrow" : func (normSort , revSort , urlSort string , isDefault bool ) template.HTML {
353
358
// if needed
354
359
if len (normSort ) == 0 || len (urlSort ) == 0 {
@@ -680,6 +685,67 @@ func AvatarByEmail(email, name string, others ...interface{}) template.HTML {
680
685
return template .HTML ("" )
681
686
}
682
687
688
+ // EscapeAmbiguous
689
+ func EscapeAmbiguous (locale translation.Locale , text string ) template.HTML {
690
+ sb := & strings.Builder {}
691
+ status , _ := charset .EscapeControlStringWriter (text , sb , locale )
692
+ escapeStatusSwitch (locale , sb , status )
693
+
694
+ return template .HTML (sb .String ())
695
+ }
696
+
697
+ // EscapeAmbiguousHTML
698
+ func EscapeAmbiguousHTML (locale translation.Locale , html string ) template.HTML {
699
+ sb := & strings.Builder {}
700
+ status , _ := charset .EscapeControlHTMLReader (strings .NewReader (html ), sb , locale )
701
+ escapeStatusSwitch (locale , sb , status )
702
+ return template .HTML (sb .String ())
703
+ }
704
+
705
+ // EscapeAmbiguousLink takes a locale, text body - which is assumed to be a string not html, href and other attributes
706
+ func EscapeAmbiguousLink (locale translation.Locale , text , href string , attrs ... string ) template.HTML {
707
+ sb := & strings.Builder {}
708
+ _ , _ = sb .WriteString (`<a href="` )
709
+ template .HTMLEscape (sb , []byte (href ))
710
+ _ , _ = sb .WriteString (`"` )
711
+ attrValue := false
712
+ for _ , attr := range attrs {
713
+ if attrValue {
714
+ _ , _ = sb .WriteString (`="` )
715
+ } else {
716
+ _ , _ = sb .WriteString (` ` )
717
+ }
718
+ template .HTMLEscape (sb , []byte (attr ))
719
+ if attrValue {
720
+ _ , _ = sb .WriteString (`"` )
721
+ }
722
+ attrValue = ! attrValue
723
+ }
724
+ _ , _ = sb .WriteString (`>` )
725
+ status , _ := charset .EscapeControlStringWriter (text , sb , locale )
726
+ _ , _ = sb .WriteString (`</a>` )
727
+
728
+ escapeStatusSwitch (locale , sb , status )
729
+ return template .HTML (sb .String ())
730
+ }
731
+
732
+ func escapeStatusSwitch (locale translation.Locale , sb * strings.Builder , status * charset.EscapeStatus ) {
733
+ if status .Escaped {
734
+ _ , _ = sb .WriteString (`<a href="" class="toggle-escape-button" title="` )
735
+ if status .HasInvisible {
736
+ _ , _ = sb .WriteString (locale .Tr ("invisible_runes" ))
737
+ }
738
+ if status .HasInvisible && status .HasAmbiguous {
739
+ _ , _ = sb .WriteString (` ` )
740
+ }
741
+ if status .HasAmbiguous {
742
+ _ , _ = sb .WriteString (locale .Tr ("ambiguous_runes" ))
743
+ }
744
+
745
+ _ , _ = sb .WriteString (`"></a>` )
746
+ }
747
+ }
748
+
683
749
// Safe render raw as HTML
684
750
func Safe (raw string ) template.HTML {
685
751
return template .HTML (raw )
@@ -711,13 +777,13 @@ func DotEscape(raw string) string {
711
777
}
712
778
713
779
// RenderCommitMessage renders commit message with XSS-safe and special links.
714
- func RenderCommitMessage (ctx context.Context , msg , urlPrefix string , metas map [string ]string ) template.HTML {
715
- return RenderCommitMessageLink (ctx , msg , urlPrefix , "" , metas )
780
+ func RenderCommitMessage (ctx context.Context , locale translation. Locale , msg , urlPrefix string , metas map [string ]string ) template.HTML {
781
+ return RenderCommitMessageLink (ctx , locale , msg , urlPrefix , "" , metas )
716
782
}
717
783
718
784
// RenderCommitMessageLink renders commit message as a XXS-safe link to the provided
719
785
// default url, handling for special links.
720
- func RenderCommitMessageLink (ctx context.Context , msg , urlPrefix , urlDefault string , metas map [string ]string ) template.HTML {
786
+ func RenderCommitMessageLink (ctx context.Context , locale translation. Locale , msg , urlPrefix , urlDefault string , metas map [string ]string ) template.HTML {
721
787
cleanMsg := template .HTMLEscapeString (msg )
722
788
// we can safely assume that it will not return any error, since there
723
789
// shouldn't be any special HTML.
@@ -731,16 +797,17 @@ func RenderCommitMessageLink(ctx context.Context, msg, urlPrefix, urlDefault str
731
797
log .Error ("RenderCommitMessage: %v" , err )
732
798
return ""
733
799
}
734
- msgLines := strings .Split (strings .TrimSpace (fullMessage ), "\n " )
800
+ msgLines := strings .SplitN (strings .TrimSpace (fullMessage ), "\n " , 2 )
735
801
if len (msgLines ) == 0 {
736
802
return template .HTML ("" )
737
803
}
738
- return template .HTML (msgLines [0 ])
804
+ _ , renderedMessage := charset .EscapeControlHTML (msgLines [0 ], locale )
805
+ return template .HTML (renderedMessage )
739
806
}
740
807
741
808
// RenderCommitMessageLinkSubject renders commit message as a XXS-safe link to
742
809
// the provided default url, handling for special links without email to links.
743
- func RenderCommitMessageLinkSubject (ctx context.Context , msg , urlPrefix , urlDefault string , metas map [string ]string ) template.HTML {
810
+ func RenderCommitMessageLinkSubject (ctx context.Context , locale translation. Locale , msg , urlPrefix , urlDefault string , metas map [string ]string ) template.HTML {
744
811
msgLine := strings .TrimLeftFunc (msg , unicode .IsSpace )
745
812
lineEnd := strings .IndexByte (msgLine , '\n' )
746
813
if lineEnd > 0 {
@@ -763,11 +830,12 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlPrefix, urlDefa
763
830
log .Error ("RenderCommitMessageSubject: %v" , err )
764
831
return template .HTML ("" )
765
832
}
833
+ _ , renderedMessage = charset .EscapeControlHTML (renderedMessage , locale )
766
834
return template .HTML (renderedMessage )
767
835
}
768
836
769
837
// RenderCommitBody extracts the body of a commit message without its title.
770
- func RenderCommitBody (ctx context.Context , msg , urlPrefix string , metas map [string ]string ) template.HTML {
838
+ func RenderCommitBody (ctx context.Context , locale translation. Locale , msg , urlPrefix string , metas map [string ]string ) template.HTML {
771
839
msgLine := strings .TrimRightFunc (msg , unicode .IsSpace )
772
840
lineEnd := strings .IndexByte (msgLine , '\n' )
773
841
if lineEnd > 0 {
@@ -789,11 +857,12 @@ func RenderCommitBody(ctx context.Context, msg, urlPrefix string, metas map[stri
789
857
log .Error ("RenderCommitMessage: %v" , err )
790
858
return ""
791
859
}
860
+ _ , renderedMessage = charset .EscapeControlHTML (renderedMessage , locale )
792
861
return template .HTML (renderedMessage )
793
862
}
794
863
795
864
// RenderIssueTitle renders issue/pull title with defined post processors
796
- func RenderIssueTitle (ctx context.Context , text , urlPrefix string , metas map [string ]string ) template.HTML {
865
+ func RenderIssueTitle (ctx context.Context , locale translation. Locale , text , urlPrefix string , metas map [string ]string ) template.HTML {
797
866
renderedText , err := markup .RenderIssueTitle (& markup.RenderContext {
798
867
Ctx : ctx ,
799
868
URLPrefix : urlPrefix ,
@@ -803,6 +872,7 @@ func RenderIssueTitle(ctx context.Context, text, urlPrefix string, metas map[str
803
872
log .Error ("RenderIssueTitle: %v" , err )
804
873
return template .HTML ("" )
805
874
}
875
+ _ , renderedText = charset .EscapeControlHTML (renderedText , locale )
806
876
return template .HTML (renderedText )
807
877
}
808
878
@@ -830,7 +900,7 @@ func ReactionToEmoji(reaction string) template.HTML {
830
900
}
831
901
832
902
// RenderNote renders the contents of a git-notes file as a commit message.
833
- func RenderNote (ctx context.Context , msg , urlPrefix string , metas map [string ]string ) template.HTML {
903
+ func RenderNote (ctx context.Context , locale translation. Locale , msg , urlPrefix string , metas map [string ]string ) template.HTML {
834
904
cleanMsg := template .HTMLEscapeString (msg )
835
905
fullMessage , err := markup .RenderCommitMessage (& markup.RenderContext {
836
906
Ctx : ctx ,
@@ -841,6 +911,8 @@ func RenderNote(ctx context.Context, msg, urlPrefix string, metas map[string]str
841
911
log .Error ("RenderNote: %v" , err )
842
912
return ""
843
913
}
914
+ _ , fullMessage = charset .EscapeControlHTML (fullMessage , locale )
915
+
844
916
return template .HTML (fullMessage )
845
917
}
846
918
0 commit comments