Beispiel #1
0
// escapeActionNode adds a pipeline call to the end that escapes the result
// of the expression before it is interpolated into the template output.
func escapeActionNode(node *parse.ActionNode) {
	pipe := node.Pipe

	cmds := pipe.Cmds
	nCmds := len(cmds)

	// If it already has an escaping command, do not interfere.
	if nCmds != 0 {
		if lastCmd := cmds[nCmds-1]; len(lastCmd.Args) != 0 {
			// TODO: Recognize url and js as escaping functions once
			// we have enough context to know whether additional
			// escaping is necessary.
			if arg, ok := lastCmd.Args[0].(*parse.IdentifierNode); ok && arg.Ident == "html" {
				return
			}
		}
	}

	htmlEscapeCommand := parse.CommandNode{
		NodeType: parse.NodeCommand,
		Args:     []parse.Node{parse.NewIdentifier("html")},
	}

	node.Pipe.Cmds = append(node.Pipe.Cmds, &htmlEscapeCommand)
}
Beispiel #2
0
// escapeAction escapes an action template node.
func escapeAction(c context, n *parse.ActionNode) context {
	sanitizer := "html"
	if c.state == stateURL {
		sanitizer = "urlquery"
	}
	// If the pipe already ends with the sanitizer, do not interfere.
	if m := len(n.Pipe.Cmds); m != 0 {
		if last := n.Pipe.Cmds[m-1]; len(last.Args) != 0 {
			if i, ok := last.Args[0].(*parse.IdentifierNode); ok && i.Ident == sanitizer {
				return c
			}
		}
	}
	// Otherwise, append the sanitizer.
	n.Pipe.Cmds = append(n.Pipe.Cmds, &parse.CommandNode{
		NodeType: parse.NodeCommand,
		Args:     []parse.Node{parse.NewIdentifier(sanitizer)},
	})
	return c
}
Beispiel #3
0
// newIdentCmd produces a command containing a single identifier node.
func newIdentCmd(identifier string) *parse.CommandNode {
	return &parse.CommandNode{
		NodeType: parse.NodeCommand,
		Args:     []parse.Node{parse.NewIdentifier(identifier)},
	}
}