Skip to content

Commit 7c585a2

Browse files
committed
Fix #22: Proper escaping of attribute values
1 parent 233e840 commit 7c585a2

File tree

6 files changed

+48
-11
lines changed

6 files changed

+48
-11
lines changed

internal/utils/utils.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package utils
22

33
import (
4+
"bytes"
45
"encoding/xml"
56
"fmt"
67
"github.com/PuerkitoBio/goquery"
@@ -85,7 +86,9 @@ func FormatXml(reader io.Reader, writer io.Writer, indent string, colors int) er
8586
if attr.Name.Local == "xmlns" {
8687
nsAliases[attr.Value] = ""
8788
}
88-
attrs = append(attrs, getTokenFullName(attr.Name, nsAliases)+attrColor("=\""+attr.Value+"\""))
89+
escapedValue, _ := escapeText(attr.Value)
90+
attrElement := getTokenFullName(attr.Name, nsAliases) + attrColor("=\""+escapedValue+"\"")
91+
attrs = append(attrs, attrElement)
8992
}
9093
attrsStr := strings.Join(attrs, " ")
9194
if attrsStr != "" {
@@ -248,7 +251,8 @@ func FormatHtml(reader io.Reader, writer io.Writer, indent string, colors int) e
248251
if hasAttr {
249252
for {
250253
attrKey, attrValue, moreAttr := tokenizer.TagAttr()
251-
attrs = append(attrs, string(attrKey)+attrColor("=\""+string(attrValue)+"\""))
254+
escapedValue, _ := escapeText(string(attrValue))
255+
attrs = append(attrs, string(attrKey)+attrColor("=\""+escapedValue+"\""))
252256
if !moreAttr {
253257
break
254258
}
@@ -360,3 +364,16 @@ func getSelfClosingTags() map[string]bool {
360364
"wbr": true,
361365
}
362366
}
367+
368+
func escapeText(input string) (string, error) {
369+
buf := new(bytes.Buffer)
370+
if err := xml.EscapeText(buf, []byte(input)); err != nil {
371+
return "", err
372+
}
373+
374+
result := buf.String()
375+
result = strings.Replace(result, """, """, -1)
376+
result = strings.Replace(result, "'", "'", -1)
377+
378+
return result, nil
379+
}

internal/utils/utils_test.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ func getFileReader(filename string) io.Reader {
2222

2323
func TestFormatXml(t *testing.T) {
2424
files := map[string]string{
25-
"unformatted.xml": "formatted.xml",
26-
"unformatted2.xml": "formatted2.xml",
27-
"unformatted3.xml": "formatted3.xml",
28-
"unformatted4.xml": "formatted4.xml",
29-
"unformatted5.xml": "formatted5.xml",
30-
"unformatted6.xml": "formatted6.xml",
31-
"unformatted7.xml": "formatted7.xml",
32-
"unformatted8.xml": "formatted8.xml",
33-
"unformatted9.xml": "formatted9.xml",
25+
"unformatted.xml": "formatted.xml",
26+
"unformatted2.xml": "formatted2.xml",
27+
"unformatted3.xml": "formatted3.xml",
28+
"unformatted4.xml": "formatted4.xml",
29+
"unformatted5.xml": "formatted5.xml",
30+
"unformatted6.xml": "formatted6.xml",
31+
"unformatted7.xml": "formatted7.xml",
32+
"unformatted8.xml": "formatted8.xml",
33+
"unformatted9.xml": "formatted9.xml",
34+
"unformatted10.xml": "formatted10.xml",
3435
}
3536

3637
for unformattedFile, expectedFile := range files {
@@ -53,6 +54,7 @@ func TestFormatHtml(t *testing.T) {
5354
"unformatted2.html": "formatted2.html",
5455
"unformatted3.html": "formatted3.html",
5556
"unformatted4.html": "formatted4.html",
57+
"unformatted5.html": "formatted5.html",
5658
"unformatted.xml": "formatted.xml",
5759
}
5860

@@ -102,3 +104,9 @@ func TestPagerPrint(t *testing.T) {
102104
assert.Nil(t, err)
103105
assert.Contains(t, output.String(), "<html>")
104106
}
107+
108+
func TestEscapeText(t *testing.T) {
109+
result, err := escapeText("\"value\"")
110+
assert.Nil(t, err)
111+
assert.Equal(t, "&quot;value&quot;", result)
112+
}

test/data/html/formatted5.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<html>
2+
<tag attr="GetParam(&quot;HASH_VALUE_SHARING_MODE&quot;) != 1"></tag>
3+
</html>

test/data/html/unformatted5.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<html >
2+
<tag attr="GetParam(&quot;HASH_VALUE_SHARING_MODE&quot;) != 1"></tag>
3+
</html>

test/data/xml/formatted10.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<root>
2+
<SEQUENCE mandatory="FALSE" precondition="GetParam(&quot;HASH_VALUE_SHARING_MODE&quot;) != 1"/>
3+
</root>

test/data/xml/unformatted10.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<root>
2+
<SEQUENCE mandatory="FALSE" precondition="GetParam(&quot;HASH_VALUE_SHARING_MODE&quot;) != 1"/>
3+
</root>

0 commit comments

Comments
 (0)