var isWikiKey = parser.NewContextKey()
var renderMetasKey = parser.NewContextKey()
-type closesWithError interface {
- io.WriteCloser
- CloseWithError(err error) error
-}
-
type limitWriter struct {
- w closesWithError
+ w io.Writer
sum int64
limit int64
}
if err != nil {
return n, err
}
- _ = l.w.Close()
return n, fmt.Errorf("Rendered content too large - truncating render")
}
n, err := l.w.Write(data)
return n, err
}
-// Close closes the writer
-func (l *limitWriter) Close() error {
- return l.w.Close()
-}
-
-// CloseWithError closes the writer
-func (l *limitWriter) CloseWithError(err error) error {
- return l.w.CloseWithError(err)
-}
-
// newParserContext creates a parser.Context with the render context set
func newParserContext(ctx *markup.RenderContext) parser.Context {
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
})
- rd, wr := io.Pipe()
- defer func() {
- _ = rd.Close()
- _ = wr.Close()
- }()
-
lw := &limitWriter{
- w: wr,
+ w: output,
limit: setting.UI.MaxDisplayFileSize * 3,
}
- // FIXME: should we include a timeout that closes the pipe to abort the renderer and sanitizer if it takes too long?
- go func() {
- defer func() {
- err := recover()
- if err == nil {
- return
- }
-
- log.Warn("Unable to render markdown due to panic in goldmark: %v", err)
- if log.IsDebug() {
- log.Debug("Panic in markdown: %v\n%s", err, string(log.Stack(2)))
- }
- _ = lw.CloseWithError(fmt.Errorf("%v", err))
- }()
-
- // FIXME: Don't read all to memory, but goldmark doesn't support
- pc := newParserContext(ctx)
- buf, err := io.ReadAll(input)
- if err != nil {
- log.Error("Unable to ReadAll: %v", err)
+ // FIXME: should we include a timeout to abort the renderer if it takes too long?
+ defer func() {
+ err := recover()
+ if err == nil {
return
}
- if err := converter.Convert(giteautil.NormalizeEOL(buf), lw, parser.WithContext(pc)); err != nil {
- log.Error("Unable to render: %v", err)
- _ = lw.CloseWithError(err)
- return
+
+ log.Warn("Unable to render markdown due to panic in goldmark: %v", err)
+ if log.IsDebug() {
+ log.Debug("Panic in markdown: %v\n%s", err, string(log.Stack(2)))
}
- _ = lw.Close()
}()
- buf := markup.SanitizeReader(rd, "")
- _, err := io.Copy(output, buf)
- return err
+
+ // FIXME: Don't read all to memory, but goldmark doesn't support
+ pc := newParserContext(ctx)
+ buf, err := io.ReadAll(input)
+ if err != nil {
+ log.Error("Unable to ReadAll: %v", err)
+ return err
+ }
+ if err := converter.Convert(giteautil.NormalizeEOL(buf), lw, parser.WithContext(pc)); err != nil {
+ log.Error("Unable to render: %v", err)
+ return err
+ }
+
+ return nil
}
+// Note: The output of this method must get sanitized.
func render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
defer func() {
err := recover()
return
}
- log.Warn("Unable to render markdown due to panic in goldmark - will return sanitized raw bytes")
+ log.Warn("Unable to render markdown due to panic in goldmark - will return raw bytes")
if log.IsDebug() {
log.Debug("Panic in markdown: %v\n%s", err, string(log.Stack(2)))
}
- ret := markup.SanitizeReader(input, "")
- _, err = io.Copy(output, ret)
+ _, err = io.Copy(output, input)
if err != nil {
- log.Error("SanitizeReader failed: %v", err)
+ log.Error("io.Copy failed: %v", err)
}
}()
return actualRender(ctx, input, output)
// Render renders Markdown to HTML with all specific handling stuff.
func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
- if ctx.Filename == "" {
- ctx.Filename = "a.md"
+ if ctx.Type == "" {
+ ctx.Type = MarkupName
}
return markup.Render(ctx, input, output)
}
// RenderRaw renders Markdown to HTML without handling special links.
func RenderRaw(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
- return render(ctx, input, output)
+ rd, wr := io.Pipe()
+ defer func() {
+ _ = rd.Close()
+ _ = wr.Close()
+ }()
+
+ go func() {
+ if err := render(ctx, input, wr); err != nil {
+ _ = wr.CloseWithError(err)
+ return
+ }
+ _ = wr.Close()
+ }()
+
+ return markup.SanitizeReader(rd, "", output)
}
// RenderRawString renders Markdown to HTML without handling special links and return string