dispatch/vendor/github.com/tdewolff/parse/v2/html/util.go

104 lines
3.1 KiB
Go
Raw Normal View History

2020-04-29 02:23:32 +00:00
package html
2018-12-17 13:41:24 +00:00
var (
singleQuoteEntityBytes = []byte("'")
doubleQuoteEntityBytes = []byte(""")
)
// EscapeAttrVal returns the escaped attribute value bytes without quotes.
2019-06-09 00:01:48 +00:00
func EscapeAttrVal(buf *[]byte, orig, b []byte, isXML bool) []byte {
2018-12-17 13:41:24 +00:00
singles := 0
doubles := 0
unquoted := true
entities := false
2020-04-29 02:23:32 +00:00
for _, c := range b {
2018-12-17 13:41:24 +00:00
if charTable[c] {
2020-04-29 02:23:32 +00:00
unquoted = false
if c == '"' {
doubles++
} else if c == '\'' {
singles++
2018-12-17 13:41:24 +00:00
}
}
}
2019-06-09 00:01:48 +00:00
if unquoted && !isXML {
2018-12-17 13:41:24 +00:00
return b
} else if !entities && len(orig) == len(b)+2 && (singles == 0 && orig[0] == '\'' || doubles == 0 && orig[0] == '"') {
return orig
}
n := len(b) + 2
var quote byte
var escapedQuote []byte
2019-06-09 00:01:48 +00:00
if singles >= doubles || isXML {
2018-12-17 13:41:24 +00:00
n += doubles * 4
quote = '"'
escapedQuote = doubleQuoteEntityBytes
2019-06-09 00:01:48 +00:00
} else {
n += singles * 4
quote = '\''
escapedQuote = singleQuoteEntityBytes
2018-12-17 13:41:24 +00:00
}
if n > cap(*buf) {
*buf = make([]byte, 0, n) // maximum size, not actual size
}
t := (*buf)[:n] // maximum size, not actual size
t[0] = quote
j := 1
start := 0
for i, c := range b {
2020-04-29 02:23:32 +00:00
if c == quote {
2018-12-17 13:41:24 +00:00
j += copy(t[j:], b[start:i])
j += copy(t[j:], escapedQuote)
start = i + 1
}
}
j += copy(t[j:], b[start:])
t[j] = quote
return t[:j+1]
}
2020-04-29 02:23:32 +00:00
var charTable = [256]bool{
// ASCII
false, false, false, false, false, false, false, false,
false, true, true, false, true, true, false, false, // tab, line feed, form feed, carriage return
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true, false, true, false, false, false, false, true, // space, "), '
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, true, true, true, false, // <, =, >
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true, false, false, false, false, false, false, false, // `
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
// non-ASCII
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
}