Codebase list golang-github-tdewolff-parse / 83ccb3c
Add XML option for EscapeAttrVal Taco de Wolff 5 years ago
2 changed file(s) with 46 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
5151 }
5252
5353 // EscapeAttrVal returns the escaped attribute value bytes without quotes.
54 func EscapeAttrVal(buf *[]byte, orig, b []byte) []byte {
54 func EscapeAttrVal(buf *[]byte, orig, b []byte, isXML bool) []byte {
5555 singles := 0
5656 doubles := 0
5757 unquoted := true
7979 }
8080 }
8181 }
82 if unquoted {
82 if unquoted && !isXML {
8383 return b
8484 } else if !entities && len(orig) == len(b)+2 && (singles == 0 && orig[0] == '\'' || doubles == 0 && orig[0] == '"') {
8585 return orig
8888 n := len(b) + 2
8989 var quote byte
9090 var escapedQuote []byte
91 if doubles > singles {
91 if singles >= doubles || isXML {
92 n += doubles * 4
93 quote = '"'
94 escapedQuote = doubleQuoteEntityBytes
95 } else {
9296 n += singles * 4
9397 quote = '\''
9498 escapedQuote = singleQuoteEntityBytes
95 } else {
96 n += doubles * 4
97 quote = '"'
98 escapedQuote = doubleQuoteEntityBytes
9999 }
100100 if n > cap(*buf) {
101101 *buf = make([]byte, 0, n) // maximum size, not actual size
1010 attrVal string
1111 expected string
1212 }{
13 {"xyz", "xyz"},
14 {"", ""},
15 {"x&z", "x&z"},
16 {"x/z", "x/z"},
17 {"x'z", "\"x'z\""},
18 {"x\"z", "'x\"z'"},
19 {"'x\"z'", "'x\"z'"},
20 {"'x'\"'z'", "\"x'"'z\""},
21 {"\"x"'"z\"", "'x\"'\"z'"},
22 {"\"x'z\"", "\"x'z\""},
23 {"'x"z'", "'x\"z'"},
24 {"'x\">'", "'x\">'"},
25 {"You're encouraged to log in; however, it's not mandatory. [o]", "\"You're encouraged to log in; however, it's not mandatory. [o]\""},
26 {"a'b=\"\"", "'a'b=\"\"'"},
27 {"x<z", "\"x<z\""},
28 {"'x\"&#39;\"z'", "'x\"&#39;\"z'"},
13 {`xyz`, `xyz`},
14 {``, ``},
15 {`x&amp;z`, `x&amp;z`},
16 {`x/z`, `x/z`},
17 {`x'z`, `"x'z"`},
18 {`x"z`, `'x"z'`},
19 {`'x"z'`, `'x"z'`},
20 {`'x&#39;"&#39;z'`, `"x'&#34;'z"`},
21 {`"x&#34;'&#34;z"`, `'x"&#39;"z'`},
22 {`"x&#x27;z"`, `"x'z"`},
23 {`'x&#x00022;z'`, `'x"z'`},
24 {`'x"&gt;'`, `'x"&gt;'`},
25 {`You&#039;re encouraged to log in; however, it&#039;s not mandatory. [o]`, `"You're encouraged to log in; however, it's not mandatory. [o]"`},
26 {`a'b=""`, `'a&#39;b=""'`},
27 {`x<z`, `"x<z"`},
28 {`'x"&#39;"z'`, `'x"&#39;"z'`},
2929 }
3030 var buf []byte
3131 for _, tt := range escapeAttrValTests {
3535 if len(b) > 1 && (b[0] == '"' || b[0] == '\'') && b[0] == b[len(b)-1] {
3636 b = b[1 : len(b)-1]
3737 }
38 val := EscapeAttrVal(&buf, orig, []byte(b))
38 val := EscapeAttrVal(&buf, orig, []byte(b), false)
3939 test.String(t, string(val), tt.expected)
4040 })
4141 }
4242 }
43
44 func TestEscapeAttrValXML(t *testing.T) {
45 var escapeAttrValTests = []struct {
46 attrVal string
47 expected string
48 }{
49 {`xyz`, `"xyz"`},
50 {``, `""`},
51 }
52 var buf []byte
53 for _, tt := range escapeAttrValTests {
54 t.Run(tt.attrVal, func(t *testing.T) {
55 b := []byte(tt.attrVal)
56 orig := b
57 if len(b) > 1 && (b[0] == '"' || b[0] == '\'') && b[0] == b[len(b)-1] {
58 b = b[1 : len(b)-1]
59 }
60 val := EscapeAttrVal(&buf, orig, []byte(b), true)
61 test.String(t, string(val), tt.expected)
62 })
63 }
64 }