diff --git a/src/pkg/exp/template/html/escape.go b/src/pkg/exp/template/html/escape.go index c6156da122..f629930df7 100644 --- a/src/pkg/exp/template/html/escape.go +++ b/src/pkg/exp/template/html/escape.go @@ -100,12 +100,12 @@ type escaper struct { derived map[string]*template.Template // called[templateName] is a set of called mangled template names. called map[string]bool - // actionNodeEdits and templateNodeEdits are the accumulated edits to - // apply during commit. Such edits are not applied immediately in case - // a template set executes a given template in different escaping - // contexts. + // xxxNodeEdits are the accumulated edits to apply during commit. + // Such edits are not applied immediately in case a template set + // executes a given template in different escaping contexts. actionNodeEdits map[*parse.ActionNode][]string templateNodeEdits map[*parse.TemplateNode]string + textNodeEdits map[*parse.TextNode][]byte } // newEscaper creates a blank escaper for the given set. @@ -117,6 +117,7 @@ func newEscaper(s *template.Set) *escaper { map[string]bool{}, map[*parse.ActionNode][]string{}, map[*parse.TemplateNode]string{}, + map[*parse.TextNode][]byte{}, } } @@ -141,7 +142,7 @@ func (e *escaper) escape(c context, n parse.Node) context { case *parse.TemplateNode: return e.escapeTemplate(c, n) case *parse.TextNode: - return e.escapeText(c, n.Text) + return e.escapeText(c, n) case *parse.WithNode: return e.escapeBranch(c, &n.BranchNode, "with") } @@ -386,6 +387,9 @@ func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter f for k, v := range e1.templateNodeEdits { e.editTemplateNode(k, v) } + for k, v := range e1.textNodeEdits { + e.editTextNode(k, v) + } } return c, ok } @@ -493,38 +497,57 @@ var delimEnds = [...]string{ } // escapeText escapes a text template node. -func (e *escaper) escapeText(c context, s []byte) context { +func (e *escaper) escapeText(c context, n *parse.TextNode) context { + s, written := n.Text, 0 + var b bytes.Buffer for len(s) > 0 { - if c.delim == delimNone { - c, s = transitionFunc[c.state](c, s) - continue - } - - i := bytes.IndexAny(s, delimEnds[c.delim]) - if i == -1 { - // Remain inside the attribute. - // Decode the value so non-HTML rules can easily handle - //