diff options
author | Bjørn Erik Pedersen <[email protected]> | 2021-01-29 17:15:42 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2021-02-18 14:11:48 +0100 |
commit | ccb822eb5afad210432eb46ec3727e3536a87f58 (patch) | |
tree | af8976d5b89af36385f0e0ff590239b00dcb5afd /tpl/internal | |
parent | 21e9eb18acc2a2f8d8b97f096615b836e65091a2 (diff) | |
download | hugo-ccb822eb5afad210432eb46ec3727e3536a87f58.tar.gz hugo-ccb822eb5afad210432eb46ec3727e3536a87f58.zip |
Pull in latest Go template source
Diffstat (limited to 'tpl/internal')
10 files changed, 156 insertions, 19 deletions
diff --git a/tpl/internal/go_templates/htmltemplate/examplefiles_test.go b/tpl/internal/go_templates/htmltemplate/examplefiles_test.go index ae763184e..4c693fba3 100644 --- a/tpl/internal/go_templates/htmltemplate/examplefiles_test.go +++ b/tpl/internal/go_templates/htmltemplate/examplefiles_test.go @@ -8,7 +8,6 @@ package template_test import ( "io" - "io/ioutil" "log" "os" "path/filepath" @@ -23,7 +22,7 @@ type templateFile struct { } func createTestDir(files []templateFile) string { - dir, err := ioutil.TempDir("", "template") + dir, err := os.MkdirTemp("", "template") if err != nil { log.Fatal(err) } diff --git a/tpl/internal/go_templates/htmltemplate/exec_test.go b/tpl/internal/go_templates/htmltemplate/exec_test.go index 7af582958..cfca536b4 100644 --- a/tpl/internal/go_templates/htmltemplate/exec_test.go +++ b/tpl/internal/go_templates/htmltemplate/exec_test.go @@ -13,9 +13,11 @@ import ( "errors" "flag" "fmt" + htmltemplate "html/template" "io" "reflect" "strings" + "sync" "testing" template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate" @@ -1709,3 +1711,127 @@ func TestIssue31810(t *testing.T) { t.Errorf("%s got %q, expected %q", textCall, b.String(), "result") } } + +// Issue 39807. There was a race applying escapeTemplate. + +const raceText = ` +{{- define "jstempl" -}} +var v = "v"; +{{- end -}} +<script type="application/javascript"> +{{ template "jstempl" $ }} +</script> +` + +func TestEscapeRace(t *testing.T) { + t.Skip("this test currently fails with -race; see issue #39807") + + tmpl := New("") + _, err := tmpl.New("templ.html").Parse(raceText) + if err != nil { + t.Fatal(err) + } + const count = 20 + for i := 0; i < count; i++ { + _, err := tmpl.New(fmt.Sprintf("x%d.html", i)).Parse(`{{ template "templ.html" .}}`) + if err != nil { + t.Fatal(err) + } + } + + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for j := 0; j < count; j++ { + sub := tmpl.Lookup(fmt.Sprintf("x%d.html", j)) + if err := sub.Execute(io.Discard, nil); err != nil { + t.Error(err) + } + } + }() + } + wg.Wait() +} + +func TestRecursiveExecute(t *testing.T) { + tmpl := New("") + + recur := func() (htmltemplate.HTML, error) { + var sb strings.Builder + if err := tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil { + t.Fatal(err) + } + return htmltemplate.HTML(sb.String()), nil + } + + m := FuncMap{ + "recur": recur, + } + + top, err := tmpl.New("x.html").Funcs(m).Parse(`{{recur}}`) + if err != nil { + t.Fatal(err) + } + _, err = tmpl.New("subroutine").Parse(`<a href="/x?p={{"'a<b'"}}">`) + if err != nil { + t.Fatal(err) + } + if err := top.Execute(io.Discard, nil); err != nil { + t.Fatal(err) + } +} + +// recursiveInvoker is for TestRecursiveExecuteViaMethod. +type recursiveInvoker struct { + t *testing.T + tmpl *Template +} + +func (r *recursiveInvoker) Recur() (string, error) { + var sb strings.Builder + if err := r.tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil { + r.t.Fatal(err) + } + return sb.String(), nil +} + +func TestRecursiveExecuteViaMethod(t *testing.T) { + tmpl := New("") + top, err := tmpl.New("x.html").Parse(`{{.Recur}}`) + if err != nil { + t.Fatal(err) + } + _, err = tmpl.New("subroutine").Parse(`<a href="/x?p={{"'a<b'"}}">`) + if err != nil { + t.Fatal(err) + } + r := &recursiveInvoker{ + t: t, + tmpl: tmpl, + } + if err := top.Execute(io.Discard, r); err != nil { + t.Fatal(err) + } +} + +// Issue 43295. +func TestTemplateFuncsAfterClone(t *testing.T) { + s := `{{ f . }}` + want := "test" + orig := New("orig").Funcs(map[string]interface{}{ + "f": func(in string) string { + return in + }, + }).New("child") + + overviewTmpl := Must(Must(orig.Clone()).Parse(s)) + var out strings.Builder + if err := overviewTmpl.Execute(&out, want); err != nil { + t.Fatal(err) + } + if got := out.String(); got != want { + t.Fatalf("got %q; want %q", got, want) + } +} diff --git a/tpl/internal/go_templates/htmltemplate/template.go b/tpl/internal/go_templates/htmltemplate/template.go index 132a4102b..263018969 100644 --- a/tpl/internal/go_templates/htmltemplate/template.go +++ b/tpl/internal/go_templates/htmltemplate/template.go @@ -8,7 +8,7 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" + "os" "path" "path/filepath" "sync" @@ -524,7 +524,7 @@ func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) { func readFileOS(file string) (name string, b []byte, err error) { name = filepath.Base(file) - b, err = ioutil.ReadFile(file) + b, err = os.ReadFile(file) return } diff --git a/tpl/internal/go_templates/testenv/testenv.go b/tpl/internal/go_templates/testenv/testenv.go index 5bd91591a..e0a0b4ec6 100644 --- a/tpl/internal/go_templates/testenv/testenv.go +++ b/tpl/internal/go_templates/testenv/testenv.go @@ -13,6 +13,7 @@ package testenv import ( "errors" "flag" + "github.com/gohugoio/hugo/tpl/internal/go_templates/cfg" "os" "os/exec" "path/filepath" @@ -21,9 +22,6 @@ import ( "strings" "sync" "testing" - - "github.com/cli/safeexec" - "github.com/gohugoio/hugo/tpl/internal/go_templates/cfg" ) // Builder reports the name of the builder running this test @@ -109,7 +107,7 @@ func GoTool() (string, error) { if _, err := os.Stat(path); err == nil { return path, nil } - goBin, err := safeexec.LookPath("go" + exeSuffix) + goBin, err := exec.LookPath("go" + exeSuffix) if err != nil { return "", errors.New("cannot find go tool: " + err.Error()) } @@ -154,7 +152,7 @@ func MustHaveExecPath(t testing.TB, path string) { err, found := execPaths.Load(path) if !found { - _, err = safeexec.LookPath(path) + _, err = exec.LookPath(path) err, _ = execPaths.LoadOrStore(path, err) } if err != nil { diff --git a/tpl/internal/go_templates/testenv/testenv_windows.go b/tpl/internal/go_templates/testenv/testenv_windows.go index eb8d6ac16..4802b1395 100644 --- a/tpl/internal/go_templates/testenv/testenv_windows.go +++ b/tpl/internal/go_templates/testenv/testenv_windows.go @@ -5,7 +5,6 @@ package testenv import ( - "io/ioutil" "os" "path/filepath" "sync" @@ -16,7 +15,7 @@ var symlinkOnce sync.Once var winSymlinkErr error func initWinHasSymlink() { - tmpdir, err := ioutil.TempDir("", "symtest") + tmpdir, err := os.MkdirTemp("", "symtest") if err != nil { panic("failed to create temp directory: " + err.Error()) } diff --git a/tpl/internal/go_templates/texttemplate/examplefiles_test.go b/tpl/internal/go_templates/texttemplate/examplefiles_test.go index 8a78a018e..5a95b7078 100644 --- a/tpl/internal/go_templates/texttemplate/examplefiles_test.go +++ b/tpl/internal/go_templates/texttemplate/examplefiles_test.go @@ -8,7 +8,6 @@ package template_test import ( "io" - "io/ioutil" "log" "os" "path/filepath" @@ -22,7 +21,7 @@ type templateFile struct { } func createTestDir(files []templateFile) string { - dir, err := ioutil.TempDir("", "template") + dir, err := os.MkdirTemp("", "template") if err != nil { log.Fatal(err) } diff --git a/tpl/internal/go_templates/texttemplate/exec.go b/tpl/internal/go_templates/texttemplate/exec.go index ca6a1a071..8b3871234 100644 --- a/tpl/internal/go_templates/texttemplate/exec.go +++ b/tpl/internal/go_templates/texttemplate/exec.go @@ -373,6 +373,10 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { if val.IsNil() { break } + if val.Type().ChanDir() == reflect.SendDir { + s.errorf("range over send-only channel %v", val) + break + } i := 0 for ; ; i++ { elem, ok := val.Recv() diff --git a/tpl/internal/go_templates/texttemplate/exec_test.go b/tpl/internal/go_templates/texttemplate/exec_test.go index 3f16b6eb6..88de0fd49 100644 --- a/tpl/internal/go_templates/texttemplate/exec_test.go +++ b/tpl/internal/go_templates/texttemplate/exec_test.go @@ -1699,3 +1699,16 @@ func TestIssue31810(t *testing.T) { t.Errorf("%s got %q, expected %q", textCall, b.String(), "result") } } + +// Issue 43065, range over send only channel +func TestIssue43065(t *testing.T) { + var b bytes.Buffer + tmp := Must(New("").Parse(`{{range .}}{{end}}`)) + ch := make(chan<- int) + err := tmp.Execute(&b, ch) + if err == nil { + t.Error("expected err got nil") + } else if !strings.Contains(err.Error(), "range over send-only channel") { + t.Errorf("%s", err) + } +} diff --git a/tpl/internal/go_templates/texttemplate/helper.go b/tpl/internal/go_templates/texttemplate/helper.go index 8269fa28c..57905e613 100644 --- a/tpl/internal/go_templates/texttemplate/helper.go +++ b/tpl/internal/go_templates/texttemplate/helper.go @@ -9,7 +9,7 @@ package template import ( "fmt" "io/fs" - "io/ioutil" + "os" "path" "path/filepath" ) @@ -164,7 +164,7 @@ func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) { func readFileOS(file string) (name string, b []byte, err error) { name = filepath.Base(file) - b, err = ioutil.ReadFile(file) + b, err = os.ReadFile(file) return } diff --git a/tpl/internal/go_templates/texttemplate/link_test.go b/tpl/internal/go_templates/texttemplate/link_test.go index 3db8c21e3..e602b0e7e 100644 --- a/tpl/internal/go_templates/texttemplate/link_test.go +++ b/tpl/internal/go_templates/texttemplate/link_test.go @@ -9,7 +9,6 @@ package template_test import ( "bytes" "github.com/gohugoio/hugo/tpl/internal/go_templates/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -42,13 +41,13 @@ func main() { t.Used() } ` - td, err := ioutil.TempDir("", "text_template_TestDeadCodeElimination") + td, err := os.MkdirTemp("", "text_template_TestDeadCodeElimination") if err != nil { t.Fatal(err) } defer os.RemoveAll(td) - if err := ioutil.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil { + if err := os.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil { t.Fatal(err) } cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "x.exe", "x.go") @@ -56,7 +55,7 @@ func main() { if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("go build: %v, %s", err, out) } - slurp, err := ioutil.ReadFile(filepath.Join(td, "x.exe")) + slurp, err := os.ReadFile(filepath.Join(td, "x.exe")) if err != nil { t.Fatal(err) } |