2016-11-04 01:16:01 +03:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2020-01-23 02:46:46 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2016-11-04 01:16:01 +03:00
package git
import (
2020-08-28 09:55:12 +03:00
"context"
2016-11-04 01:16:01 +03:00
"fmt"
2021-06-24 00:12:38 +03:00
"io"
2024-01-19 08:49:18 +03:00
"os"
2016-11-04 01:16:01 +03:00
"path/filepath"
"strings"
)
2016-12-22 12:30:52 +03:00
// ArchiveType archive types
2016-11-04 01:16:01 +03:00
type ArchiveType int
const (
2016-12-22 12:30:52 +03:00
// ZIP zip archive type
2016-11-04 01:16:01 +03:00
ZIP ArchiveType = iota + 1
2016-12-22 12:30:52 +03:00
// TARGZ tar gz archive type
2016-11-04 01:16:01 +03:00
TARGZ
2021-08-24 19:47:09 +03:00
// BUNDLE bundle archive type
BUNDLE
2016-11-04 01:16:01 +03:00
)
2020-01-23 02:46:46 +03:00
// String converts an ArchiveType to string
func ( a ArchiveType ) String ( ) string {
switch a {
2016-11-04 01:16:01 +03:00
case ZIP :
2020-01-23 02:46:46 +03:00
return "zip"
2016-11-04 01:16:01 +03:00
case TARGZ :
2020-01-23 02:46:46 +03:00
return "tar.gz"
2021-08-24 19:47:09 +03:00
case BUNDLE :
return "bundle"
2016-11-04 01:16:01 +03:00
}
2020-01-23 02:46:46 +03:00
return "unknown"
}
2022-11-15 11:08:59 +03:00
func ToArchiveType ( s string ) ArchiveType {
switch s {
case "zip" :
return ZIP
case "tar.gz" :
return TARGZ
case "bundle" :
return BUNDLE
}
return 0
}
2020-01-23 02:46:46 +03:00
// CreateArchive create archive content to the target path
2021-06-24 00:12:38 +03:00
func ( repo * Repository ) CreateArchive ( ctx context . Context , format ArchiveType , target io . Writer , usePrefix bool , commitID string ) error {
if format . String ( ) == "unknown" {
return fmt . Errorf ( "unknown format: %v" , format )
2020-01-23 02:46:46 +03:00
}
2022-10-23 17:44:45 +03:00
cmd := NewCommand ( ctx , "archive" )
2021-06-24 00:12:38 +03:00
if usePrefix {
Refactor git command package to improve security and maintainability (#22678)
This PR follows #21535 (and replace #22592)
## Review without space diff
https://github.com/go-gitea/gitea/pull/22678/files?diff=split&w=1
## Purpose of this PR
1. Make git module command completely safe (risky user inputs won't be
passed as argument option anymore)
2. Avoid low-level mistakes like
https://github.com/go-gitea/gitea/pull/22098#discussion_r1045234918
3. Remove deprecated and dirty `CmdArgCheck` function, hide the `CmdArg`
type
4. Simplify code when using git command
## The main idea of this PR
* Move the `git.CmdArg` to the `internal` package, then no other package
except `git` could use it. Then developers could never do
`AddArguments(git.CmdArg(userInput))` any more.
* Introduce `git.ToTrustedCmdArgs`, it's for user-provided and already
trusted arguments. It's only used in a few cases, for example: use git
arguments from config file, help unit test with some arguments.
* Introduce `AddOptionValues` and `AddOptionFormat`, they make code more
clear and simple:
* Before: `AddArguments("-m").AddDynamicArguments(message)`
* After: `AddOptionValues("-m", message)`
* -
* Before: `AddArguments(git.CmdArg(fmt.Sprintf("--author='%s <%s>'",
sig.Name, sig.Email)))`
* After: `AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)`
## FAQ
### Why these changes were not done in #21535 ?
#21535 is mainly a search&replace, it did its best to not change too
much logic.
Making the framework better needs a lot of changes, so this separate PR
is needed as the second step.
### The naming of `AddOptionXxx`
According to git's manual, the `--xxx` part is called `option`.
### How can it guarantee that `internal.CmdArg` won't be not misused?
Go's specification guarantees that. Trying to access other package's
internal package causes compilation error.
And, `golangci-lint` also denies the git/internal package. Only the
`git/command.go` can use it carefully.
### There is still a `ToTrustedCmdArgs`, will it still allow developers
to make mistakes and pass untrusted arguments?
Generally speaking, no. Because when using `ToTrustedCmdArgs`, the code
will be very complex (see the changes for examples). Then developers and
reviewers can know that something might be unreasonable.
### Why there was a `CmdArgCheck` and why it's removed?
At the moment of #21535, to reduce unnecessary changes, `CmdArgCheck`
was introduced as a hacky patch. Now, almost all code could be written
as `cmd := NewCommand(); cmd.AddXxx(...)`, then there is no need for
`CmdArgCheck` anymore.
### Why many codes for `signArg == ""` is deleted?
Because in the old code, `signArg` could never be empty string, it's
either `-S[key-id]` or `--no-gpg-sign`. So the `signArg == ""` is just
dead code.
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-04 05:30:43 +03:00
cmd . AddOptionFormat ( "--prefix=%s" , filepath . Base ( strings . TrimSuffix ( repo . Path , ".git" ) ) + "/" )
2020-01-23 02:46:46 +03:00
}
Refactor git command package to improve security and maintainability (#22678)
This PR follows #21535 (and replace #22592)
## Review without space diff
https://github.com/go-gitea/gitea/pull/22678/files?diff=split&w=1
## Purpose of this PR
1. Make git module command completely safe (risky user inputs won't be
passed as argument option anymore)
2. Avoid low-level mistakes like
https://github.com/go-gitea/gitea/pull/22098#discussion_r1045234918
3. Remove deprecated and dirty `CmdArgCheck` function, hide the `CmdArg`
type
4. Simplify code when using git command
## The main idea of this PR
* Move the `git.CmdArg` to the `internal` package, then no other package
except `git` could use it. Then developers could never do
`AddArguments(git.CmdArg(userInput))` any more.
* Introduce `git.ToTrustedCmdArgs`, it's for user-provided and already
trusted arguments. It's only used in a few cases, for example: use git
arguments from config file, help unit test with some arguments.
* Introduce `AddOptionValues` and `AddOptionFormat`, they make code more
clear and simple:
* Before: `AddArguments("-m").AddDynamicArguments(message)`
* After: `AddOptionValues("-m", message)`
* -
* Before: `AddArguments(git.CmdArg(fmt.Sprintf("--author='%s <%s>'",
sig.Name, sig.Email)))`
* After: `AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)`
## FAQ
### Why these changes were not done in #21535 ?
#21535 is mainly a search&replace, it did its best to not change too
much logic.
Making the framework better needs a lot of changes, so this separate PR
is needed as the second step.
### The naming of `AddOptionXxx`
According to git's manual, the `--xxx` part is called `option`.
### How can it guarantee that `internal.CmdArg` won't be not misused?
Go's specification guarantees that. Trying to access other package's
internal package causes compilation error.
And, `golangci-lint` also denies the git/internal package. Only the
`git/command.go` can use it carefully.
### There is still a `ToTrustedCmdArgs`, will it still allow developers
to make mistakes and pass untrusted arguments?
Generally speaking, no. Because when using `ToTrustedCmdArgs`, the code
will be very complex (see the changes for examples). Then developers and
reviewers can know that something might be unreasonable.
### Why there was a `CmdArgCheck` and why it's removed?
At the moment of #21535, to reduce unnecessary changes, `CmdArgCheck`
was introduced as a hacky patch. Now, almost all code could be written
as `cmd := NewCommand(); cmd.AddXxx(...)`, then there is no need for
`CmdArgCheck` anymore.
### Why many codes for `signArg == ""` is deleted?
Because in the old code, `signArg` could never be empty string, it's
either `-S[key-id]` or `--no-gpg-sign`. So the `signArg == ""` is just
dead code.
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-04 05:30:43 +03:00
cmd . AddOptionFormat ( "--format=%s" , format . String ( ) )
2022-10-23 17:44:45 +03:00
cmd . AddDynamicArguments ( commitID )
2016-11-04 01:16:01 +03:00
2024-01-19 08:49:18 +03:00
// Avoid LFS hooks getting installed because of /etc/gitconfig, which can break pull requests.
env := append ( os . Environ ( ) , "GIT_CONFIG_NOSYSTEM=1" )
2021-06-24 00:12:38 +03:00
var stderr strings . Builder
2022-10-23 17:44:45 +03:00
err := cmd . Run ( & RunOpts {
2022-04-01 05:55:30 +03:00
Dir : repo . Path ,
Stdout : target ,
Stderr : & stderr ,
2024-01-19 08:49:18 +03:00
Env : env ,
2022-02-11 15:47:22 +03:00
} )
2021-06-24 00:12:38 +03:00
if err != nil {
return ConcatenateError ( err , stderr . String ( ) )
}
return nil
2016-11-04 01:16:01 +03:00
}