Allow space and/or percent in file and directory namestags/v1.2.0-rc1
@@ -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 | |||
} | |||
@@ -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) | |||
} | |||
@@ -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) | |||
@@ -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) | |||
@@ -6,7 +6,7 @@ | |||
{{if .IsDiffCompare }} | |||
<div class="panel panel-info panel-radius compare-head-box"> | |||
<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> | |||
</div> | |||
<div class="panel-body compare"> | |||
@@ -16,7 +16,7 @@ | |||
{{else}} | |||
<div class="panel panel-info panel-radius diff-head-box"> | |||
<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> | |||
</div> | |||
<div class="panel-body"> | |||
@@ -37,7 +37,7 @@ | |||
<img class="avatar-30" src="{{AvatarLink .Commit.Author.Email}}" /> | |||
<strong>{{.Commit.Author.Name}}</strong> | |||
{{end}} | |||
<span class="text-grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span> | |||
<span class="text-grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span> | |||
</p> | |||
</div> | |||
</div> | |||
@@ -90,9 +90,9 @@ | |||
{{end}} | |||
</div> | |||
{{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}} | |||
<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}} | |||
<span class="file">{{$file.Name}}</span> | |||
</div> | |||
@@ -100,7 +100,7 @@ | |||
<div class="panel-body file-body file-code code-view code-diff"> | |||
{{if $isImage}} | |||
<div class="text-center"> | |||
<img src="{{$.RawPath}}/{{.Name}}"> | |||
<img src="{{$.RawPath}}/{{EscapePound .Name}}"> | |||
</div> | |||
{{else}} | |||
<table> | |||
@@ -114,7 +114,7 @@ | |||
<td class="lines-num lines-num-new"> | |||
<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span> | |||
</td> | |||
<td class="lines-code"> | |||
<pre>{{$line.Content}}</pre> | |||
</td> | |||
@@ -126,7 +126,7 @@ | |||
{{end}} | |||
</div> | |||
</div> | |||
<br> | |||
<br> | |||
{{end}} | |||
{{end}} | |||
</div> | |||
@@ -50,7 +50,8 @@ | |||
{{if eq $i $l}} | |||
<span class="bread">{{$v}}</span> | |||
{{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}} | |||
</li> | |||
@@ -13,11 +13,11 @@ | |||
{{end}} | |||
{{if not .ReadmeInList}} | |||
{{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> | |||
</a> | |||
{{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> | |||
</a> | |||
<a class="right" href="{{EscapePound .FileLink}}"> | |||
@@ -47,4 +47,4 @@ | |||
</table> | |||
{{end}} | |||
</div> | |||
</div> | |||
</div> |