1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Display SVG files as images instead of text (#14101)

* Change to display SVG files as images

* Remove unsafe styles from SVG CSP

* Add integration test to test SVG headers

* Add config setting to disable SVG rendering

* Add test for img tag when loading SVG image

* Remove the Raw view button for svg files since we don't fully support this

* Fix copyright year

* Rename and move config setting

* Add setting to cheat sheet in docs

* Fix so that comment matches cheat sheet

* Add allowing styles in CSP based on pull request feedback

* Re-enable raw button since we show SVG styles now

* Change so that SVG files are editable

* Add UI to toggle between source and rendered image for SVGs

* Change to show blame button for SVG images

* Fix to update ctx data

* Add test for DetectContentType when file is longer than sniffLen

Co-authored-by: Jonathan Tran <jon@allspice.io>
Co-authored-by: Kyle D <kdumontnu@gmail.com>
This commit is contained in:
Jonathan Tran
2021-01-12 22:45:19 -05:00
committed by GitHub
parent 9465e60504
commit 81467e6f35
47 changed files with 736 additions and 16 deletions

View File

@@ -46,6 +46,11 @@ func ServeData(ctx *context.Context, name string, reader io.Reader) error {
} else if base.IsImageFile(buf) || base.IsPDFFile(buf) {
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, name))
ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
if base.IsSVGImageFile(buf) {
ctx.Resp.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
ctx.Resp.Header().Set("X-Content-Type-Options", "nosniff")
ctx.Resp.Header().Set("Content-Type", base.SVGMimeType)
}
} else {
ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name))
ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")

View File

@@ -114,9 +114,9 @@ func editFile(ctx *context.Context, isNewFile bool) {
n, _ := dataRc.Read(buf)
buf = buf[:n]
// Only text file are editable online.
if !base.IsTextFile(buf) {
ctx.NotFound("base.IsTextFile", nil)
// Only some file types are editable online as text.
if !base.IsRepresentableAsText(buf) {
ctx.NotFound("base.IsRepresentableAsText", nil)
return
}

View File

@@ -279,14 +279,19 @@ func LFSFileGet(ctx *context.Context) {
}
buf = buf[:n]
isTextFile := base.IsTextFile(buf)
ctx.Data["IsTextFile"] = isTextFile
ctx.Data["IsTextFile"] = base.IsTextFile(buf)
isRepresentableAsText := base.IsRepresentableAsText(buf)
fileSize := meta.Size
ctx.Data["FileSize"] = meta.Size
ctx.Data["RawFileLink"] = fmt.Sprintf("%s%s.git/info/lfs/objects/%s/%s", setting.AppURL, ctx.Repo.Repository.FullName(), meta.Oid, "direct")
switch {
case isTextFile:
case isRepresentableAsText:
// This will be true for SVGs.
if base.IsImageFile(buf) {
ctx.Data["IsImageFile"] = true
}
if fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
break

View File

@@ -396,6 +396,20 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
isLFSFile := false
ctx.Data["IsTextFile"] = isTextFile
isDisplayingSource := ctx.Query("display") == "source"
isDisplayingRendered := !isDisplayingSource
isRepresentableAsText := base.IsRepresentableAsText(buf)
ctx.Data["IsRepresentableAsText"] = isRepresentableAsText
if !isRepresentableAsText {
// If we can't show plain text, always try to render.
isDisplayingSource = false
isDisplayingRendered = true
}
ctx.Data["IsDisplayingSource"] = isDisplayingSource
ctx.Data["IsDisplayingRendered"] = isDisplayingRendered
ctx.Data["IsTextSource"] = isTextFile || isDisplayingSource
//Check for LFS meta file
if isTextFile && setting.LFS.StartServer {
meta := lfs.IsPointerFile(&buf)
@@ -451,12 +465,18 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
// Assume file is not editable first.
if isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
} else if !isTextFile {
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
}
switch {
case isTextFile:
case isRepresentableAsText:
// This will be true for SVGs.
if base.IsImageFile(buf) {
ctx.Data["IsImageFile"] = true
ctx.Data["HasSourceRenderedToggle"] = true
}
if fileSize >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
break