From ca4589169437a828281f374b29820ee0c1e3cf07 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Fri, 3 Mar 2023 22:28:38 +0000
Subject: [PATCH] Fix GetFilesChangedBetween if the file name may be escaped
 (#23272)

The code for GetFilesChangedBetween uses `git diff --name-only
base..head` to get the names of files changed between base and head
however this forgets that git will escape certain values.

This PR simply switches to use `-z` which has the `NUL` character as the
separator.

Ref https://github.com/go-gitea/gitea/pull/22568#discussion_r1123138096

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
---
 modules/git/repo_compare.go | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go
index 9a4d66f2f521b..439455e3c295c 100644
--- a/modules/git/repo_compare.go
+++ b/modules/git/repo_compare.go
@@ -277,11 +277,18 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
 
 // GetFilesChangedBetween returns a list of all files that have been changed between the given commits
 func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) {
-	stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path})
+	stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path})
 	if err != nil {
 		return nil, err
 	}
-	return strings.Split(stdout, "\n"), err
+	split := strings.Split(stdout, "\000")
+
+	// Because Git will always emit filenames with a terminal NUL ignore the last entry in the split - which will always be empty.
+	if len(split) > 0 {
+		split = split[:len(split)-1]
+	}
+
+	return split, err
 }
 
 // GetDiffFromMergeBase generates and return patch data from merge base to head