* 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
Showing the changes to services/gitdiff/gitdiff.go (1 of 2 files). Show all
Unified · Split
| @@ -18,7 +18,6 @@ import ( · 17 unmodified lines | ||
| 18 | 18 | "os/exec" |
| 19 | 19 | "regexp" |
| 20 | 20 | "sort" |
| 21 | − "strconv" | |
| 22 | 21 | "strings" |
| 23 | 22 | |
| 24 | 23 | "code.gitea.io/gitea/models" |
| @@ -570,40 +569,28 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D · 545 unmodified lines | ||
| 570 | 569 | break |
| 571 | 570 | } |
| 572 | 571 | |
| 573 | − var middle int | |
| 574 | − | |
| 575 | 572 | // Note: In case file name is surrounded by double quotes (it happens only in git-shell). |
| 576 | 573 | // e.g. diff --git "a/xxx" "b/xxx" |
| 577 | − hasQuote := line[len(cmdDiffHead)] == '"' | |
| 578 | − if hasQuote { | |
| 579 | − middle = strings.Index(line, ` "b/`) | |
| 574 | + var a string | |
| 575 | + var b string | |
| 576 | + | |
| 577 | + rd := strings.NewReader(line[len(cmdDiffHead):]) | |
| 578 | + char, _ := rd.ReadByte() | |
| 579 | + _ = rd.UnreadByte() | |
| 580 | + if char == '"' { | |
| 581 | + fmt.Fscanf(rd, "%q ", &a) | |
| 580 | 582 | } else { |
| 581 | − middle = strings.Index(line, " b/") | |
| 583 | + fmt.Fscanf(rd, "%s ", &a) | |
| 582 | 584 | } |
| 583 | − | |
| 584 | − beg := len(cmdDiffHead) | |
| 585 | − a := line[beg+2 : middle] | |
| 586 | − b := line[middle+3:] | |
| 587 | − | |
| 588 | − if hasQuote { | |
| 589 | − // Keep the entire string in double quotes for now | |
| 590 | − a = line[beg:middle] | |
| 591 | − b = line[middle+1:] | |
| 592 | − | |
| 593 | − var err error | |
| 594 | − a, err = strconv.Unquote(a) | |
| 595 | − if err != nil { | |
| 596 | − return nil, fmt.Errorf("Unquote: %v", err) | |
| 597 | − } | |
| 598 | − b, err = strconv.Unquote(b) | |
| 599 | − if err != nil { | |
| 600 | − return nil, fmt.Errorf("Unquote: %v", err) | |
| 601 | − } | |
| 602 | − // Now remove the /a /b | |
| 603 | − a = a[2:] | |
| 604 | − b = b[2:] | |
| 605 | − | |
| 585 | + char, _ = rd.ReadByte() | |
| 586 | + _ = rd.UnreadByte() | |
| 587 | + if char == '"' { | |
| 588 | + fmt.Fscanf(rd, "%q", &b) | |
| 589 | + } else { | |
| 590 | + fmt.Fscanf(rd, "%s", &b) | |
| 606 | 591 | } |
| 592 | + a = a[2:] | |
| 593 | + b = b[2:] | |
| 607 | 594 | |
| 608 | 595 | curFile = &DiffFile{ |
| 609 | 596 | Name: b, |