Skip to content

Commit

Permalink
private/protocol/xml/xmlutil: Updated XML encoding to ensure line fee…
Browse files Browse the repository at this point in the history
…d is escaped. (#3881)
  • Loading branch information
skmcgrail committed Apr 30, 2021
1 parent b5cfa21 commit 65c0f3b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_PENDING.md
@@ -1,5 +1,6 @@
### SDK Features

### SDK Enhancements
* `private/protocol/xml/xmlutil`: XML encoding has been updated to include encoding line feed character. ([#3881](https://github.com/aws/aws-sdk-go/pull/3881))

### SDK Bugs
2 changes: 2 additions & 0 deletions private/protocol/xml/xmlutil/build.go
Expand Up @@ -308,6 +308,8 @@ func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag refl
if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
attr := xml.Attr{Name: xname, Value: str}
current.Attr = append(current.Attr, attr)
} else if len(xname.Local) == 0 {
current.Text = str
} else { // regular text node
current.AddChild(&XMLNode{Name: xname, Text: str})
}
Expand Down
6 changes: 6 additions & 0 deletions private/protocol/xml/xmlutil/build_test.go
Expand Up @@ -153,6 +153,12 @@ func TestBuildXML(t *testing.T) {
Input: &namedEmptyPayload{},
Expect: "<namedEmptyPayload></namedEmptyPayload>",
},
"escape line feed and carriage return": {
Input: &implicitPayload{
StrVal: aws.String("this\nstring\rhas\r\nescapable\n\rcharacters"),
},
Expect: "<StrVal>this&#xA;string&#xD;has&#xD;&#xA;escapable&#xA;&#xD;characters</StrVal>",
},
}

for name, c := range cases {
Expand Down
22 changes: 18 additions & 4 deletions private/protocol/xml/xmlutil/xml_to_struct.go
Expand Up @@ -18,6 +18,14 @@ type XMLNode struct {
parent *XMLNode
}

// textEncoder is a string type alias that implemnts the TextMarshaler interface.
// This alias type is used to ensure that the line feed (\n) (U+000A) is escaped.
type textEncoder string

func (t textEncoder) MarshalText() ([]byte, error) {
return []byte(t), nil
}

// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
func NewXMLElement(name xml.Name) *XMLNode {
return &XMLNode{
Expand Down Expand Up @@ -130,11 +138,16 @@ func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
attrs = sortedAttrs
}

e.EncodeToken(xml.StartElement{Name: node.Name, Attr: attrs})
startElement := xml.StartElement{Name: node.Name, Attr: attrs}

if node.Text != "" {
e.EncodeToken(xml.CharData([]byte(node.Text)))
} else if sorted {
e.EncodeElement(textEncoder(node.Text), startElement)
return e.Flush()
}

e.EncodeToken(startElement)

if sorted {
sortedNames := []string{}
for k := range node.Children {
sortedNames = append(sortedNames, k)
Expand All @@ -154,6 +167,7 @@ func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
}
}

e.EncodeToken(xml.EndElement{Name: node.Name})
e.EncodeToken(startElement.End())

return e.Flush()
}

0 comments on commit 65c0f3b

Please sign in to comment.