diff options
Diffstat (limited to 'libgo/go/html/template/content.go')
-rw-r--r-- | libgo/go/html/template/content.go | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/libgo/go/html/template/content.go b/libgo/go/html/template/content.go index d720d4ba689..4de7ccde912 100644 --- a/libgo/go/html/template/content.go +++ b/libgo/go/html/template/content.go @@ -6,15 +6,16 @@ package template import ( "fmt" + "reflect" ) // Strings of content from a trusted source. type ( // CSS encapsulates known safe content that matches any of: - // (1) The CSS3 stylesheet production, such as `p { color: purple }`. - // (2) The CSS3 rule production, such as `a[href=~"https:"].foo#bar`. - // (3) CSS3 declaration productions, such as `color: red; margin: 2px`. - // (4) The CSS3 value production, such as `rgba(0, 0, 255, 127)`. + // 1. The CSS3 stylesheet production, such as `p { color: purple }`. + // 2. The CSS3 rule production, such as `a[href=~"https:"].foo#bar`. + // 3. CSS3 declaration productions, such as `color: red; margin: 2px`. + // 4. The CSS3 value production, such as `rgba(0, 0, 255, 127)`. // See http://www.w3.org/TR/css3-syntax/#style CSS string @@ -40,8 +41,8 @@ type ( // JSStr encapsulates a sequence of characters meant to be embedded // between quotes in a JavaScript expression. // The string must match a series of StringCharacters: - // StringCharacter :: SourceCharacter but not `\` or LineTerminator - // | EscapeSequence + // StringCharacter :: SourceCharacter but not `\` or LineTerminator + // | EscapeSequence // Note that LineContinuations are not allowed. // JSStr("foo\\nbar") is fine, but JSStr("foo\\\nbar") is not. JSStr string @@ -70,10 +71,25 @@ const ( contentTypeUnsafe ) +// indirect returns the value, after dereferencing as many times +// as necessary to reach the base type (or nil). +func indirect(a interface{}) interface{} { + if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr { + // Avoid creating a reflect.Value if it's not a pointer. + return a + } + v := reflect.ValueOf(a) + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v.Interface() +} + // stringify converts its arguments to a string and the type of the content. +// All pointers are dereferenced, as in the text/template package. func stringify(args ...interface{}) (string, contentType) { if len(args) == 1 { - switch s := args[0].(type) { + switch s := indirect(args[0]).(type) { case string: return s, contentTypePlain case CSS: @@ -90,5 +106,8 @@ func stringify(args ...interface{}) (string, contentType) { return string(s), contentTypeURL } } + for i, arg := range args { + args[i] = indirect(arg) + } return fmt.Sprint(args...), contentTypePlain } |