Skip to content

Commit

Permalink
Escape Next Line and Line Start in XML
Browse files Browse the repository at this point in the history
  • Loading branch information
skmcgrail committed Feb 8, 2021
1 parent 61f63d8 commit 360664a
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 2 deletions.
48 changes: 48 additions & 0 deletions encoding/xml/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package xml_test
import (
"bytes"
"log"
"sort"
"testing"

"github.com/aws/smithy-go/encoding/xml"
Expand Down Expand Up @@ -478,6 +479,53 @@ func TestEncodeListNamedShape(t *testing.T) {
verify(t, encoder, ex)
}

func TestEncodeEscaping(t *testing.T) {
b := bytes.NewBuffer(nil)
encoder := xml.NewEncoder(b)

func() {
r := encoder.RootElement(root)
defer r.Close()

cases := map[string]rune{
"quote": '"',
"apos": '\'',
"amp": '&',
"lt": '<',
"gt": '>',
"tab": '\t',
"newLine": '\n',
"carriageReturn": '\r',
"nextLine": '\u0085',
"lineSeparator": '\u2028',
}

var sortedKeys []string
for name := range cases {
sortedKeys = append(sortedKeys, name)
}

sort.Strings(sortedKeys)

for _, name := range sortedKeys {
rr := cases[name]

st := xml.StartElement{Name: xml.Name{Local: name}}
st.Attr = append(st.Attr, xml.Attr{
Name: xml.Name{
Local: "key",
},
Value: name + string(rr) + name,
})
value := r.MemberElement(st)
value.String(name + string(rr) + name)
}
}()

ex := []byte(`<root><amp key="amp&amp;amp">amp&amp;amp</amp><apos key="apos&#39;apos">apos&#39;apos</apos><carriageReturn key="carriageReturn&#xD;carriageReturn">carriageReturn&#xD;carriageReturn</carriageReturn><gt key="gt&gt;gt">gt&gt;gt</gt><lineSeparator key="lineSeparator&#x2028;lineSeparator">lineSeparator&#x2028;lineSeparator</lineSeparator><lt key="lt&lt;lt">lt&lt;lt</lt><newLine key="newLine&#xA;newLine">newLine&#xA;newLine</newLine><nextLine key="nextLine&#x85;nextLine">nextLine&#x85;nextLine</nextLine><quote key="quote&#34;quote">quote&#34;quote</quote><tab key="tab&#x9;tab">tab&#x9;tab</tab></root>`)
verify(t, encoder, ex)
}

// ExampleEncoder is the example function on how to use an encoder
func ExampleEncoder() {
b := bytes.NewBuffer(nil)
Expand Down
20 changes: 18 additions & 2 deletions encoding/xml/escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ var (
escNL = []byte("&#xA;")
escCR = []byte("&#xD;")
escFFFD = []byte("\uFFFD") // Unicode replacement character

// Additional Escapes
escNextLine = []byte("&#x85;")
escLS = []byte("&#x2028;")
)

// Decide whether the given rune is in the XML Character Range, per
Expand Down Expand Up @@ -61,6 +65,12 @@ func escapeString(e writer, s string) {
esc = escNL
case '\r':
esc = escCR
case '\u0085':
// Not escaped by stdlib
esc = escNextLine
case '\u2028':
// Not escaped by stdlib
esc = escLS
default:
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
esc = escFFFD
Expand Down Expand Up @@ -101,11 +111,17 @@ func escapeText(e writer, s []byte) {
case '\t':
esc = escTab
case '\n':
// TODO: This always escapes newline, which is different than stdlib's optional
// escape of new line
// This always escapes newline, which is different than stdlib's optional
// escape of new line.
esc = escNL
case '\r':
esc = escCR
case '\u0085':
// Not escaped by stdlib
esc = escNextLine
case '\u2028':
// Not escaped by stdlib
esc = escLS
default:
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
esc = escFFFD
Expand Down
39 changes: 39 additions & 0 deletions local-mod-replace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#1/usr/bin/env bash

PROJECT_DIR=""
SMITHY_SOURCE_DIR=$(cd `dirname $0` && pwd)

usage() {
echo "Usage: $0 [-s SMITHY_SOURCE_DIR] [-d PROJECT_DIR]" 1>&2
exit 1
}

while getopts "hs:d:" options; do
case "${options}" in
s)
SMITHY_SOURCE_DIR=${OPTARG}
if [ "$SMITHY_SOURCE_DIR" == "" ]; then
echo "path to smithy-go source directory is required" || exit
usage
fi
;;
d)
PROJECT_DIR=${OPTARG}
;;
h)
usage
;;
*)
usage
;;
esac
done

if [ "$PROJECT_DIR" != "" ]; then
cd $PROJECT_DIR || exit
fi

go mod graph | awk '{print $1}' | cut -d '@' -f 1 | sort | uniq | grep "github.com/aws/smithy-go" | while read x; do
repPath=${x/github.com\/aws\/smithy-go/${SMITHY_SOURCE_DIR}}
echo -replace $x=$repPath
done | xargs go mod edit

0 comments on commit 360664a

Please sign in to comment.