diff --git a/models/git_diff.go b/models/git_diff.go index 9d34ed62..9681b3f4 100644 --- a/models/git_diff.go +++ b/models/git_diff.go @@ -87,7 +87,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff leftLine, rightLine int isTooLong bool - // FIXME: use first 30 lines to detect file encoding. Should use cache in the future. + // FIXME: Should use cache in the future. buf bytes.Buffer ) @@ -106,16 +106,10 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff i = i + 1 - // FIXME: use first 30 lines to detect file encoding. - if i <= 30 { - buf.WriteString(line) - } - // Diff data too large, we only show the first about maxlines lines if i == maxlines { isTooLong = true log.Warn("Diff data too large") - //return &Diff{}, nil } switch { @@ -127,7 +121,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff continue case line[0] == '@': if isTooLong { - return diff, nil + break } curSection = &DiffSection{} @@ -137,9 +131,14 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff curSection.Lines = append(curSection.Lines, diffLine) // Parse line number. - ranges := strings.Split(ss[len(ss)-2][1:], " ") + ranges := strings.Split(ss[1][1:], " ") leftLine, _ = com.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int() - rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int() + if len(ranges) > 1 { + rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int() + } else { + log.Warn("Parse line number failed: %v", line) + rightLine = leftLine + } continue case line[0] == '+': curFile.Addition++ @@ -164,11 +163,11 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff // Get new file. if strings.HasPrefix(line, DIFF_HEAD) { if isTooLong { - return diff, nil + break } - fs := strings.Split(line[len(DIFF_HEAD):], " ") - a := fs[0] + beg := len(DIFF_HEAD) + a := line[beg : (len(line)-beg)/2+beg] curFile = &DiffFile{ Name: a[strings.Index(a, "/")+1:], @@ -201,14 +200,19 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff } } - // FIXME: use first 30 lines to detect file encoding. - charsetLabel, err := base.DetectEncoding(buf.Bytes()) - if charsetLabel != "utf8" && err == nil { - encoding, _ := charset.Lookup(charsetLabel) - - if encoding != nil { - d := encoding.NewDecoder() - for _, f := range diff.Files { + for _, f := range diff.Files { + buf.Reset() + for _, sec := range f.Sections { + for _, l := range sec.Lines { + buf.WriteString(l.Content) + buf.WriteString("\n") + } + } + charsetLabel, err := base.DetectEncoding(buf.Bytes()) + if charsetLabel != "UTF-8" && err == nil { + encoding, _ := charset.Lookup(charsetLabel) + if encoding != nil { + d := encoding.NewDecoder() for _, sec := range f.Sections { for _, l := range sec.Lines { if c, _, err := transform.String(d, l.Content); err == nil { @@ -219,7 +223,6 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff } } } - return diff, nil } diff --git a/modules/base/template.go b/modules/base/template.go index f0a2e032..2a81a34d 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -55,7 +55,7 @@ func ShortSha(sha1 string) string { func DetectEncoding(content []byte) (string, error) { detector := chardet.NewTextDetector() result, err := detector.DetectBest(content) - if result.Charset == "ISO-8859-1" { + if result.Charset != "UTF-8" && len(setting.AnsiCharset) > 0 { return setting.AnsiCharset, err } return result.Charset, err @@ -67,7 +67,7 @@ func ToUtf8WithErr(content []byte) (error, string) { return err, "" } - if charsetLabel == "utf8" { + if charsetLabel == "UTF-8" { return nil, string(content) } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 896e60ad..f826a3a4 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -313,7 +313,7 @@ func NewConfigContext() { RepoRootPath = path.Clean(RepoRootPath) } ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash") - AnsiCharset = sec.Key("ANSI_CHARSET").MustString("ISO-8859-1") + AnsiCharset = sec.Key("ANSI_CHARSET").MustString("") // UI settings. IssuePagingNum = Cfg.Section("ui").Key("ISSUE_PAGING_NUM").MustInt(10) diff --git a/routers/repo/download.go b/routers/repo/download.go index b1c5fbc8..c71f8d29 100644 --- a/routers/repo/download.go +++ b/routers/repo/download.go @@ -26,10 +26,17 @@ func ServeBlob(ctx *middleware.Context, blob *git.Blob) error { } _, isTextFile := base.IsTextFile(buf) - _, isImageFile := base.IsImageFile(buf) - if !isTextFile && !isImageFile { - ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+path.Base(ctx.Repo.TreeName)) - ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") + if isTextFile { + charset, _ := base.DetectEncoding(buf) + if charset != "UTF-8" { + ctx.Resp.Header().Set("Content-Type", "text/plain; charset="+charset) + } + } else { + _, isImageFile := base.IsImageFile(buf) + if !isImageFile { + ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+path.Base(ctx.Repo.TreeName)) + ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") + } } ctx.Resp.Write(buf) _, err = io.Copy(ctx.Resp, dataRc) diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl index b9dc87de..268bbc16 100644 --- a/templates/repo/diff.tmpl +++ b/templates/repo/diff.tmpl @@ -6,7 +6,7 @@ {{if .IsDiffCompare }}
{{if $line.RightIdx}}{{$line.RightIdx}}{{end}} | - +
{{$line.Content}} |
@@ -126,7 +126,7 @@
{{end}}
-