Skip to content

Commit cc037ac

Browse files
author
Gusted
authored
Merge branch 'main' into improve-code-review-comment
2 parents 6d90d8f + 677af6a commit cc037ac

File tree

8 files changed

+99
-29
lines changed

8 files changed

+99
-29
lines changed

modules/git/command.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type Command struct {
4040
parentContext context.Context
4141
desc string
4242
globalArgsLength int
43+
brokenArgs []string
4344
}
4445

4546
func (c *Command) String() string {
@@ -50,6 +51,7 @@ func (c *Command) String() string {
5051
}
5152

5253
// NewCommand creates and returns a new Git Command based on given command and arguments.
54+
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
5355
func NewCommand(ctx context.Context, args ...string) *Command {
5456
// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it
5557
cargs := make([]string, len(globalCommandArgs))
@@ -63,11 +65,13 @@ func NewCommand(ctx context.Context, args ...string) *Command {
6365
}
6466

6567
// NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
68+
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
6669
func NewCommandNoGlobals(args ...string) *Command {
6770
return NewCommandContextNoGlobals(DefaultContext, args...)
6871
}
6972

7073
// NewCommandContextNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
74+
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
7175
func NewCommandContextNoGlobals(ctx context.Context, args ...string) *Command {
7276
return &Command{
7377
name: GitExecutable,
@@ -89,12 +93,28 @@ func (c *Command) SetDescription(desc string) *Command {
8993
return c
9094
}
9195

92-
// AddArguments adds new argument(s) to the command.
96+
// AddArguments adds new argument(s) to the command. Each argument must be safe to be trusted.
97+
// User-provided arguments should be passed to AddDynamicArguments instead.
9398
func (c *Command) AddArguments(args ...string) *Command {
9499
c.args = append(c.args, args...)
95100
return c
96101
}
97102

103+
// AddDynamicArguments adds new dynamic argument(s) to the command.
104+
// The arguments may come from user input and can not be trusted, so no leading '-' is allowed to avoid passing options
105+
func (c *Command) AddDynamicArguments(args ...string) *Command {
106+
for _, arg := range args {
107+
if arg != "" && arg[0] == '-' {
108+
c.brokenArgs = append(c.brokenArgs, arg)
109+
}
110+
}
111+
if len(c.brokenArgs) != 0 {
112+
return c
113+
}
114+
c.args = append(c.args, args...)
115+
return c
116+
}
117+
98118
// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
99119
type RunOpts struct {
100120
Env []string
@@ -138,8 +158,14 @@ func CommonCmdServEnvs() []string {
138158
return commonBaseEnvs()
139159
}
140160

161+
var ErrBrokenCommand = errors.New("git command is broken")
162+
141163
// Run runs the command with the RunOpts
142164
func (c *Command) Run(opts *RunOpts) error {
165+
if len(c.brokenArgs) != 0 {
166+
log.Error("git command is broken: %s, broken args: %s", c.String(), strings.Join(c.brokenArgs, " "))
167+
return ErrBrokenCommand
168+
}
143169
if opts == nil {
144170
opts = &RunOpts{}
145171
}

modules/git/command_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,19 @@ func TestRunWithContextStd(t *testing.T) {
2626
assert.Contains(t, err.Error(), "exit status 129 - unknown option:")
2727
assert.Empty(t, stdout)
2828
}
29+
30+
cmd = NewCommand(context.Background())
31+
cmd.AddDynamicArguments("-test")
32+
assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
33+
34+
cmd = NewCommand(context.Background())
35+
cmd.AddDynamicArguments("--test")
36+
assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
37+
38+
subCmd := "version"
39+
cmd = NewCommand(context.Background()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
40+
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
41+
assert.NoError(t, err)
42+
assert.Empty(t, stderr)
43+
assert.Contains(t, stdout, "git version")
2944
}

modules/git/commit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file
166166
// CommitsCountFiles returns number of total commits of until given revision.
167167
func CommitsCountFiles(ctx context.Context, repoPath string, revision, relpath []string) (int64, error) {
168168
cmd := NewCommand(ctx, "rev-list", "--count")
169-
cmd.AddArguments(revision...)
169+
cmd.AddDynamicArguments(revision...)
170170
if len(relpath) > 0 {
171171
cmd.AddArguments("--")
172172
cmd.AddArguments(relpath...)

modules/git/repo_commit.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co
161161
// add previous arguments except for --grep and --all
162162
hashCmd.AddArguments(args...)
163163
// add keyword as <commit>
164-
hashCmd.AddArguments(v)
164+
hashCmd.AddDynamicArguments(v)
165165

166166
// search with given constraints for commit matching sha hash of v
167167
hashMatching, _, err := hashCmd.RunStdBytes(&RunOpts{Dir: repo.Path})
@@ -211,14 +211,17 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
211211
}()
212212
go func() {
213213
stderr := strings.Builder{}
214-
err := NewCommand(repo.Ctx, "rev-list", revision,
214+
gitCmd := NewCommand(repo.Ctx, "rev-list",
215215
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
216-
"--skip="+strconv.Itoa(skip), "--", file).
217-
Run(&RunOpts{
218-
Dir: repo.Path,
219-
Stdout: stdoutWriter,
220-
Stderr: &stderr,
221-
})
216+
"--skip="+strconv.Itoa(skip),
217+
)
218+
gitCmd.AddDynamicArguments(revision)
219+
gitCmd.AddArguments("--", file)
220+
err := gitCmd.Run(&RunOpts{
221+
Dir: repo.Path,
222+
Stdout: stdoutWriter,
223+
Stderr: &stderr,
224+
})
222225
if err != nil {
223226
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
224227
} else {

modules/git/repo_stats.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
6161
_ = stdoutWriter.Close()
6262
}()
6363

64-
args := []string{"log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso", fmt.Sprintf("--since='%s'", since)}
64+
gitCmd := NewCommand(repo.Ctx, "log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso", fmt.Sprintf("--since='%s'", since))
6565
if len(branch) == 0 {
66-
args = append(args, "--branches=*")
66+
gitCmd.AddArguments("--branches=*")
6767
} else {
68-
args = append(args, "--first-parent", branch)
68+
gitCmd.AddArguments("--first-parent").AddDynamicArguments(branch)
6969
}
7070

7171
stderr := new(strings.Builder)
72-
err = NewCommand(repo.Ctx, args...).Run(&RunOpts{
72+
err = gitCmd.Run(&RunOpts{
7373
Env: []string{},
7474
Dir: repo.Path,
7575
Stdout: stdoutWriter,

modules/gitgraph/graph.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,35 +24,30 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo
2424
page = 1
2525
}
2626

27-
args := make([]string, 0, 12+len(branches)+len(files))
28-
29-
args = append(args, "--graph", "--date-order", "--decorate=full")
27+
graphCmd := git.NewCommand(r.Ctx, "log", "--graph", "--date-order", "--decorate=full")
3028

3129
if hidePRRefs {
32-
args = append(args, "--exclude="+git.PullPrefix+"*")
30+
graphCmd.AddArguments("--exclude=" + git.PullPrefix + "*")
3331
}
3432

3533
if len(branches) == 0 {
36-
args = append(args, "--all")
34+
graphCmd.AddArguments("--all")
3735
}
3836

39-
args = append(args,
37+
graphCmd.AddArguments(
4038
"-C",
4139
"-M",
4240
fmt.Sprintf("-n %d", setting.UI.GraphMaxCommitNum*page),
4341
"--date=iso",
4442
fmt.Sprintf("--pretty=format:%s", format))
4543

4644
if len(branches) > 0 {
47-
args = append(args, branches...)
45+
graphCmd.AddDynamicArguments(branches...)
4846
}
49-
args = append(args, "--")
5047
if len(files) > 0 {
51-
args = append(args, files...)
48+
graphCmd.AddArguments("--")
49+
graphCmd.AddArguments(files...)
5250
}
53-
54-
graphCmd := git.NewCommand(r.Ctx, "log")
55-
graphCmd.AddArguments(args...)
5651
graph := NewGraph()
5752

5853
stderr := new(strings.Builder)

options/locale/locale_tr-TR.ini

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,11 @@ users=Kullanıcılar
268268
organizations=Organizasyonlar
269269
search=Ara
270270
code=Kod
271+
search.type.tooltip=Arama türü
271272
search.fuzzy=Belirsiz
273+
search.fuzzy.tooltip=Arama terimine benzeyen sonuçları da içer
272274
search.match=Eşleştir
275+
search.match.tooltip=Sadece arama terimiyle tamamen eşleşen sonuçları içer
273276
code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticinizle bağlantıya geçin.
274277
repo_no_results=Eşleşen bir depo bulunamadı.
275278
user_no_results=Eşleşen kullanıcı bulunamadı.
@@ -507,6 +510,7 @@ activity=Genel Aktivite
507510
followers=Takipçiler
508511
starred=Yıldızlanmış depolar
509512
watched=İzlenen Depolar
513+
code=Kod
510514
projects=Projeler
511515
following=Takip Edilenler
512516
follow=Takip Et
@@ -1763,8 +1767,11 @@ activity.git_stats_deletion_n=%d silme oldu
17631767
17641768
search=Ara
17651769
search.search_repo=Depo ara
1770+
search.type.tooltip=Arama türü
17661771
search.fuzzy=Belirsiz
1772+
search.fuzzy.tooltip=Arama terimine benzeyen sonuçları da içer
17671773
search.match=Eşleştir
1774+
search.match.tooltip=Sadece arama terimiyle tamamen eşleşen sonuçları içer
17681775
search.results="%s" için <a href="%s">%s</a> içinde sonuçları ara
17691776
search.code_no_results=Arama teriminizle eşleşen bir kaynak kod bulunamadı.
17701777
search.code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
@@ -1898,6 +1905,7 @@ settings.confirm_delete=Depoyu Sil
18981905
settings.add_collaborator=Katkıcı Ekle
18991906
settings.add_collaborator_success=Katkıcı eklendi.
19001907
settings.add_collaborator_inactive_user=Etkin olmayan bir kullanıcı katkıcı olarak eklenemez.
1908+
settings.add_collaborator_owner=Bir sahip katkıcı olarak eklenemez.
19011909
settings.add_collaborator_duplicate=Katkıcı bu depoya zaten eklenmiş.
19021910
settings.delete_collaborator=Sil
19031911
settings.collaborator_deletion=Katkıcıyı Sil
@@ -2309,6 +2317,7 @@ create_org=Organizasyon Oluştur
23092317
repo_updated=Güncellendi
23102318
people=İnsanlar
23112319
teams=Takımlar
2320+
code=Kod
23122321
lower_members=üyeler
23132322
lower_repositories=depo
23142323
create_new_team=Yeni Takım
@@ -3033,6 +3042,9 @@ pin=Pin bildirimi
30333042
mark_as_read=Okundu olarak işaretle
30343043
mark_as_unread=Okunmadı olarak işaretle
30353044
mark_all_as_read=Tümünü okundu olarak işaretle
3045+
subscriptions=Abonelikler
3046+
watching=İzleniyor
3047+
no_subscriptions=Abonelik yok
30363048
30373049
[gpg]
30383050
default_key=Varsayılan anahtarla imzalanmış

options/locale/locale_zh-TW.ini

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,11 @@ users=使用者
268268
organizations=組織
269269
search=搜尋
270270
code=程式碼
271+
search.type.tooltip=搜尋類型
271272
search.fuzzy=模糊
273+
search.fuzzy.tooltip=包含近似關鍵字的結果
272274
search.match=符合
275+
search.match.tooltip=只包含完全符合關鍵字的結果
273276
code_search_unavailable=現在無法使用程式碼搜尋。請與網站管理員聯絡。
274277
repo_no_results=沒有找到符合的儲存庫。
275278
user_no_results=沒有找到符合的使用者。
@@ -505,6 +508,7 @@ activity=公開動態
505508
followers=追蹤者
506509
starred=已加星號
507510
watched=關注的儲存庫
511+
code=程式碼
508512
projects=專案
509513
following=追蹤中
510514
follow=追蹤
@@ -852,7 +856,7 @@ license_helper_desc=授權條款定義了他人使用您原始碼的允許和禁
852856
readme=讀我檔案
853857
readme_helper=選擇讀我檔案範本。
854858
readme_helper_desc=這是您能為專案撰寫完整描述的地方。
855-
auto_init=初始化儲存庫 (加入 .gitignore、授權條款和讀我檔案)
859+
auto_init=初始化儲存庫 (加入 .gitignore、授權條款、讀我檔案)
856860
trust_model_helper=選擇簽署驗證的信任模型。可用的選項:
857861
trust_model_helper_collaborator=協作者: 信任協作者的簽署
858862
trust_model_helper_committer=提交者: 信任與提交者相符的簽署
@@ -1134,7 +1138,7 @@ commits.commits=次程式碼提交
11341138
commits.no_commits=沒有共同的提交。「%s」和「%s」的歷史完全不同。
11351139
commits.nothing_to_compare=這些分支是相同的。
11361140
commits.search=搜尋提交歷史...
1137-
commits.search.tooltip=你可以用「author:」、「committer:」、「after:」「before:」作為關鍵詞的前綴,例如「revert author:Alice before:2019-04-01」。
1141+
commits.search.tooltip=你可以用「author:」、「committer:」、「after:」「before:」等作為關鍵字的前綴,例如: 「revert author:Alice before:2019-04-01」。
11381142
commits.find=搜尋
11391143
commits.search_all=所有分支
11401144
commits.author=作者
@@ -1229,6 +1233,8 @@ issues.new.add_reviewer_title=請求審核
12291233
issues.choose.get_started=開始
12301234
issues.choose.blank=預設
12311235
issues.choose.blank_about=從預設範本建立問題。
1236+
issues.choose.ignore_invalid_templates=已忽略無效的範本
1237+
issues.choose.invalid_templates=找到了 %v 個無效的範本
12321238
issues.no_ref=未指定分支或標籤
12331239
issues.create=建立問題
12341240
issues.new_label=新增標籤
@@ -1759,8 +1765,11 @@ activity.git_stats_deletion_n=刪除 %d 行
17591765

17601766
search=搜尋
17611767
search.search_repo=搜尋儲存庫
1768+
search.type.tooltip=搜尋類型
17621769
search.fuzzy=模糊
1770+
search.fuzzy.tooltip=包含近似關鍵字的結果
17631771
search.match=符合
1772+
search.match.tooltip=只包含完全符合關鍵字的結果
17641773
search.results=在 <a href="%s"> %s </a> 中搜尋 "%s" 的结果
17651774
search.code_no_results=找不到符合您關鍵字的原始碼。
17661775
search.code_search_unavailable=現在無法使用程式碼搜尋。請與網站管理員聯絡。
@@ -1893,7 +1902,8 @@ settings.update_settings_success=已更新儲存庫的設定。
18931902
settings.confirm_delete=刪除儲存庫
18941903
settings.add_collaborator=增加協作者
18951904
settings.add_collaborator_success=成功增加協作者!
1896-
settings.add_collaborator_inactive_user=無法加入未啟用的使用者為協作者。
1905+
settings.add_collaborator_inactive_user=無法將未啟用的使用者加入為協作者。
1906+
settings.add_collaborator_owner=無法將擁有者加入為協作者。
18971907
settings.add_collaborator_duplicate=此協作者早已被加入此儲存庫。
18981908
settings.delete_collaborator=移除
18991909
settings.collaborator_deletion=移除協作者
@@ -1952,6 +1962,8 @@ settings.event_delete=刪除
19521962
settings.event_delete_desc=刪除分支或標籤。
19531963
settings.event_fork=Fork
19541964
settings.event_fork_desc=儲存庫已被 fork。
1965+
settings.event_wiki=Uncyclo
1966+
settings.event_wiki_desc=建立、重新命名、編輯、刪除 Uncyclo 頁面。
19551967
settings.event_release=版本發布
19561968
settings.event_release_desc=在儲存庫中發布、更新或刪除版本。
19571969
settings.event_push=推送
@@ -2303,6 +2315,7 @@ create_org=建立組織
23032315
repo_updated=更新於
23042316
people=成員
23052317
teams=團隊
2318+
code=程式碼
23062319
lower_members=名成員
23072320
lower_repositories=個儲存庫
23082321
create_new_team=建立團隊
@@ -3027,6 +3040,9 @@ pin=固定通知
30273040
mark_as_read=標記為已讀
30283041
mark_as_unread=標記為未讀
30293042
mark_all_as_read=標記所有為已讀
3043+
subscriptions=訂閱
3044+
watching=正在關注
3045+
no_subscriptions=沒有訂閱
30303046

30313047
[gpg]
30323048
default_key=使用預設金鑰簽署
@@ -3086,6 +3102,7 @@ container.details.platform=平台
30863102
container.details.repository_site=儲存庫網站
30873103
container.details.documentation_site=文件網站
30883104
container.pull=透過下列命令拉取映像檔:
3105+
container.digest=摘要:
30893106
container.documentation=關於 Container registry 的詳情請參閱<a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/container/">說明文件</a>。
30903107
container.multi_arch=作業系統 / 架構
30913108
container.layers=映像檔 Layers
@@ -3129,6 +3146,8 @@ rubygems.dependencies.development=開發相依性
31293146
rubygems.required.ruby=需要的 Ruby 版本
31303147
rubygems.required.rubygems=需要的 RubyGem 版本
31313148
rubygems.documentation=關於 RubyGems registry 的詳情請參閱<a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/rubygems/">說明文件</a>。
3149+
vagrant.install=執行下列命令以新增 Vagrant box:
3150+
vagrant.documentation=關於 Vagrant registry 的詳情請參閱<a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/vagrant/">說明文件</a>。
31323151
settings.link=連結此套件到儲存庫
31333152
settings.link.description=如果您將套件連結到儲存庫,該套件會顯示在儲存庫的套件清單。
31343153
settings.link.select=選擇儲存庫

0 commit comments

Comments
 (0)