mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 14:01:02 +00:00 
			
		
		
		
	- The ambiguous character detection is an important security feature to combat against sourcebase attacks (https://trojansource.codes/). - However there are a few problems with the feature as it stands today (i) it's apparantly an big performance hitter, it's twice as slow as syntax highlighting (ii) it contains false positives, because it's reporting valid problems but not valid within the context of a programming language (ambiguous charachters in code comments being a prime example) that can lead to security issues (iii) charachters from certain languages always being marked as ambiguous. It's a lot of effort to fix the aforementioned issues. - Therefore, make it configurable in which context the ambiguous character detection should be run, this avoids running detection in all contexts such as file views, but still enable it in commits and pull requests diffs where it matters the most. Ideally this also becomes an per-repository setting, but the code architecture doesn't allow for a clean implementation of that. - Adds unit test. - Adds integration tests to ensure that the contexts and instance-wide is respected (and that ambigious charachter detection actually work in different places). - Ref: https://codeberg.org/forgejo/forgejo/pulls/2395#issuecomment-1575547 - Ref: https://codeberg.org/forgejo/forgejo/issues/564
		
			
				
	
	
		
			166 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2023 The Gitea Authors. All rights reserved.
 | ||
| // SPDX-License-Identifier: MIT
 | ||
| 
 | ||
| package setting
 | ||
| 
 | ||
| import (
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"code.gitea.io/gitea/modules/container"
 | ||
| 	"code.gitea.io/gitea/modules/log"
 | ||
| )
 | ||
| 
 | ||
| // UI settings
 | ||
| var UI = struct {
 | ||
| 	ExplorePagingNum        int
 | ||
| 	SitemapPagingNum        int
 | ||
| 	IssuePagingNum          int
 | ||
| 	RepoSearchPagingNum     int
 | ||
| 	MembersPagingNum        int
 | ||
| 	FeedMaxCommitNum        int
 | ||
| 	FeedPagingNum           int
 | ||
| 	PackagesPagingNum       int
 | ||
| 	GraphMaxCommitNum       int
 | ||
| 	CodeCommentLines        int
 | ||
| 	ReactionMaxUserNum      int
 | ||
| 	MaxDisplayFileSize      int64
 | ||
| 	ShowUserEmail           bool
 | ||
| 	DefaultShowFullName     bool
 | ||
| 	DefaultTheme            string
 | ||
| 	Themes                  []string
 | ||
| 	Reactions               []string
 | ||
| 	ReactionsLookup         container.Set[string] `ini:"-"`
 | ||
| 	CustomEmojis            []string
 | ||
| 	CustomEmojisMap         map[string]string `ini:"-"`
 | ||
| 	SearchRepoDescription   bool
 | ||
| 	OnlyShowRelevantRepos   bool
 | ||
| 	ExploreDefaultSort      string `ini:"EXPLORE_PAGING_DEFAULT_SORT"`
 | ||
| 	PreferredTimestampTense string
 | ||
| 
 | ||
| 	AmbiguousUnicodeDetection bool
 | ||
| 	SkipEscapeContexts        []string
 | ||
| 
 | ||
| 	Notification struct {
 | ||
| 		MinTimeout            time.Duration
 | ||
| 		TimeoutStep           time.Duration
 | ||
| 		MaxTimeout            time.Duration
 | ||
| 		EventSourceUpdateTime time.Duration
 | ||
| 	} `ini:"ui.notification"`
 | ||
| 
 | ||
| 	SVG struct {
 | ||
| 		Enabled bool `ini:"ENABLE_RENDER"`
 | ||
| 	} `ini:"ui.svg"`
 | ||
| 
 | ||
| 	CSV struct {
 | ||
| 		MaxFileSize int64
 | ||
| 	} `ini:"ui.csv"`
 | ||
| 
 | ||
| 	Admin struct {
 | ||
| 		UserPagingNum   int
 | ||
| 		RepoPagingNum   int
 | ||
| 		NoticePagingNum int
 | ||
| 		OrgPagingNum    int
 | ||
| 	} `ini:"ui.admin"`
 | ||
| 	User struct {
 | ||
| 		RepoPagingNum int
 | ||
| 	} `ini:"ui.user"`
 | ||
| 	Meta struct {
 | ||
| 		Author      string
 | ||
| 		Description string
 | ||
| 		Keywords    string
 | ||
| 	} `ini:"ui.meta"`
 | ||
| }{
 | ||
| 	ExplorePagingNum:        20,
 | ||
| 	SitemapPagingNum:        20,
 | ||
| 	IssuePagingNum:          20,
 | ||
| 	RepoSearchPagingNum:     20,
 | ||
| 	MembersPagingNum:        20,
 | ||
| 	FeedMaxCommitNum:        5,
 | ||
| 	FeedPagingNum:           20,
 | ||
| 	PackagesPagingNum:       20,
 | ||
| 	GraphMaxCommitNum:       100,
 | ||
| 	CodeCommentLines:        4,
 | ||
| 	ReactionMaxUserNum:      10,
 | ||
| 	MaxDisplayFileSize:      8388608,
 | ||
| 	DefaultTheme:            `forgejo-auto`,
 | ||
| 	Themes:                  []string{`forgejo-auto`, `forgejo-light`, `forgejo-dark`, `gitea-auto`, `gitea-light`, `gitea-dark`, `forgejo-auto-deuteranopia-protanopia`, `forgejo-light-deuteranopia-protanopia`, `forgejo-dark-deuteranopia-protanopia`, `forgejo-auto-tritanopia`, `forgejo-light-tritanopia`, `forgejo-dark-tritanopia`},
 | ||
| 	Reactions:               []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`},
 | ||
| 	CustomEmojis:            []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`, `forgejo`},
 | ||
| 	CustomEmojisMap:         map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:", "forgejo": ":forgejo:"},
 | ||
| 	PreferredTimestampTense: "mixed",
 | ||
| 
 | ||
| 	AmbiguousUnicodeDetection: true,
 | ||
| 	SkipEscapeContexts:        []string{},
 | ||
| 
 | ||
| 	Notification: struct {
 | ||
| 		MinTimeout            time.Duration
 | ||
| 		TimeoutStep           time.Duration
 | ||
| 		MaxTimeout            time.Duration
 | ||
| 		EventSourceUpdateTime time.Duration
 | ||
| 	}{
 | ||
| 		MinTimeout:            10 * time.Second,
 | ||
| 		TimeoutStep:           10 * time.Second,
 | ||
| 		MaxTimeout:            60 * time.Second,
 | ||
| 		EventSourceUpdateTime: 10 * time.Second,
 | ||
| 	},
 | ||
| 	SVG: struct {
 | ||
| 		Enabled bool `ini:"ENABLE_RENDER"`
 | ||
| 	}{
 | ||
| 		Enabled: true,
 | ||
| 	},
 | ||
| 	CSV: struct {
 | ||
| 		MaxFileSize int64
 | ||
| 	}{
 | ||
| 		MaxFileSize: 524288,
 | ||
| 	},
 | ||
| 	Admin: struct {
 | ||
| 		UserPagingNum   int
 | ||
| 		RepoPagingNum   int
 | ||
| 		NoticePagingNum int
 | ||
| 		OrgPagingNum    int
 | ||
| 	}{
 | ||
| 		UserPagingNum:   50,
 | ||
| 		RepoPagingNum:   50,
 | ||
| 		NoticePagingNum: 25,
 | ||
| 		OrgPagingNum:    50,
 | ||
| 	},
 | ||
| 	User: struct {
 | ||
| 		RepoPagingNum int
 | ||
| 	}{
 | ||
| 		RepoPagingNum: 15,
 | ||
| 	},
 | ||
| 	Meta: struct {
 | ||
| 		Author      string
 | ||
| 		Description string
 | ||
| 		Keywords    string
 | ||
| 	}{
 | ||
| 		Author:      "Forgejo – Beyond coding. We forge.",
 | ||
| 		Description: "Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.",
 | ||
| 		Keywords:    "git,forge,forgejo",
 | ||
| 	},
 | ||
| }
 | ||
| 
 | ||
| func loadUIFrom(rootCfg ConfigProvider) {
 | ||
| 	mustMapSetting(rootCfg, "ui", &UI)
 | ||
| 	sec := rootCfg.Section("ui")
 | ||
| 	UI.ShowUserEmail = sec.Key("SHOW_USER_EMAIL").MustBool(true)
 | ||
| 	UI.DefaultShowFullName = sec.Key("DEFAULT_SHOW_FULL_NAME").MustBool(false)
 | ||
| 	UI.SearchRepoDescription = sec.Key("SEARCH_REPO_DESCRIPTION").MustBool(true)
 | ||
| 
 | ||
| 	if UI.PreferredTimestampTense != "mixed" && UI.PreferredTimestampTense != "absolute" {
 | ||
| 		log.Fatal("ui.PREFERRED_TIMESTAMP_TENSE must be either 'mixed' or 'absolute'")
 | ||
| 	}
 | ||
| 
 | ||
| 	// OnlyShowRelevantRepos=false is important for many private/enterprise instances,
 | ||
| 	// because many private repositories do not have "description/topic", users just want to search by their names.
 | ||
| 	UI.OnlyShowRelevantRepos = sec.Key("ONLY_SHOW_RELEVANT_REPOS").MustBool(false)
 | ||
| 
 | ||
| 	UI.ReactionsLookup = make(container.Set[string])
 | ||
| 	for _, reaction := range UI.Reactions {
 | ||
| 		UI.ReactionsLookup.Add(reaction)
 | ||
| 	}
 | ||
| 	UI.CustomEmojisMap = make(map[string]string)
 | ||
| 	for _, emoji := range UI.CustomEmojis {
 | ||
| 		UI.CustomEmojisMap[emoji] = ":" + emoji + ":"
 | ||
| 	}
 | ||
| }
 |