1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

utils: avoid importing encoding/xml package

This commit is contained in:
wdvxdr 2022-03-18 17:34:47 +08:00
parent f7ced299d9
commit d185826bee
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
2 changed files with 74 additions and 6 deletions

View File

@ -1,11 +1,11 @@
package utils
import (
"encoding/xml"
"math/rand"
"reflect"
"strconv"
"strings"
"unicode/utf8"
"unsafe"
)
@ -69,9 +69,63 @@ func S2B(s string) (b []byte) {
return
}
// XmlEscape xml escape string
func XmlEscape(c string) string {
buf := new(strings.Builder)
_ = xml.EscapeText(buf, []byte(c))
return buf.String()
const (
escQuot = """ // shorter than """
escApos = "'" // shorter than "'"
escAmp = "&"
escLT = "<"
escGT = ">"
escTab = "	"
escNL = "
"
escCR = "
"
escFFFD = "\uFFFD" // Unicode replacement character
)
func isInCharacterRange(r rune) (inrange bool) {
return r == 0x09 ||
r == 0x0A ||
r == 0x0D ||
r >= 0x20 && r <= 0xD7FF ||
r >= 0xE000 && r <= 0xFFFD ||
r >= 0x10000 && r <= 0x10FFFF
}
// XmlEscape xml escape string
func XmlEscape(s string) string {
var esc string
var sb strings.Builder
sb.Grow(len(s))
last := 0
for i, r := range s {
width := utf8.RuneLen(r)
switch r {
case '"':
esc = escQuot
case '\'':
esc = escApos
case '&':
esc = escAmp
case '<':
esc = escLT
case '>':
esc = escGT
case '\t':
esc = escTab
case '\n':
esc = escNL
case '\r':
esc = escCR
default:
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
esc = escFFFD
break
}
continue
}
sb.WriteString(s[last:i])
sb.WriteString(esc)
last = i + width
}
sb.WriteString(s[last:])
return sb.String()
}

14
utils/string_test.go Normal file
View File

@ -0,0 +1,14 @@
package utils
import (
"testing"
)
func TestXmlEscape(t *testing.T) {
input := "A \x00 terminated string."
expected := "A \uFFFD terminated string."
text := XmlEscape(input)
if text != expected {
t.Errorf("have %v, want %v", text, expected)
}
}