diff options
author | Ilya <ilux@cpan.org> | 2019-11-01 03:30:02 +0300 |
---|---|---|
committer | zeripath <art27@cantab.net> | 2019-11-01 00:30:02 +0000 |
commit | ac0fb36c417376f3967d0d98ae5066d8946c41c9 (patch) | |
tree | 8c9416a9961aaa7cd51cba5a6e3154c81ada1073 /services/pull/merge.go | |
parent | 4ee986e4c909641ce020f58f6803aed8b1559fcb (diff) | |
download | gitea-ac0fb36c417376f3967d0d98ae5066d8946c41c9.tar.gz gitea-ac0fb36c417376f3967d0d98ae5066d8946c41c9.zip |
Allow to merge if file path contains " or \ (#8629)
* if a filename in a repository contains " or \ the owner can't merge pull request with this files
because "git diff-tree" adds double quotes to that filepath
example: filepath is ab"cd but "git diff-tree" returns "ab\"cd"
now, when the owner click "Merge Pull Request" button the server returns 500
this commit fix it
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* add -z option to getDiffTree
escape spec symbols for sparse-checkout
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* go fmt
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* typo
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* escape '\'
escape all spaces and '!'
* use regexp.ReplaceAllString()
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* strings.ReplaceAll was added in go 1.12
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
* add '\' to regexp.MustCompile
Signed-off-by: Ilya Pavlov <ilux@cpan.org>
Diffstat (limited to 'services/pull/merge.go')
-rw-r--r-- | services/pull/merge.go | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/services/pull/merge.go b/services/pull/merge.go index 5eb8eaa4d4..2e093eef86 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -12,6 +12,7 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" "strings" "time" @@ -374,16 +375,31 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor return nil } +var escapedSymbols = regexp.MustCompile(`([*[?! \\])`) + func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) { getDiffTreeFromBranch := func(repoPath, baseBranch, headBranch string) (string, error) { var outbuf, errbuf strings.Builder // Compute the diff-tree for sparse-checkout - if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil { + if err := git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-z", "--root", baseBranch, headBranch, "--").RunInDirPipeline(repoPath, &outbuf, &errbuf); err != nil { return "", fmt.Errorf("git diff-tree [%s base:%s head:%s]: %s", repoPath, baseBranch, headBranch, errbuf.String()) } return outbuf.String(), nil } + scanNullTerminatedStrings := func(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.IndexByte(data, '\x00'); i >= 0 { + return i + 1, data[0:i], nil + } + if atEOF { + return len(data), data, nil + } + return 0, nil, nil + } + list, err := getDiffTreeFromBranch(repoPath, baseBranch, headBranch) if err != nil { return "", err @@ -392,8 +408,14 @@ func getDiffTree(repoPath, baseBranch, headBranch string) (string, error) { // Prefixing '/' for each entry, otherwise all files with the same name in subdirectories would be matched. out := bytes.Buffer{} scanner := bufio.NewScanner(strings.NewReader(list)) + scanner.Split(scanNullTerminatedStrings) for scanner.Scan() { - fmt.Fprintf(&out, "/%s\n", scanner.Text()) + filepath := scanner.Text() + // escape '*', '?', '[', spaces and '!' prefix + filepath = escapedSymbols.ReplaceAllString(filepath, `\$1`) + // no necessary to escape the first '#' symbol because the first symbol is '/' + fmt.Fprintf(&out, "/%s\n", filepath) } + return out.String(), nil } |