Merge pull request #1404 from wqweto/develop

Allow space and/or percent in file and directory names
This commit is contained in:
无闻 2015-07-30 20:22:42 +08:00
commit eedac73229
7 changed files with 52 additions and 41 deletions

View file

@ -87,7 +87,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
leftLine, rightLine int leftLine, rightLine int
isTooLong bool 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 buf bytes.Buffer
) )
@ -106,16 +106,10 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
i = i + 1 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 // Diff data too large, we only show the first about maxlines lines
if i == maxlines { if i == maxlines {
isTooLong = true isTooLong = true
log.Warn("Diff data too large") log.Warn("Diff data too large")
//return &Diff{}, nil
} }
switch { switch {
@ -127,7 +121,7 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
continue continue
case line[0] == '@': case line[0] == '@':
if isTooLong { if isTooLong {
return diff, nil break
} }
curSection = &DiffSection{} 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) curSection.Lines = append(curSection.Lines, diffLine)
// Parse line number. // 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() 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 continue
case line[0] == '+': case line[0] == '+':
curFile.Addition++ curFile.Addition++
@ -164,11 +163,11 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
// Get new file. // Get new file.
if strings.HasPrefix(line, DIFF_HEAD) { if strings.HasPrefix(line, DIFF_HEAD) {
if isTooLong { if isTooLong {
return diff, nil break
} }
fs := strings.Split(line[len(DIFF_HEAD):], " ") beg := len(DIFF_HEAD)
a := fs[0] a := line[beg : (len(line)-beg)/2+beg]
curFile = &DiffFile{ curFile = &DiffFile{
Name: a[strings.Index(a, "/")+1:], 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. for _, f := range diff.Files {
charsetLabel, err := base.DetectEncoding(buf.Bytes()) buf.Reset()
if charsetLabel != "utf8" && err == nil { for _, sec := range f.Sections {
encoding, _ := charset.Lookup(charsetLabel) for _, l := range sec.Lines {
buf.WriteString(l.Content)
if encoding != nil { buf.WriteString("\n")
d := encoding.NewDecoder() }
for _, f := range diff.Files { }
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 _, sec := range f.Sections {
for _, l := range sec.Lines { for _, l := range sec.Lines {
if c, _, err := transform.String(d, l.Content); err == nil { 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 return diff, nil
} }

View file

@ -55,7 +55,7 @@ func ShortSha(sha1 string) string {
func DetectEncoding(content []byte) (string, error) { func DetectEncoding(content []byte) (string, error) {
detector := chardet.NewTextDetector() detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content) 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 setting.AnsiCharset, err
} }
return result.Charset, err return result.Charset, err
@ -67,7 +67,7 @@ func ToUtf8WithErr(content []byte) (error, string) {
return err, "" return err, ""
} }
if charsetLabel == "utf8" { if charsetLabel == "UTF-8" {
return nil, string(content) return nil, string(content)
} }

View file

@ -313,7 +313,7 @@ func NewConfigContext() {
RepoRootPath = path.Clean(RepoRootPath) RepoRootPath = path.Clean(RepoRootPath)
} }
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash") ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
AnsiCharset = sec.Key("ANSI_CHARSET").MustString("ISO-8859-1") AnsiCharset = sec.Key("ANSI_CHARSET").MustString("")
// UI settings. // UI settings.
IssuePagingNum = Cfg.Section("ui").Key("ISSUE_PAGING_NUM").MustInt(10) IssuePagingNum = Cfg.Section("ui").Key("ISSUE_PAGING_NUM").MustInt(10)

View file

@ -26,10 +26,17 @@ func ServeBlob(ctx *middleware.Context, blob *git.Blob) error {
} }
_, isTextFile := base.IsTextFile(buf) _, isTextFile := base.IsTextFile(buf)
_, isImageFile := base.IsImageFile(buf) if isTextFile {
if !isTextFile && !isImageFile { charset, _ := base.DetectEncoding(buf)
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+path.Base(ctx.Repo.TreeName)) if charset != "UTF-8" {
ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") 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) ctx.Resp.Write(buf)
_, err = io.Copy(ctx.Resp, dataRc) _, err = io.Copy(ctx.Resp, dataRc)

View file

@ -6,7 +6,7 @@
{{if .IsDiffCompare }} {{if .IsDiffCompare }}
<div class="panel panel-info panel-radius compare-head-box"> <div class="panel panel-info panel-radius compare-head-box">
<div class="panel-header"> <div class="panel-header">
<a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{.SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a> <a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{EscapePound .SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a>
<h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-green">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-green">{{ShortSha .AfterCommitId}}</a></h4> <h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-green">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-green">{{ShortSha .AfterCommitId}}</a></h4>
</div> </div>
<div class="panel-body compare"> <div class="panel-body compare">
@ -16,7 +16,7 @@
{{else}} {{else}}
<div class="panel panel-info panel-radius diff-head-box"> <div class="panel panel-info panel-radius diff-head-box">
<div class="panel-header"> <div class="panel-header">
<a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{.SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a> <a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{EscapePound .SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a>
<h4 class="commit-message">{{RenderCommitMessage .Commit.Message $.RepoLink}}</h4> <h4 class="commit-message">{{RenderCommitMessage .Commit.Message $.RepoLink}}</h4>
</div> </div>
<div class="panel-body"> <div class="panel-body">
@ -90,9 +90,9 @@
{{end}} {{end}}
</div> </div>
{{if $file.IsDeleted}} {{if $file.IsDeleted}}
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.BeforeSourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> <a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{else}} {{else}}
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.SourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> <a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
{{end}} {{end}}
<span class="file">{{$file.Name}}</span> <span class="file">{{$file.Name}}</span>
</div> </div>
@ -100,7 +100,7 @@
<div class="panel-body file-body file-code code-view code-diff"> <div class="panel-body file-body file-code code-view code-diff">
{{if $isImage}} {{if $isImage}}
<div class="text-center"> <div class="text-center">
<img src="{{$.RawPath}}/{{.Name}}"> <img src="{{$.RawPath}}/{{EscapePound .Name}}">
</div> </div>
{{else}} {{else}}
<table> <table>

View file

@ -50,7 +50,8 @@
{{if eq $i $l}} {{if eq $i $l}}
<span class="bread">{{$v}}</span> <span class="bread">{{$v}}</span>
{{else}} {{else}}
<span class="bread"><a href="{{EscapePound $.BranchLink}}/{{index $.Paths $i}}">{{$v}}</a></span> {{ $p := index $.Paths $i}}
<span class="bread"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}">{{$v}}</a></span>
{{end}} {{end}}
{{end}} {{end}}
</li> </li>

View file

@ -13,11 +13,11 @@
{{end}} {{end}}
{{if not .ReadmeInList}} {{if not .ReadmeInList}}
{{if not .IsCommit}} {{if not .IsCommit}}
<a class="right" href="{{.RepoLink}}/src/{{.CommitId}}/{{.TreeName}}"> <a class="right" href="{{.RepoLink}}/src/{{.CommitId}}/{{EscapePound .TreeName}}">
<button class="btn btn-medium btn-gray btn-right-radius btn-comb">{{.i18n.Tr "repo.file_permalink"}}</button> <button class="btn btn-medium btn-gray btn-right-radius btn-comb">{{.i18n.Tr "repo.file_permalink"}}</button>
</a> </a>
{{end}} {{end}}
<a class="right" href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}/{{.TreeName}}"> <a class="right" href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}/{{EscapePound .TreeName}}">
<button class="btn btn-medium btn-gray btn-right-radius btn-comb">{{.i18n.Tr "repo.file_history"}}</button> <button class="btn btn-medium btn-gray btn-right-radius btn-comb">{{.i18n.Tr "repo.file_history"}}</button>
</a> </a>
<a class="right" href="{{EscapePound .FileLink}}"> <a class="right" href="{{EscapePound .FileLink}}">