func init() { // Articles goweb.MapRest("/article/category/{category_id}", new(controller.ArticleController)) // Articles goweb.MapRest("/article", new(controller.ArticleController)) // Comments goweb.MapRest("/comment", new(controller.CommentController)) // Categories goweb.MapRest("/category", new(controller.CategoryController)) // Logs goweb.MapRest("/log", new(controller.LogController)) // Search goweb.MapRest("/search", new(controller.SearchController)) // Documentation wadl goweb.MapFunc("/documentation/wadl", func(c *goweb.Context) { var docTemplate = template.Must(template.ParseFile("webservice/views/wadl.wadl")) if err := docTemplate.Execute(c.ResponseWriter, nil); err != nil { c.RespondWithErrorMessage(err.String(), http.StatusInternalServerError) } }) // WADL in XML voor XML viewer goweb.MapFunc("/documentation/wadl/xml", func(c *goweb.Context) { var docTemplate = template.Must(template.ParseFile("webservice/views/wadl.xml")) if err := docTemplate.Execute(c.ResponseWriter, nil); err != nil { c.RespondWithErrorMessage(err.String(), http.StatusInternalServerError) } }) // Documentation goweb.MapFunc("/documentation", func(c *goweb.Context) { var docTemplate = template.Must(template.ParseFile("webservice/views/documentation.html")) if err := docTemplate.Execute(c.ResponseWriter, nil); err != nil { c.RespondWithErrorMessage(err.String(), http.StatusInternalServerError) } }) // Index goweb.MapFunc("/", func(c *goweb.Context) { var indexTemplate = template.Must(template.ParseFile("webservice/views/index.html")) if err := indexTemplate.Execute(c.ResponseWriter, nil); err != nil { c.RespondWithErrorMessage(err.String(), http.StatusInternalServerError) } }) // use the default Go handler http.Handle("/", goweb.DefaultHttpHandler) }
func BenchmarkEscapedExecute(b *testing.B) { tmpl := template.Must(Escape(template.Must(template.New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`)))) var buf bytes.Buffer b.ResetTimer() for i := 0; i < b.N; i++ { tmpl.Execute(&buf, "foo & 'bar' & baz") buf.Reset() } }
/* * Run the program * * Usage: * ./ls [args] directory_name * * possible args: * -R: go through directories recursively * -n: print with information * -t: sort files by modification time * * if no arguments are getting, print out alphabetically with 1 file * per line */ func main() { var R *bool var n *bool var t *bool R = flag.Bool("R", false, "go through directories recursively") n = flag.Bool("n", false, "print with information") t = flag.Bool("t", false, "sort files by modification time") flag.Parse() args := flag.Args() if len(args) == 0 { args = []string{"./"} } defer func() { if r := recover(); r != nil { fmt.Fprintln(os.Stderr, "Invalid Arguments") } }() temp := template.Must(template.New("ls").Parse("{{.Mode}} {{printf `%3d` .Nlink}} {{.Uid}} {{.Gid}} {{printf `%7d` .Size}} {{.Mtime}} {{.Name}}\n")) for _, arg := range args { if data, error := ls.Ls(arg, *R, *t); error == nil { path := data[0][0].Name if strings.HasSuffix(path, "/") { path = path[0 : len(path)-1] } printFiles(flag.NArg(), data, path, n, temp) } else { fmt.Fprintln(os.Stderr, "File or directory not found") } } }
func ShowErrors(templateString string) Middleware { if templateString == "" { templateString = ` <html> <body> <p> {{.Error|html}} </p> </body> </html> ` } errorTemplate := template.Must(template.New("error").Parse(templateString)) return func(env Env, app App) (status Status, headers Headers, body Body) { defer func() { if err := recover(); err != nil { buffer := bytes.NewBufferString("") errorTemplate.Execute(buffer, struct{ Error string }{fmt.Sprintf("%s", err)}) status = 500 headers = Headers{} body = Body(buffer.String()) } }() return app(env) } }
func NewRollOff(w http.ResponseWriter, r *http.Request) { rollingUser := ParseUser(r) entry := &RollOffEntry{User: rollingUser, Score: rand.Intn(100) + 1} rolloff := &RollOff{Id: randomString(20), Open: true} rolloff.AddEntry(entry) go rolloff.Cycle() rolloffs = append(rolloffs, rolloff) for elem := room.Users.Front(); elem != nil; elem = elem.Next() { go func(e *list.Element) { var tName string u := e.Value.(*User) if u == rollingUser { tName = "templates/roll-off/rolling-user.html" } else { tName = "templates/roll-off/other-users.html" } t := template.Must(template.ParseFile(tName)) m := NewMessage("system", "", "system") t.Execute(m, entry) u.c <- m }(elem) } }
func EnterRollOff(w http.ResponseWriter, r *http.Request) { id := r.URL.Path[len("/roll-off-entry/"):] fmt.Println("User wishes to enter rolloff ", id) rollingUser := ParseUser(r) entry := &RollOffEntry{User: rollingUser, Score: rand.Intn(100) + 1} for _, r := range rolloffs { fmt.Println("Checking rolloff ", r.Id) if r.Id == id { r.AddEntry(entry) for elem := room.Users.Front(); elem != nil; elem = elem.Next() { go func(e *list.Element) { var tName string u := e.Value.(*User) if u == rollingUser { tName = "templates/roll-off/user-joins.html" } else { tName = "templates/roll-off/other-user-joins.html" } t := template.Must(template.ParseFile(tName)) m := NewMessage("system", "", "system") t.Execute(m, entry) u.c <- m }(elem) } } } }
func TestEscapeErrorsNotIgnorable(t *testing.T) { var b bytes.Buffer tmpl := template.Must(template.New("dangerous").Parse("<a")) Escape(tmpl) err := tmpl.Execute(&b, nil) expectExecuteFailure(t, &b, err) }
func parseTemplate(filename string) *Template { return &Template{ t: template.Must(template.New(filename). Funcs(template.FuncMap{"item": itemFormatter}). ParseFile(path.Join("template", filename))), mimeType: mime.TypeByExtension(path.Ext(filename))} }
func handler(w http.ResponseWriter, r *http.Request) { name := r.FormValue("name") htmltemplate := template.Must(template.New("html").Parse(templateHTML)) err := htmltemplate.Execute(w, name) if err != nil { http.Error(w, err.String(), http.StatusInternalServerError) } }
func root(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) clientTemplate := template.Must(template.ParseFile("client.html")) token_value := strconv.Itoa(rand.Int()) token_key, _ := channel.Create(c, token_value) clientTemplate.Execute(w, token_key) map_clients[token_key] = token_value }
func main() { chatTempl = template.Must(template.New("chat").Parse(chatStr)) go hub() server.Run(":8080", web.NewRouter(). Register("/", "GET", chatFrameHandler). Register("/ws", "GET", chatWsHandler)) }
func init() { for _, name := range []string{"500", "404", "report"} { tmpl := template.Must(template.New(name).ParseFile("jshint/templates/" + name + ".html")) templates[name] = tmpl } http.HandleFunc("/reports/save/", save) http.HandleFunc("/reports/", show) http.HandleFunc("/", notFound) }
func generateFeed(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) feed := GetFeed(c) if feed == nil { http.Error(w, "", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/rss+xml") tpl := template.Must(template.New("feed").Parse(rawtemplate)) tpl.Execute(w, feed) }
func readTemplate(name string) *template.Template { path := filepath.Join(*goroot, "lib", "godoc", name) if *templateDir != "" { defaultpath := path path = filepath.Join(*templateDir, name) if _, err := fs.Stat(path); err != nil { log.Print("readTemplate:", err) path = defaultpath } } return template.Must(template.New(name).Funcs(fmap).ParseFile(path)) }
func init() { layout := template.New("error template") layout.Funcs(fmap) tmpl = template.Must(layout.Parse(` <!DOCTYPE html> <html> <head><title>Error: {{.title | html}}</title></head> <body style='font-style:sans-serif;font-size:10pt;background:#eee'> <div style='border:1px solid #999;background:white;margin: 50px auto;padding:1em 3em;width:600px'> <h2>{{.title | html | n2br}}</h2> <pre style='background:#222;color:#eee;padding:8px 5px;border:1px solid #666'>{{.error | html | n2br}}</pre> </div> </body> </html>`)) ex = regexp.MustCompile("\n") }
func loginGet(w http.ResponseWriter, r *http.Request) { responseType, client, err := params(r) if err != nil { err.WriteTo(w) return } loginTemplate := template.Must(template.ParseFile("fragspace/oauth2/login.xhtml")) loginModel := &LoginModel{ responseType, client.Id, slicelib.Filter(strings.Split(r.FormValue("msgs"), "|"), slicelib.IsNonEmpty), } if err := loginTemplate.Execute(w, loginModel); err != nil { c := appengine.NewContext(r) c.Errorf("%v", err) http.Error(w, err.String(), http.StatusInternalServerError) } }
func main() { runtime.GOMAXPROCS(8) port := "0.0.0.0:8000" room = NewRoom() rolloffs = make([]*RollOff, 0) staticDir := http.Dir("/projects/go/chat/static") staticServer := http.FileServer(staticDir) homeTemplate = template.Must(template.ParseFile("templates/index.html")) http.HandleFunc("/", LogWrap(Home, "Home")) http.HandleFunc("/feed", LogWrap(FeedMux, "FeedMux")) http.HandleFunc("/login", LogWrap(LoginMux, "LoginMux")) http.HandleFunc("/users", LogWrap(GetUsers, "GetUsers")) http.HandleFunc("/roll", LogWrap(Roll, "Roll")) http.HandleFunc("/roll-off", LogWrap(NewRollOff, "NewRollOff")) http.HandleFunc("/roll-off-entry/", LogWrap(EnterRollOff, "EnterRollOff")) http.Handle("/static/", http.StripPrefix("/static", staticServer)) fmt.Printf("Serving at %s ----------------------------------------------------\n", port) http.ListenAndServe(port, nil) }
func TestErrors(t *testing.T) { tests := []struct { input string err string }{ // Non-error cases. { "{{if .Cond}}<a>{{else}}<b>{{end}}", "", }, { "{{if .Cond}}<a>{{end}}", "", }, { "{{if .Cond}}{{else}}<b>{{end}}", "", }, { "{{with .Cond}}<div>{{end}}", "", }, { "{{range .Items}}<a>{{end}}", "", }, { "<a href='/foo?{{range .Items}}&{{.K}}={{.V}}{{end}}'>", "", }, // Error cases. { "{{if .Cond}}<a{{end}}", "z:1: {{if}} branches", }, { "{{if .Cond}}\n{{else}}\n<a{{end}}", "z:1: {{if}} branches", }, { // Missing quote in the else branch. `{{if .Cond}}<a href="foo">{{else}}<a href="bar>{{end}}`, "z:1: {{if}} branches", }, { // Different kind of attribute: href implies a URL. "<a {{if .Cond}}href='{{else}}title='{{end}}{{.X}}'>", "z:1: {{if}} branches", }, { "\n{{with .X}}<a{{end}}", "z:2: {{with}} branches", }, { "\n{{with .X}}<a>{{else}}<a{{end}}", "z:2: {{with}} branches", }, { "{{range .Items}}<a{{end}}", `z:1: on range loop re-entry: "<" in attribute name: "<a"`, }, { "\n{{range .Items}} x='<a{{end}}", "z:2: on range loop re-entry: {{range}} branches", }, { "<a b=1 c={{.H}}", "z: ends in a non-text context: {stateAttr delimSpaceOrTagEnd", }, { "<script>foo();", "z: ends in a non-text context: {stateJS", }, { `<a href="{{if .F}}/foo?a={{else}}/bar/{{end}}{{.H}}">`, "z:1: (action: [(command: [F=[H]])]) appears in an ambiguous URL context", }, { `<a onclick="alert('Hello \`, `unfinished escape sequence in JS string: "Hello \\"`, }, { `<a onclick='alert("Hello\, World\`, `unfinished escape sequence in JS string: "Hello\\, World\\"`, }, { `<a onclick='alert(/x+\`, `unfinished escape sequence in JS string: "x+\\"`, }, { `<a onclick="/foo[\]/`, `unfinished JS regexp charset: "foo[\\]/"`, }, { // It is ambiguous whether 1.5 should be 1\.5 or 1.5. // Either `var x = 1/- 1.5 /i.test(x)` // where `i.test(x)` is a method call of reference i, // or `/-1\.5/i.test(x)` which is a method call on a // case insensitive regular expression. `<script>{{if false}}var x = 1{{end}}/-{{"1.5"}}/i.test(x)</script>`, `'/' could start a division or regexp: "/-"`, }, { `{{template "foo"}}`, "z:1: no such template foo", }, { `{{define "z"}}<div{{template "y"}}>{{end}}` + // Illegal starting in stateTag but not in stateText. `{{define "y"}} foo<b{{end}}`, `"<" in attribute name: " foo<b"`, }, { `{{define "z"}}<script>reverseList = [{{template "t"}}]</script>{{end}}` + // Missing " after recursive call. `{{define "t"}}{{if .Tail}}{{template "t" .Tail}}{{end}}{{.Head}}",{{end}}`, `: cannot compute output context for template t$htmltemplate_stateJS_elementScript`, }, { `<input type=button value=onclick=>`, `exp/template/html:z: "=" in unquoted attr: "onclick="`, }, { `<input type=button value= onclick=>`, `exp/template/html:z: "=" in unquoted attr: "onclick="`, }, { `<input type=button value= 1+1=2>`, `exp/template/html:z: "=" in unquoted attr: "1+1=2"`, }, { "<a class=`foo>", "exp/template/html:z: \"`\" in unquoted attr: \"`foo\"", }, { `<a style=font:'Arial'>`, `exp/template/html:z: "'" in unquoted attr: "font:'Arial'"`, }, { `<a=foo>`, `: expected space, attr name, or end of tag, but got "=foo>"`, }, } for _, test := range tests { var err error if strings.HasPrefix(test.input, "{{define") { var s template.Set _, err = s.Parse(test.input) if err != nil { t.Errorf("Failed to parse %q: %s", test.input, err) continue } _, err = EscapeSet(&s, "z") } else { tmpl := template.Must(template.New("z").Parse(test.input)) _, err = Escape(tmpl) } var got string if err != nil { got = err.Error() } if test.err == "" { if got != "" { t.Errorf("input=%q: unexpected error %q", test.input, got) } continue } if strings.Index(got, test.err) == -1 { t.Errorf("input=%q: error\n\t%q\ndoes not contain expected string\n\t%q", test.input, got, test.err) continue } } }
func TestEnsurePipelineContains(t *testing.T) { tests := []struct { input, output string ids []string }{ { "{{.X}}", "[(command: [F=[X]])]", []string{}, }, { "{{.X | html}}", "[(command: [F=[X]]) (command: [I=html])]", []string{}, }, { "{{.X}}", "[(command: [F=[X]]) (command: [I=html])]", []string{"html"}, }, { "{{.X | html}}", "[(command: [F=[X]]) (command: [I=html]) (command: [I=urlquery])]", []string{"urlquery"}, }, { "{{.X | html | urlquery}}", "[(command: [F=[X]]) (command: [I=html]) (command: [I=urlquery])]", []string{"urlquery"}, }, { "{{.X | html | urlquery}}", "[(command: [F=[X]]) (command: [I=html]) (command: [I=urlquery])]", []string{"html", "urlquery"}, }, { "{{.X | html | urlquery}}", "[(command: [F=[X]]) (command: [I=html]) (command: [I=urlquery])]", []string{"html"}, }, { "{{.X | urlquery}}", "[(command: [F=[X]]) (command: [I=html]) (command: [I=urlquery])]", []string{"html", "urlquery"}, }, { "{{.X | html | print}}", "[(command: [F=[X]]) (command: [I=urlquery]) (command: [I=html]) (command: [I=print])]", []string{"urlquery", "html"}, }, } for _, test := range tests { tmpl := template.Must(template.New("test").Parse(test.input)) action, ok := (tmpl.Tree.Root.Nodes[0].(*parse.ActionNode)) if !ok { t.Errorf("First node is not an action: %s", test.input) continue } pipe := action.Pipe ensurePipelineContains(pipe, test.ids) got := pipe.String() if got != test.output { t.Errorf("%s, %v: want\n\t%s\ngot\n\t%s", test.input, test.ids, test.output, got) } } }
package handlers import ( // "appengine" // "backend/models" "fmt" "http" "template" ) var ( indexTemplate = template.Must(template.ParseFile("frontend/index.html")) ) func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, world!") } func Main(w http.ResponseWriter, r *http.Request) { indexTemplate.Execute(w, nil) }
package components import ( "github.com/skelterjohn/goui" "github.com/skelterjohn/goui/messages" "io" "template" ) const ButtonHTMLTemplateFormat = ` <a href=/m/{{.MName}}>{{.Label}}</a> ` var ButtonHTMLTemplate = template.Must(goui.ParseExecTemplate(ButtonHTMLTemplateFormat)) type ButtonData struct { Label string MName string } type Button struct { data ButtonData dirty bool Click <-chan []byte } func NewButton(label string) (me *Button) { me = new(Button) me.data.Label = label me.data.MName, me.Click = messages.GetMessenger()
var TestmainTemplate = template.Must(template.New("TestSource").Parse( `package main {{range .TestPkgs}}import {{.PkgAlias}} "{{.PkgTarget}}" {{end}} import "testing" import "os" import __regexp__ "regexp" var tests = []testing.InternalTest{ {{range .TestPkgs}}{{if $PkgName=.PkgName}}{{if $PkgAlias=.PkgAlias}}{{range .TestFuncs}} {"{{$PkgName}}.{{.}}", {{$PkgAlias}}.{{.}}},{{end}}{{end}}{{end}}{{end}} } var benchmarks = []testing.InternalBenchmark{ {{range .TestPkgs}}{{if $PkgName=.PkgName}}{{if $PkgAlias=.PkgAlias}}{{range .TestBenchmarks}} {"{{$PkgName}}.{{.}}", {{$PkgAlias}}.{{.}}},{{end}}{{end}}{{end}}{{end}} } var matchPat string var matchRe *__regexp__.Regexp func matchString(pat, str string) (result bool, err os.Error) { if matchRe == nil || matchPat != pat { matchPat = pat matchRe, err = __regexp__.Compile(matchPat) if err != nil { return } } return matchRe.MatchString(str), nil } func main() { testing.Main(matchString, tests, benchmarks) } `))
package components import ( "github.com/skelterjohn/goui" "io" "template" ) const LabelHTMLTemplateFormat = ` Label: {{.Text}} ` var LabelHTMLTemplate = template.Must(goui.ParseExecTemplate(LabelHTMLTemplateFormat)) type LabelData struct { Text string } type Label struct { data LabelData dirty bool } func NewLabel(text string) (me *Label) { me = new(Label) me.data.Text = text return } func (me *Label) SetData(data LabelData) { me.data = data
func TestEscape(t *testing.T) { var data = struct { F, T bool C, G, H string A, E []string B, M json.Marshaler N int Z *int W HTML }{ F: false, T: true, C: "<Cincinatti>", G: "<Goodbye>", H: "<Hello>", A: []string{"<a>", "<b>"}, E: []string{}, N: 42, B: &badMarshaler{}, M: &goodMarshaler{}, Z: nil, W: HTML(`¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`), } tests := []struct { name string input string output string }{ { "if", "{{if .T}}Hello{{end}}, {{.C}}!", "Hello, <Cincinatti>!", }, { "else", "{{if .F}}{{.H}}{{else}}{{.G}}{{end}}!", "<Goodbye>!", }, { "overescaping1", "Hello, {{.C | html}}!", "Hello, <Cincinatti>!", }, { "overescaping2", "Hello, {{html .C}}!", "Hello, <Cincinatti>!", }, { "overescaping3", "{{with .C}}{{$msg := .}}Hello, {{$msg}}!{{end}}", "Hello, <Cincinatti>!", }, { "assignment", "{{if $x := .H}}{{$x}}{{end}}", "<Hello>", }, { "withBody", "{{with .H}}{{.}}{{end}}", "<Hello>", }, { "withElse", "{{with .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>", }, { "rangeBody", "{{range .A}}{{.}}{{end}}", "<a><b>", }, { "rangeElse", "{{range .E}}{{.}}{{else}}{{.H}}{{end}}", "<Hello>", }, { "nonStringValue", "{{.T}}", "true", }, { "constant", `<a href="/search?q={{"'a<b'"}}">`, `<a href="/search?q=%27a%3cb%27">`, }, { "multipleAttrs", "<a b=1 c={{.H}}>", "<a b=1 c=<Hello>>", }, { "urlStartRel", `<a href='{{"/foo/bar?a=b&c=d"}}'>`, `<a href='/foo/bar?a=b&c=d'>`, }, { "urlStartAbsOk", `<a href='{{"http://example.com/foo/bar?a=b&c=d"}}'>`, `<a href='http://example.com/foo/bar?a=b&c=d'>`, }, { "protocolRelativeURLStart", `<a href='{{"//example.com:8000/foo/bar?a=b&c=d"}}'>`, `<a href='//example.com:8000/foo/bar?a=b&c=d'>`, }, { "pathRelativeURLStart", `<a href="{{"/javascript:80/foo/bar"}}">`, `<a href="/javascript:80/foo/bar">`, }, { "dangerousURLStart", `<a href='{{"javascript:alert(%22pwned%22)"}}'>`, `<a href='#ZgotmplZ'>`, }, { "dangerousURLStart2", `<a href=' {{"javascript:alert(%22pwned%22)"}}'>`, `<a href=' #ZgotmplZ'>`, }, { "nonHierURL", `<a href={{"mailto:Muhammed \"The Greatest\" Ali <*****@*****.**>"}}>`, `<a href=mailto:Muhammed%20%22The%20Greatest%22%20Ali%20%[email protected]%3e>`, }, { "urlPath", `<a href='http://{{"javascript:80"}}/foo'>`, `<a href='http://javascript:80/foo'>`, }, { "urlQuery", `<a href='/search?q={{.H}}'>`, `<a href='/search?q=%3cHello%3e'>`, }, { "urlFragment", `<a href='/faq#{{.H}}'>`, `<a href='/faq#%3cHello%3e'>`, }, { "urlBranch", `<a href="{{if .F}}/foo?a=b{{else}}/bar{{end}}">`, `<a href="/bar">`, }, { "urlBranchConflictMoot", `<a href="{{if .T}}/foo?a={{else}}/bar#{{end}}{{.C}}">`, `<a href="/foo?a=%3cCincinatti%3e">`, }, { "jsStrValue", "<button onclick='alert({{.H}})'>", `<button onclick='alert("\u003cHello\u003e")'>`, }, { "jsNumericValue", "<button onclick='alert({{.N}})'>", `<button onclick='alert( 42 )'>`, }, { "jsBoolValue", "<button onclick='alert({{.T}})'>", `<button onclick='alert( true )'>`, }, { "jsNilValue", "<button onclick='alert(typeof{{.Z}})'>", `<button onclick='alert(typeof null )'>`, }, { "jsObjValue", "<button onclick='alert({{.A}})'>", `<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`, }, { "jsObjValueScript", "<script>alert({{.A}})</script>", `<script>alert(["\u003ca\u003e","\u003cb\u003e"])</script>`, }, { "jsObjValueNotOverEscaped", "<button onclick='alert({{.A | html}})'>", `<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`, }, { "jsStr", "<button onclick='alert("{{.H}}")'>", `<button onclick='alert("\x3cHello\x3e")'>`, }, { "badMarshaller", `<button onclick='alert(1/{{.B}}in numbers)'>`, `<button onclick='alert(1/ /* json: error calling MarshalJSON for type *html.badMarshaler: invalid character 'f' looking for beginning of object key string */null in numbers)'>`, }, { "jsMarshaller", `<button onclick='alert({{.M}})'>`, `<button onclick='alert({"<foo>":"O'Reilly"})'>`, }, { "jsStrNotUnderEscaped", "<button onclick='alert({{.C | urlquery}})'>", // URL escaped, then quoted for JS. `<button onclick='alert("%3CCincinatti%3E")'>`, }, { "jsRe", `<button onclick='alert(/{{"foo+bar"}}/.test(""))'>`, `<button onclick='alert(/foo\x2bbar/.test(""))'>`, }, { "jsReBlank", `<script>alert(/{{""}}/.test(""));</script>`, `<script>alert(/(?:)/.test(""));</script>`, }, { "jsReAmbigOk", `<script>{{if true}}var x = 1{{end}}</script>`, // The {if} ends in an ambiguous jsCtx but there is // no slash following so we shouldn't care. `<script>var x = 1</script>`, }, { "styleBidiKeywordPassed", `<p style="dir: {{"ltr"}}">`, `<p style="dir: ltr">`, }, { "styleBidiPropNamePassed", `<p style="border-{{"left"}}: 0; border-{{"right"}}: 1in">`, `<p style="border-left: 0; border-right: 1in">`, }, { "styleExpressionBlocked", `<p style="width: {{"expression(alert(1337))"}}">`, `<p style="width: ZgotmplZ">`, }, { "styleTagSelectorPassed", `<style>{{"p"}} { color: pink }</style>`, `<style>p { color: pink }</style>`, }, { "styleIDPassed", `<style>p{{"#my-ID"}} { font: Arial }</style>`, `<style>p#my-ID { font: Arial }</style>`, }, { "styleClassPassed", `<style>p{{".my_class"}} { font: Arial }</style>`, `<style>p.my_class { font: Arial }</style>`, }, { "styleQuantityPassed", `<a style="left: {{"2em"}}; top: {{0}}">`, `<a style="left: 2em; top: 0">`, }, { "stylePctPassed", `<table style=width:{{"100%"}}>`, `<table style=width:100%>`, }, { "styleColorPassed", `<p style="color: {{"#8ff"}}; background: {{"#000"}}">`, `<p style="color: #8ff; background: #000">`, }, { "styleObfuscatedExpressionBlocked", `<p style="width: {{" e\78preS\0Sio/**/n(alert(1337))"}}">`, `<p style="width: ZgotmplZ">`, }, { "styleMozBindingBlocked", `<p style="{{"-moz-binding(alert(1337))"}}: ...">`, `<p style="ZgotmplZ: ...">`, }, { "styleObfuscatedMozBindingBlocked", `<p style="{{" -mo\7a-B\0I/**/nding(alert(1337))"}}: ...">`, `<p style="ZgotmplZ: ...">`, }, { "styleFontNameString", `<p style='font-family: "{{"Times New Roman"}}"'>`, `<p style='font-family: "Times New Roman"'>`, }, { "styleFontNameString", `<p style='font-family: "{{"Times New Roman"}}", "{{"sans-serif"}}"'>`, `<p style='font-family: "Times New Roman", "sans-serif"'>`, }, { "styleFontNameUnquoted", `<p style='font-family: {{"Times New Roman"}}'>`, `<p style='font-family: Times New Roman'>`, }, { "styleURLQueryEncoded", `<p style="background: url(/img?name={{"O'Reilly Animal(1)<2>.png"}})">`, `<p style="background: url(/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png)">`, }, { "styleQuotedURLQueryEncoded", `<p style="background: url('/img?name={{"O'Reilly Animal(1)<2>.png"}}')">`, `<p style="background: url('/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png')">`, }, { "styleStrQueryEncoded", `<p style="background: '/img?name={{"O'Reilly Animal(1)<2>.png"}}'">`, `<p style="background: '/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png'">`, }, { "styleURLBadProtocolBlocked", `<a style="background: url('{{"javascript:alert(1337)"}}')">`, `<a style="background: url('#ZgotmplZ')">`, }, { "styleStrBadProtocolBlocked", `<a style="background: '{{"vbscript:alert(1337)"}}'">`, `<a style="background: '#ZgotmplZ'">`, }, { "styleStrEncodedProtocolEncoded", `<a style="background: '{{"javascript\\3a alert(1337)"}}'">`, // The CSS string 'javascript\\3a alert(1337)' does not contains a colon. `<a style="background: 'javascript\\3a alert\28 1337\29 '">`, }, { "styleURLGoodProtocolPassed", `<a style="background: url('{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}')">`, `<a style="background: url('http://oreilly.com/O%27Reilly%20Animals%281%29%3c2%3e;%7b%7d.html')">`, }, { "styleStrGoodProtocolPassed", `<a style="background: '{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}'">`, `<a style="background: 'http\3a\2f\2foreilly.com\2fO\27Reilly Animals\28 1\29\3c 2\3e\3b\7b\7d.html'">`, }, { "styleURLEncodedForHTMLInAttr", `<a style="background: url('{{"/search?img=foo&size=icon"}}')">`, `<a style="background: url('/search?img=foo&size=icon')">`, }, { "styleURLNotEncodedForHTMLInCdata", `<style>body { background: url('{{"/search?img=foo&size=icon"}}') }</style>`, `<style>body { background: url('/search?img=foo&size=icon') }</style>`, }, { "styleURLMixedCase", `<p style="background: URL(#{{.H}})">`, `<p style="background: URL(#%3cHello%3e)">`, }, { "stylePropertyPairPassed", `<a style='{{"color: red"}}'>`, `<a style='color: red'>`, }, { "styleStrSpecialsEncoded", `<a style="font-family: '{{"/**/'\";:// \\"}}', "{{"/**/'\";:// \\"}}"">`, `<a style="font-family: '\2f**\2f\27\22\3b\3a\2f\2f \\', "\2f**\2f\27\22\3b\3a\2f\2f \\"">`, }, { "styleURLSpecialsEncoded", `<a style="border-image: url({{"/**/'\";:// \\"}}), url("{{"/**/'\";:// \\"}}"), url('{{"/**/'\";:// \\"}}'), 'http://www.example.com/?q={{"/**/'\";:// \\"}}''">`, `<a style="border-image: url(/**/%27%22;://%20%5c), url("/**/%27%22;://%20%5c"), url('/**/%27%22;://%20%5c'), 'http://www.example.com/?q=%2f%2a%2a%2f%27%22%3b%3a%2f%2f%20%5c''">`, }, { "HTML comment", "<b>Hello, <!-- name of world -->{{.C}}</b>", "<b>Hello, <Cincinatti></b>", }, { "HTML comment not first < in text node.", "<<!-- -->!--", "<!--", }, { "HTML normalization 1", "a < b", "a < b", }, { "HTML normalization 2", "a << b", "a << b", }, { "HTML normalization 3", "a<<!-- --><!-- -->b", "a<b", }, { "HTML doctype not normalized", "<!DOCTYPE html>Hello, World!", "<!DOCTYPE html>Hello, World!", }, { "No doctype injection", `<!{{"DOCTYPE"}}`, "<!DOCTYPE", }, { "Split HTML comment", "<b>Hello, <!-- name of {{if .T}}city -->{{.C}}{{else}}world -->{{.W}}{{end}}</b>", "<b>Hello, <Cincinatti></b>", }, { "JS line comment", "<script>for (;;) { if (c()) break// foo not a label\n" + "foo({{.T}});}</script>", "<script>for (;;) { if (c()) break\n" + "foo( true );}</script>", }, { "JS multiline block comment", "<script>for (;;) { if (c()) break/* foo not a label\n" + " */foo({{.T}});}</script>", // Newline separates break from call. If newline // removed, then break will consume label leaving // code invalid. "<script>for (;;) { if (c()) break\n" + "foo( true );}</script>", }, { "JS single-line block comment", "<script>for (;;) {\n" + "if (c()) break/* foo a label */foo;" + "x({{.T}});}</script>", // Newline separates break from call. If newline // removed, then break will consume label leaving // code invalid. "<script>for (;;) {\n" + "if (c()) break foo;" + "x( true );}</script>", }, { "JS block comment flush with mathematical division", "<script>var a/*b*//c\nd</script>", "<script>var a /c\nd</script>", }, { "JS mixed comments", "<script>var a/*b*///c\nd</script>", "<script>var a \nd</script>", }, { "CSS comments", "<style>p// paragraph\n" + `{border: 1px/* color */{{"#00f"}}}</style>`, "<style>p\n" + "{border: 1px #00f}</style>", }, { "JS attr block comment", `<a onclick="f(""); /* alert({{.H}}) */">`, // Attribute comment tests should pass if the comments // are successfully elided. `<a onclick="f(""); /* alert() */">`, }, { "JS attr line comment", `<a onclick="// alert({{.G}})">`, `<a onclick="// alert()">`, }, { "CSS attr block comment", `<a style="/* color: {{.H}} */">`, `<a style="/* color: */">`, }, { "CSS attr line comment", `<a style="// color: {{.G}}">`, `<a style="// color: ">`, }, { "HTML substitution commented out", "<p><!-- {{.H}} --></p>", "<p></p>", }, { "Comment ends flush with start", "<!--{{.}}--><script>/*{{.}}*///{{.}}\n</script><style>/*{{.}}*///{{.}}\n</style><a onclick='/*{{.}}*///{{.}}' style='/*{{.}}*///{{.}}'>", "<script> \n</script><style> \n</style><a onclick='/**///' style='/**///'>", }, { "typed HTML in text", `{{.W}}`, `¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`, }, { "typed HTML in attribute", `<div title="{{.W}}">`, `<div title="¡Hello, O'World!">`, }, { "typed HTML in script", `<button onclick="alert({{.W}})">`, `<button onclick="alert("&iexcl;\u003cb class=\"foo\"\u003eHello\u003c/b\u003e, \u003ctextarea\u003eO'World\u003c/textarea\u003e!")">`, }, { "typed HTML in RCDATA", `<textarea>{{.W}}</textarea>`, `<textarea>¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!</textarea>`, }, { "range in textarea", "<textarea>{{range .A}}{{.}}{{end}}</textarea>", "<textarea><a><b></textarea>", }, { "auditable exemption from escaping", "{{range .A}}{{. | noescape}}{{end}}", "<a><b>", }, { "No tag injection", `{{"10$"}}<{{"script src,evil.org/pwnd.js"}}...`, `10$<script src,evil.org/pwnd.js...`, }, { "No comment injection", `<{{"!--"}}`, `<!--`, }, { "No RCDATA end tag injection", `<textarea><{{"/textarea "}}...</textarea>`, `<textarea></textarea ...</textarea>`, }, { "optional attrs", `<img class="{{"iconClass"}}"` + `{{if .T}} id="{{"<iconId>"}}"{{end}}` + // Double quotes inside if/else. ` src=` + `{{if .T}}"?{{"<iconPath>"}}"` + `{{else}}"images/cleardot.gif"{{end}}` + // Missing space before title, but it is not a // part of the src attribute. `{{if .T}}title="{{"<title>"}}"{{end}}` + // Quotes outside if/else. ` alt="` + `{{if .T}}{{"<alt>"}}` + `{{else}}{{if .F}}{{"<title>"}}{{end}}` + `{{end}}"` + `>`, `<img class="iconClass" id="<iconId>" src="?%3ciconPath%3e"title="<title>" alt="<alt>">`, }, { "conditional valueless attr name", `<input{{if .T}} checked{{end}} name=n>`, `<input checked name=n>`, }, { "conditional dynamic valueless attr name 1", `<input{{if .T}} {{"checked"}}{{end}} name=n>`, `<input checked name=n>`, }, { "conditional dynamic valueless attr name 2", `<input {{if .T}}{{"checked"}} {{end}}name=n>`, `<input checked name=n>`, }, { "dynamic attribute name", `<img on{{"load"}}="alert({{"loaded"}})">`, // Treated as JS since quotes are inserted. `<img onload="alert("loaded")">`, }, { "bad dynamic attribute name 1", // Allow checked, selected, disabled, but not JS or // CSS attributes. `<input {{"onchange"}}="{{"doEvil()"}}">`, `<input ZgotmplZ="doEvil()">`, }, { "bad dynamic attribute name 2", `<div {{"sTyle"}}="{{"color: expression(alert(1337))"}}">`, `<div ZgotmplZ="color: expression(alert(1337))">`, }, { "bad dynamic attribute name 3", // Allow title or alt, but not a URL. `<img {{"src"}}="{{"javascript:doEvil()"}}">`, `<img ZgotmplZ="javascript:doEvil()">`, }, { "bad dynamic attribute name 4", // Structure preservation requires values to associate // with a consistent attribute. `<input checked {{""}}="Whose value am I?">`, `<input checked ZgotmplZ="Whose value am I?">`, }, { "dynamic element name", `<h{{3}}><table><t{{"head"}}>...</h{{3}}>`, `<h3><table><thead>...</h3>`, }, { "bad dynamic element name", // Dynamic element names are typically used to switch // between (thead, tfoot, tbody), (ul, ol), (th, td), // and other replaceable sets. // We do not currently easily support (ul, ol). // If we do change to support that, this test should // catch failures to filter out special tag names which // would violate the structure preservation property -- // if any special tag name could be substituted, then // the content could be raw text/RCDATA for some inputs // and regular HTML content for others. `<{{"script"}}>{{"doEvil()"}}</{{"script"}}>`, `<script>doEvil()</script>`, }, } for _, test := range tests { tmpl := template.New(test.name) // TODO: Move noescape into template/func.go tmpl.Funcs(template.FuncMap{ "noescape": func(a ...interface{}) string { return fmt.Sprint(a...) }, }) tmpl = template.Must(Escape(template.Must(tmpl.Parse(test.input)))) b := new(bytes.Buffer) if err := tmpl.Execute(b, data); err != nil { t.Errorf("%s: template execution failed: %s", test.name, err) continue } if w, g := test.output, b.String(); w != g { t.Errorf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g) continue } } }
func TestEscapeSet(t *testing.T) { type dataItem struct { Children []*dataItem X string } data := dataItem{ Children: []*dataItem{ &dataItem{X: "foo"}, &dataItem{X: "<bar>"}, &dataItem{ Children: []*dataItem{ &dataItem{X: "baz"}, }, }, }, } tests := []struct { inputs map[string]string want string }{ // The trivial set. { map[string]string{ "main": ``, }, ``, }, // A template called in the start context. { map[string]string{ "main": `Hello, {{template "helper"}}!`, // Not a valid top level HTML template. // "<b" is not a full tag. "helper": `{{"<World>"}}`, }, `Hello, <World>!`, }, // A template called in a context other than the start. { map[string]string{ "main": `<a onclick='a = {{template "helper"}};'>`, // Not a valid top level HTML template. // "<b" is not a full tag. "helper": `{{"<a>"}}<b`, }, `<a onclick='a = "\u003ca\u003e"<b;'>`, }, // A recursive template that ends in its start context. { map[string]string{ "main": `{{range .Children}}{{template "main" .}}{{else}}{{.X}} {{end}}`, }, `foo <bar> baz `, }, // A recursive helper template that ends in its start context. { map[string]string{ "main": `{{template "helper" .}}`, "helper": `{{if .Children}}<ul>{{range .Children}}<li>{{template "main" .}}</li>{{end}}</ul>{{else}}{{.X}}{{end}}`, }, `<ul><li>foo</li><li><bar></li><li><ul><li>baz</li></ul></li></ul>`, }, // Co-recursive templates that end in its start context. { map[string]string{ "main": `<blockquote>{{range .Children}}{{template "helper" .}}{{end}}</blockquote>`, "helper": `{{if .Children}}{{template "main" .}}{{else}}{{.X}}<br>{{end}}`, }, `<blockquote>foo<br><bar><br><blockquote>baz<br></blockquote></blockquote>`, }, // A template that is called in two different contexts. { map[string]string{ "main": `<button onclick="title='{{template "helper"}}'; ...">{{template "helper"}}</button>`, "helper": `{{11}} of {{"<100>"}}`, }, `<button onclick="title='11 of \x3c100\x3e'; ...">11 of <100></button>`, }, // A non-recursive template that ends in a different context. // helper starts in jsCtxRegexp and ends in jsCtxDivOp. { map[string]string{ "main": `<script>var x={{template "helper"}}/{{"42"}};</script>`, "helper": "{{126}}", }, `<script>var x= 126 /"42";</script>`, }, // A recursive template that ends in a similar context. { map[string]string{ "main": `<script>var x=[{{template "countdown" 4}}];</script>`, "countdown": `{{.}}{{if .}},{{template "countdown" . | pred}}{{end}}`, }, `<script>var x=[ 4 , 3 , 2 , 1 , 0 ];</script>`, }, // A recursive template that ends in a different context. /* { map[string]string{ "main": `<a href="/foo{{template "helper" .}}">`, "helper": `{{if .Children}}{{range .Children}}{{template "helper" .}}{{end}}{{else}}?x={{.X}}{{end}}`, }, `<a href="/foo?x=foo?x=%3cbar%3e?x=baz">`, }, */ } // pred is a template function that returns the predecessor of a // natural number for testing recursive templates. fns := template.FuncMap{"pred": func(a ...interface{}) (interface{}, error) { if len(a) == 1 { if i, _ := a[0].(int); i > 0 { return i - 1, nil } } return nil, fmt.Errorf("undefined pred(%v)", a) }} for _, test := range tests { var s template.Set for name, src := range test.inputs { t := template.New(name) t.Funcs(fns) s.Add(template.Must(t.Parse(src))) } s.Funcs(fns) if _, err := EscapeSet(&s, "main"); err != nil { t.Errorf("%s for input:\n%v", err, test.inputs) continue } var b bytes.Buffer if err := s.Execute(&b, "main", data); err != nil { t.Errorf("%q executing %v", err.Error(), s.Template("main")) continue } if got := b.String(); test.want != got { t.Errorf("want\n\t%q\ngot\n\t%q", test.want, got) } } }
package controller import ( "appengine" "fmt" "http" "model" "strconv" "template" ) var detailTemplate = template.Must(template.New("detail").ParseFile("view/detail.html")) type detail_view struct { Group model.Group Member []model.Member } func view(w http.ResponseWriter, r *http.Request) { id, _ := strconv.Atoi(r.FormValue("id")) c := appengine.NewContext(r) var view detail_view // グループ情報を取得 if group, err := model.GetGroup(c, id); err != nil { http.Error(w, err.String(), http.StatusInternalServerError) return } else {
for i := range color_ { // Use a broader range of color for low intensities. if i < 255/10 { color_[i] = color.RGBA{uint8(i * 10), 0, 0, 0xFF} } else { color_[i] = color.RGBA{0xFF, 0, uint8(i - 255/10), 0xFF} } } } var ( // color is the mapping of intensity to color. color_ [256]color.Color frontPageTmpl = template.Must(template.ParseFile("map.html")) ) const ( // The number of iterations of the Mandelbrot calculation. // More iterations mean higher quality at the cost of more CPU time. iterations = 400 // Each tile is 256 pixels wide and 256 pixels high. tileSize = 256 // The maximum zoom level at which to use memcache. maxMemcacheLevel = 8 ) func frontPageHandler(w http.ResponseWriter, r *http.Request) { b := new(bytes.Buffer) data := map[string]interface{}{
Service {{.Name}} <hr> <table> <th align=center>Method</th><th align=center>Calls</th> {{range .Method}} <tr> <td align=left font=fixed>{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) os.Error</td> <td align=center>{{.Type.NumCalls}}</td> </tr> {{end}} </table> {{end}} </body> </html>` var debug = template.Must(template.New("RPC debug").Parse(debugText)) type debugMethod struct { Type *methodType Name string } type methodArray []debugMethod type debugService struct { Service *service Name string Method methodArray } type serviceArray []debugService
func init() { for _, tmpl := range []string{"edit", "view"} { t := template.Must(template.ParseFile(tmpl + ".html")) templates[tmpl] = t } }
http.HandleFunc("/lengthen", handleLengthen) http.ListenAndServe("localhost:8080", nil) } //the template used to show the forms and the results web page to the user var rootHtmlTmpl = template.Must(template.New("rootHtml").Parse(` <html><body> <h1>My URL Shrtnr</h1> {{if .}} {{.}}<br /><br />{{end}} <form action"/shorten" type="POST"> Shorten this: <input type="text" name="longUrl" /> <input type="submit" value="Give me short URL" /> </form> <br /> <form action="/lengthen"type="POST"> Expand this: http://goo.gl/<input type="text" name="shortURL" /> <input type="submit" value="Give me long URL" /> </form> </body></html> `)) func handleRoot(w http.ResponseWriter, r *http.Request) { rootHtmlTmpl.Execute(w, nil) } func handleShorten(w http.ResponseWriter, r *http.Request) { longUrl := r.FormValue("longUrl") //get the value of the text field with the name longUrl in the form urlshortenerSvc, _ := urlshortener.New(http.DefaultFClient) //use the default client that is available in the http package and create a new instance of the url shortener service