mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 22:11:07 +00:00 
			
		
		
		
	This solution implements a new config variable MAX_ROWS, which corresponds to the “Maximum allowed rows to render CSV files. (0 for no limit)” and rewrites the Render function for CSV files in markup module. Now the render function only reads the file once, having MAX_FILE_SIZE+1 as a reader limit and MAX_ROWS as a row limit. When the file is larger than MAX_FILE_SIZE or has more rows than MAX_ROWS, it only renders until the limit, and displays a user-friendly warning informing that the rendered data is not complete, in the user's language. --- Previously, when a CSV file was larger than the limit, the render function lost its function to render the code. There were also multiple reads to the file, in order to determine its size and render or pre-render. The warning:  (cherry picked from commit f7125ab61aaa02fd4c7ab0062a2dc9a57726e2ec)
		
			
				
	
	
		
			169 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			169 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
 | ||
| 		MaxRows     int
 | ||
| 	} `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
 | ||
| 		MaxRows     int
 | ||
| 	}{
 | ||
| 		MaxFileSize: 524288,
 | ||
| 		MaxRows:     2500,
 | ||
| 	},
 | ||
| 	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 + ":"
 | ||
| 	}
 | ||
| }
 |