* 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 | "os/exec" | 18 | "os/exec" |
| 19 | "regexp" | 19 | "regexp" |
| 20 | "sort" | 20 | "sort" |
| 21 | "strconv" | ||
| 22 | "strings" | 21 | "strings" |
| 23 | 22 | ||
| 24 | "code.gitea.io/gitea/models" | 23 | "code.gitea.io/gitea/models" |
| @@ -570,40 +569,28 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D · 545 unmodified lines | |||
| 570 | break | 569 | break |
| 571 | } | 570 | } |
| 572 | 571 | ||
| 573 | var middle int | ||
| 574 | |||
| 575 | // Note: In case file name is surrounded by double quotes (it happens only in git-shell). | 572 | // Note: In case file name is surrounded by double quotes (it happens only in git-shell). |
| 576 | // e.g. diff --git "a/xxx" "b/xxx" | 573 | // e.g. diff --git "a/xxx" "b/xxx" |
| 577 | hasQuote := line[len(cmdDiffHead)] == '"' | 574 | var a string |
| 578 | if hasQuote { | 575 | var b string |
| 579 | middle = strings.Index(line, ` "b/`) | 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 | } else { | 582 | } else { |
| 581 | middle = strings.Index(line, " b/") | 583 | fmt.Fscanf(rd, "%s ", &a) |
| 582 | } | 584 | } |
| 583 | 585 | char, _ = rd.ReadByte() | |
| 584 | beg := len(cmdDiffHead) | 586 | _ = rd.UnreadByte() |
| 585 | a := line[beg+2 : middle] | 587 | if char == '"' { |
| 586 | b := line[middle+3:] | 588 | fmt.Fscanf(rd, "%q", &b) |
| 587 | 589 | } else { | |
| 588 | if hasQuote { | 590 | fmt.Fscanf(rd, "%s", &b) |
| 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 | |||
| 606 | } | 591 | } |
| 592 | a = a[2:] | ||
| 593 | b = b[2:] | ||
| 607 | 594 | ||
| 608 | curFile = &DiffFile{ | 595 | curFile = &DiffFile{ |
| 609 | Name: b, | 596 | Name: b, |