From 3f6b91b1136e25e75da71b727e536ba4f4066fd5 Mon Sep 17 00:00:00 2001 From: Charles Weill Date: Fri, 23 Oct 2015 16:08:20 -0400 Subject: encoding/xml: Add CDATA-wrapper output support to xml.Marshal. Fixes #12963 Change-Id: Icc50dfb6130fe1e189d45f923c2f7408d3cf9401 Reviewed-on: https://go-review.googlesource.com/16047 Reviewed-by: Russ Cox --- src/encoding/xml/xml.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/encoding/xml/xml.go') diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go index 6c7debe521..bd766a6934 100644 --- a/src/encoding/xml/xml.go +++ b/src/encoding/xml/xml.go @@ -1943,6 +1943,46 @@ func Escape(w io.Writer, s []byte) { EscapeText(w, s) } +var ( + cdataStart = []byte("") + cdataEscape = []byte("]]]]>") +) + +// emitCDATA writes to w the CDATA-wrapped plain text data s. +// It escapes CDATA directives nested in s. +func emitCDATA(w io.Writer, s []byte) error { + if len(s) == 0 { + return nil + } + if _, err := w.Write(cdataStart); err != nil { + return err + } + for { + i := bytes.Index(s, cdataEnd) + if i >= 0 && i+len(cdataEnd) <= len(s) { + // Found a nested CDATA directive end. + if _, err := w.Write(s[:i]); err != nil { + return err + } + if _, err := w.Write(cdataEscape); err != nil { + return err + } + i += len(cdataEnd) + } else { + if _, err := w.Write(s); err != nil { + return err + } + break + } + s = s[i:] + } + if _, err := w.Write(cdataEnd); err != nil { + return err + } + return nil +} + // procInst parses the `param="..."` or `param='...'` // value out of the provided string, returning "" if not found. func procInst(param, s string) string { -- cgit v1.3-5-g9baa