forgejo/modules/markup/console/console.go
Lunny Xiao b01dce2a6e
Allow render HTML with css/js external links (#19017)
* Allow render HTML with css/js external links

* Fix bug because of filename escape chars

* Fix lint

* Update docs about new configuration item

* Fix bug of render HTML in sub directory

* Add CSP head for displaying iframe in rendering file

* Fix test

* Apply suggestions from code review

Co-authored-by: delvh <dev.lh@web.de>

* Some improvements

* some improvement

* revert change in SanitizerDisabled of external renderer

* Add sandbox for iframe and support allow-scripts and allow-same-origin

* refactor

* fix

* fix lint

* fine tune

* use single option RENDER_CONTENT_MODE, use sandbox=allow-scripts

* fine tune CSP

* Apply suggestions from code review

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2022-06-16 11:33:23 +08:00

88 lines
2.3 KiB
Go

// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package console
import (
"bytes"
"io"
"path/filepath"
"regexp"
"strings"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
trend "github.com/buildkite/terminal-to-html/v3"
"github.com/go-enry/go-enry/v2"
)
// MarkupName describes markup's name
var MarkupName = "console"
func init() {
markup.RegisterRenderer(Renderer{})
}
// Renderer implements markup.Renderer
type Renderer struct{}
// Name implements markup.Renderer
func (Renderer) Name() string {
return MarkupName
}
// Extensions implements markup.Renderer
func (Renderer) Extensions() []string {
return []string{".sh-session"}
}
// SanitizerRules implements markup.Renderer
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
return []setting.MarkupSanitizerRule{
{Element: "span", AllowAttr: "class", Regexp: regexp.MustCompile(`^term-((fg[ix]?|bg)\d+|container)$`)},
}
}
// CanRender implements markup.RendererContentDetector
func (Renderer) CanRender(filename string, input io.Reader) bool {
buf, err := io.ReadAll(input)
if err != nil {
return false
}
if enry.GetLanguage(filepath.Base(filename), buf) != enry.OtherLanguage {
return false
}
return bytes.ContainsRune(buf, '\x1b')
}
// Render renders terminal colors to HTML with all specific handling stuff.
func (Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
buf, err := io.ReadAll(input)
if err != nil {
return err
}
buf = trend.Render(buf)
buf = bytes.ReplaceAll(buf, []byte("\n"), []byte(`<br>`))
_, err = output.Write(buf)
return err
}
// Render renders terminal colors to HTML with all specific handling stuff.
func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
if ctx.Type == "" {
ctx.Type = MarkupName
}
return markup.Render(ctx, input, output)
}
// RenderString renders terminal colors in string to HTML with all specific handling stuff and return string
func RenderString(ctx *markup.RenderContext, content string) (string, error) {
var buf strings.Builder
if err := Render(ctx, strings.NewReader(content), &buf); err != nil {
return "", err
}
return buf.String(), nil
}