diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-30 22:09:55 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-30 22:09:55 +0000 |
commit | 75cd0c848ff1a57a6fa90b79eef180e7a33b0a42 (patch) | |
tree | 26322d11da7cc220190e0b8430565ea207eb3eab /libgo/go/html | |
parent | 5a333029b49a1435961f5e39c5c16294da81e322 (diff) | |
download | gcc-75cd0c848ff1a57a6fa90b79eef180e7a33b0a42.tar.gz |
libgo: Update to weekly.2012-03-22.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186026 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/html')
-rw-r--r-- | libgo/go/html/template/clone_test.go | 33 | ||||
-rw-r--r-- | libgo/go/html/template/content.go | 4 | ||||
-rw-r--r-- | libgo/go/html/template/escape.go | 42 | ||||
-rw-r--r-- | libgo/go/html/template/escape_test.go | 9 | ||||
-rw-r--r-- | libgo/go/html/template/template.go | 34 |
5 files changed, 114 insertions, 8 deletions
diff --git a/libgo/go/html/template/clone_test.go b/libgo/go/html/template/clone_test.go index c612775d4f0..2663cddc24b 100644 --- a/libgo/go/html/template/clone_test.go +++ b/libgo/go/html/template/clone_test.go @@ -113,3 +113,36 @@ func TestClone(t *testing.T) { t.Errorf("t3: got %q want %q", got, want) } } + +func TestTemplates(t *testing.T) { + names := []string{"t0", "a", "lhs", "rhs"} + // Some template definitions borrowed from TestClone. + const tmpl = ` + {{define "a"}}{{template "lhs"}}{{.}}{{template "rhs"}}{{end}} + {{define "lhs"}} <a href=" {{end}} + {{define "rhs"}} "></a> {{end}}` + t0 := Must(New("t0").Parse(tmpl)) + templates := t0.Templates() + if len(templates) != len(names) { + t.Errorf("expected %d templates; got %d", len(names), len(templates)) + } + for _, name := range names { + found := false + for _, tmpl := range templates { + if name == tmpl.text.Name() { + found = true + break + } + } + if !found { + t.Error("could not find template", name) + } + } +} + +// This used to crash; http://golang.org/issue/3281 +func TestCloneCrash(t *testing.T) { + t1 := New("all") + Must(t1.New("t1").Parse(`{{define "foo"}}foo{{end}}`)) + t1.Clone() +} diff --git a/libgo/go/html/template/content.go b/libgo/go/html/template/content.go index 539664f9729..c1bd2e4949b 100644 --- a/libgo/go/html/template/content.go +++ b/libgo/go/html/template/content.go @@ -26,10 +26,10 @@ type ( HTML string // HTMLAttr encapsulates an HTML attribute from a trusted source, - // for example: ` dir="ltr"`. + // for example, ` dir="ltr"`. HTMLAttr string - // JS encapsulates a known safe EcmaScript5 Expression, or example, + // JS encapsulates a known safe EcmaScript5 Expression, for example, // `(x + y * z())`. // Template authors are responsible for ensuring that typed expressions // do not break the intended precedence and that there is no diff --git a/libgo/go/html/template/escape.go b/libgo/go/html/template/escape.go index a058e20d7b3..5f0e28e8c1c 100644 --- a/libgo/go/html/template/escape.go +++ b/libgo/go/html/template/escape.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "html" + "io" "text/template" "text/template/parse" ) @@ -751,3 +752,44 @@ func (e *escaper) template(name string) *template.Template { } return t } + +// Forwarding functions so that clients need only import this package +// to reach the general escaping functions of text/template. + +// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b. +func HTMLEscape(w io.Writer, b []byte) { + template.HTMLEscape(w, b) +} + +// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s. +func HTMLEscapeString(s string) string { + return template.HTMLEscapeString(s) +} + +// HTMLEscaper returns the escaped HTML equivalent of the textual +// representation of its arguments. +func HTMLEscaper(args ...interface{}) string { + return template.HTMLEscaper(args...) +} + +// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. +func JSEscape(w io.Writer, b []byte) { + template.JSEscape(w, b) +} + +// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s. +func JSEscapeString(s string) string { + return template.JSEscapeString(s) +} + +// JSEscaper returns the escaped JavaScript equivalent of the textual +// representation of its arguments. +func JSEscaper(args ...interface{}) string { + return template.JSEscaper(args...) +} + +// URLQueryEscaper returns the escaped value of the textual representation of +// its arguments in a form suitable for embedding in a URL query. +func URLQueryEscaper(args ...interface{}) string { + return template.URLQueryEscaper(args...) +} diff --git a/libgo/go/html/template/escape_test.go b/libgo/go/html/template/escape_test.go index 2bbb1b1bc94..ce12c1795c2 100644 --- a/libgo/go/html/template/escape_test.go +++ b/libgo/go/html/template/escape_test.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "fmt" + "os" "strings" "testing" "text/template" @@ -1637,6 +1638,14 @@ func TestIndirectPrint(t *testing.T) { } } +// This is a test for issue 3272. +func TestEmptyTemplate(t *testing.T) { + page := Must(New("page").ParseFiles(os.DevNull)) + if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil { + t.Fatal("expected error") + } +} + func BenchmarkEscapedExecute(b *testing.B) { tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`)) var buf bytes.Buffer diff --git a/libgo/go/html/template/template.go b/libgo/go/html/template/template.go index b0bae7a54fb..edac7335cfd 100644 --- a/libgo/go/html/template/template.go +++ b/libgo/go/html/template/template.go @@ -31,6 +31,20 @@ type nameSpace struct { set map[string]*Template } +// Templates returns a slice of the templates associated with t, including t +// itself. +func (t *Template) Templates() []*Template { + ns := t.nameSpace + ns.mu.Lock() + defer ns.mu.Unlock() + // Return a slice so we don't expose the map. + m := make([]*Template, 0, len(ns.set)) + for _, v := range ns.set { + m = append(m, v) + } + return m +} + // Execute applies a parsed template to the specified data object, // writing the output to wr. func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { @@ -64,7 +78,13 @@ func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err err t.nameSpace.mu.Lock() defer t.nameSpace.mu.Unlock() tmpl = t.set[name] - if (tmpl == nil) != (t.text.Lookup(name) == nil) { + if tmpl == nil { + return nil, fmt.Errorf("html/template: %q is undefined", name) + } + if tmpl.text.Tree == nil || tmpl.text.Root == nil { + return nil, fmt.Errorf("html/template: %q is an incomplete template", name) + } + if t.text.Lookup(name) == nil { panic("html/template internal error: template escaping out of sync") } if tmpl != nil && !tmpl.escaped { @@ -160,9 +180,11 @@ func (t *Template) Clone() (*Template, error) { if src == nil || src.escaped { return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name()) } - x.Tree = &parse.Tree{ - Name: x.Tree.Name, - Root: x.Tree.Root.CopyList(), + if x.Tree != nil { + x.Tree = &parse.Tree{ + Name: x.Tree.Name, + Root: x.Tree.Root.CopyList(), + } } ret.set[name] = &Template{ false, @@ -274,7 +296,7 @@ func (t *Template) ParseFiles(filenames ...string) (*Template, error) { func parseFiles(t *Template, filenames ...string) (*Template, error) { if len(filenames) == 0 { // Not really a problem, but be consistent. - return nil, fmt.Errorf("template: no files named in call to ParseFiles") + return nil, fmt.Errorf("html/template: no files named in call to ParseFiles") } for _, filename := range filenames { b, err := ioutil.ReadFile(filename) @@ -331,7 +353,7 @@ func parseGlob(t *Template, pattern string) (*Template, error) { return nil, err } if len(filenames) == 0 { - return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) + return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern) } return parseFiles(t, filenames...) } |