mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Fix diff path unquoting (#12554)
* Fix diff path unquoting services/gitdiff/gitdiff.go whereby there it assumed that the path would always be quoted on both sides This PR simplifies the code here and uses fmt.Fscanf to parse the strings as necessary. Fix #12546 Signed-off-by: Andrew Thornton <art27@cantab.net> * Add testcase as per @mrsdizzie Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
		| @@ -18,7 +18,6 @@ import ( | |||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strconv" |  | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| @@ -570,40 +569,28 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D | |||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var middle int |  | ||||||
|  |  | ||||||
| 			// Note: In case file name is surrounded by double quotes (it happens only in git-shell). | 			// Note: In case file name is surrounded by double quotes (it happens only in git-shell). | ||||||
| 			// e.g. diff --git "a/xxx" "b/xxx" | 			// e.g. diff --git "a/xxx" "b/xxx" | ||||||
| 			hasQuote := line[len(cmdDiffHead)] == '"' | 			var a string | ||||||
| 			if hasQuote { | 			var b string | ||||||
| 				middle = strings.Index(line, ` "b/`) |  | ||||||
|  | 			rd := strings.NewReader(line[len(cmdDiffHead):]) | ||||||
|  | 			char, _ := rd.ReadByte() | ||||||
|  | 			_ = rd.UnreadByte() | ||||||
|  | 			if char == '"' { | ||||||
|  | 				fmt.Fscanf(rd, "%q ", &a) | ||||||
| 			} else { | 			} else { | ||||||
| 				middle = strings.Index(line, " b/") | 				fmt.Fscanf(rd, "%s ", &a) | ||||||
| 			} | 			} | ||||||
|  | 			char, _ = rd.ReadByte() | ||||||
| 			beg := len(cmdDiffHead) | 			_ = rd.UnreadByte() | ||||||
| 			a := line[beg+2 : middle] | 			if char == '"' { | ||||||
| 			b := line[middle+3:] | 				fmt.Fscanf(rd, "%q", &b) | ||||||
|  | 			} else { | ||||||
| 			if hasQuote { | 				fmt.Fscanf(rd, "%s", &b) | ||||||
| 				// Keep the entire string in double quotes for now |  | ||||||
| 				a = line[beg:middle] |  | ||||||
| 				b = line[middle+1:] |  | ||||||
|  |  | ||||||
| 				var err error |  | ||||||
| 				a, err = strconv.Unquote(a) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, fmt.Errorf("Unquote: %v", err) |  | ||||||
| 				} |  | ||||||
| 				b, err = strconv.Unquote(b) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, fmt.Errorf("Unquote: %v", err) |  | ||||||
| 				} |  | ||||||
| 				// Now remove the /a /b |  | ||||||
| 				a = a[2:] |  | ||||||
| 				b = b[2:] |  | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
|  | 			a = a[2:] | ||||||
|  | 			b = b[2:] | ||||||
|  |  | ||||||
| 			curFile = &DiffFile{ | 			curFile = &DiffFile{ | ||||||
| 				Name:      b, | 				Name:      b, | ||||||
|   | |||||||
| @@ -112,6 +112,23 @@ func TestParsePatch(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	println(result) | 	println(result) | ||||||
|  |  | ||||||
|  | 	var diff2a = `diff --git "a/A \\ B" b/A/B | ||||||
|  | --- "a/A \\ B" | ||||||
|  | +++ b/A/B | ||||||
|  | @@ -1,3 +1,6 @@ | ||||||
|  |  # gitea-github-migrator | ||||||
|  | + | ||||||
|  | + Build Status | ||||||
|  | - Latest Release | ||||||
|  |  Docker Pulls | ||||||
|  | + cut off | ||||||
|  | + cut off` | ||||||
|  | 	result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Errorf("ParsePatch failed: %s", err) | ||||||
|  | 	} | ||||||
|  | 	println(result) | ||||||
|  |  | ||||||
| 	var diff3 = `diff --git a/README.md b/README.md | 	var diff3 = `diff --git a/README.md b/README.md | ||||||
| --- a/README.md | --- a/README.md | ||||||
| +++ b/README.md | +++ b/README.md | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user