Skip to content

Commit

Permalink
encoding/xml: rewrite invalid code points to U FFFD in Marshal, Escape
Browse files Browse the repository at this point in the history
Fixes #4235.

R=rsc, dave, r, dr.volker.dobler
CC=golang-dev
https://golang.org/cl/7438051
  • Loading branch information
osaingre authored and rsc committed Mar 14, 2013
1 parent e778f93 commit f74eb6d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
15 changes: 11 additions & 4 deletions src/pkg/encoding/xml/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -1729,15 1729,18 @@ var (
esc_tab = []byte("	")
esc_nl = []byte("
")
esc_cr = []byte("
")
esc_fffd = []byte("\uFFFD") // Unicode replacement character
)

// EscapeText writes to w the properly escaped XML equivalent
// of the plain text data s.
func EscapeText(w io.Writer, s []byte) error {
var esc []byte
last := 0
for i, c := range s {
switch c {
for i := 0; i < len(s); {
r, width := utf8.DecodeRune(s[i:])
i = width
switch r {
case '"':
esc = esc_quot
case '\'':
Expand All @@ -1755,15 1758,19 @@ func EscapeText(w io.Writer, s []byte) error {
case '\r':
esc = esc_cr
default:
if !isInCharacterRange(r) {
esc = esc_fffd
break
}
continue
}
if _, err := w.Write(s[last:i]); err != nil {
if _, err := w.Write(s[last : i-width]); err != nil {
return err
}
if _, err := w.Write(esc); err != nil {
return err
}
last = i 1
last = i
}
if _, err := w.Write(s[last:]); err != nil {
return err
Expand Down
18 changes: 17 additions & 1 deletion src/pkg/encoding/xml/xml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,7 @@
package xml

import (
"bytes"
"fmt"
"io"
"reflect"
Expand Down Expand Up @@ -695,6 696,21 @@ func TestEscapeTextIOErrors(t *testing.T) {
err := EscapeText(errWriter{}, []byte{'A'})

if err == nil || err.Error() != expectErr {
t.Errorf("EscapeTest = [error] %v, want %v", err, expectErr)
t.Errorf("have %v, want %v", err, expectErr)
}
}

func TestEscapeTextInvalidChar(t *testing.T) {
input := []byte("A \x00 terminated string.")
expected := "A \uFFFD terminated string."

buff := new(bytes.Buffer)
if err := EscapeText(buff, input); err != nil {
t.Fatalf("have %v, want nil", err)
}
text := buff.String()

if text != expected {
t.Errorf("have %v, want %v", text, expected)
}
}

0 comments on commit f74eb6d

Please sign in to comment.