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:
		
							parent
							
								
									fcabbae168
								
							
						
					
					
						commit
						7a8a05cc44
					
				
					 2 changed files with 34 additions and 30 deletions
				
			
		|  | @ -18,7 +18,6 @@ import ( | |||
| 	"os/exec" | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
|  | @ -570,41 +569,29 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D | |||
| 				break | ||||
| 			} | ||||
| 
 | ||||
| 			var middle int | ||||
| 
 | ||||
| 			// Note: In case file name is surrounded by double quotes (it happens only in git-shell).
 | ||||
| 			// e.g. diff --git "a/xxx" "b/xxx"
 | ||||
| 			hasQuote := line[len(cmdDiffHead)] == '"' | ||||
| 			if hasQuote { | ||||
| 				middle = strings.Index(line, ` "b/`) | ||||
| 			var a string | ||||
| 			var b string | ||||
| 
 | ||||
| 			rd := strings.NewReader(line[len(cmdDiffHead):]) | ||||
| 			char, _ := rd.ReadByte() | ||||
| 			_ = rd.UnreadByte() | ||||
| 			if char == '"' { | ||||
| 				fmt.Fscanf(rd, "%q ", &a) | ||||
| 			} else { | ||||
| 				middle = strings.Index(line, " b/") | ||||
| 				fmt.Fscanf(rd, "%s ", &a) | ||||
| 			} | ||||
| 
 | ||||
| 			beg := len(cmdDiffHead) | ||||
| 			a := line[beg+2 : middle] | ||||
| 			b := line[middle+3:] | ||||
| 
 | ||||
| 			if hasQuote { | ||||
| 				// 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) | ||||
| 			char, _ = rd.ReadByte() | ||||
| 			_ = rd.UnreadByte() | ||||
| 			if char == '"' { | ||||
| 				fmt.Fscanf(rd, "%q", &b) | ||||
| 			} else { | ||||
| 				fmt.Fscanf(rd, "%s", &b) | ||||
| 			} | ||||
| 				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:] | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			curFile = &DiffFile{ | ||||
| 				Name:      b, | ||||
| 				OldName:   a, | ||||
|  |  | |||
|  | @ -112,6 +112,23 @@ func TestParsePatch(t *testing.T) { | |||
| 	} | ||||
| 	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 | ||||
| --- a/README.md | ||||
| +++ b/README.md | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue