forked from NYANDEV/forgejo
72524adf3f
Backport #22017 As recognised in #21841 the rendering of plain text files is somewhat incorrect when there are ambiguous characters as the html code is double escaped. In fact there are several more problems here. We have a residual isRenderedHTML which is actually simply escaping the file - not rendering it. This is badly named and gives the wrong impression. There is also unusual behaviour whether the file is called a Readme or not and there is no way to get to the source code if the file is called README. In reality what should happen is different depending on whether the file is being rendered a README at the bottom of the directory view or not. 1. If it is rendered as a README on a directory - it should simply be escaped and rendered as `<pre>` text. 2. If it is rendered as a file then it should be rendered as source code. This PR therefore does: 1. Rename IsRenderedHTML to IsPlainText 2. Readme files rendered at the bottom of the directory are rendered without line numbers 3. Otherwise plain text files are rendered as source code. Replace #21841 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
88 lines
3.2 KiB
Go
88 lines
3.2 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.
|
|
|
|
//go:generate go run invisible/generate.go -v -o ./invisible_gen.go
|
|
|
|
//go:generate go run ambiguous/generate.go -v -o ./ambiguous_gen.go ambiguous/ambiguous.json
|
|
|
|
package charset
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
"strings"
|
|
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/translation"
|
|
)
|
|
|
|
// RuneNBSP is the codepoint for NBSP
|
|
const RuneNBSP = 0xa0
|
|
|
|
// EscapeControlHTML escapes the unicode control sequences in a provided html document
|
|
func EscapeControlHTML(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) {
|
|
sb := &strings.Builder{}
|
|
outputStream := &HTMLStreamerWriter{Writer: sb}
|
|
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
|
|
|
|
if err := StreamHTML(strings.NewReader(text), streamer); err != nil {
|
|
streamer.escaped.HasError = true
|
|
log.Error("Error whilst escaping: %v", err)
|
|
}
|
|
return streamer.escaped, sb.String()
|
|
}
|
|
|
|
// EscapeControlReaders escapes the unicode control sequences in a provided reader of HTML content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
|
|
func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) {
|
|
outputStream := &HTMLStreamerWriter{Writer: writer}
|
|
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
|
|
|
|
if err = StreamHTML(reader, streamer); err != nil {
|
|
streamer.escaped.HasError = true
|
|
log.Error("Error whilst escaping: %v", err)
|
|
}
|
|
return streamer.escaped, err
|
|
}
|
|
|
|
// EscapeControlStringReader escapes the unicode control sequences in a provided reader of string content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
|
|
func EscapeControlStringReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) {
|
|
bufRd := bufio.NewReader(reader)
|
|
outputStream := &HTMLStreamerWriter{Writer: writer}
|
|
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
|
|
|
|
for {
|
|
line, rdErr := bufRd.ReadString('\n')
|
|
if len(line) > 0 {
|
|
if err := streamer.Text(line); err != nil {
|
|
streamer.escaped.HasError = true
|
|
log.Error("Error whilst escaping: %v", err)
|
|
return streamer.escaped, err
|
|
}
|
|
}
|
|
if rdErr != nil {
|
|
if rdErr != io.EOF {
|
|
err = rdErr
|
|
}
|
|
break
|
|
}
|
|
if err := streamer.SelfClosingTag("br"); err != nil {
|
|
streamer.escaped.HasError = true
|
|
return streamer.escaped, err
|
|
}
|
|
}
|
|
return streamer.escaped, err
|
|
}
|
|
|
|
// EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string
|
|
func EscapeControlString(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) {
|
|
sb := &strings.Builder{}
|
|
outputStream := &HTMLStreamerWriter{Writer: sb}
|
|
streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
|
|
|
|
if err := streamer.Text(text); err != nil {
|
|
streamer.escaped.HasError = true
|
|
log.Error("Error whilst escaping: %v", err)
|
|
}
|
|
return streamer.escaped, sb.String()
|
|
}
|