Skip to content

Commit

Permalink
Pull in latest Go template source
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Feb 18, 2021
1 parent 21e9eb1 commit ccb822e
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 20 deletions.
2 changes: 1 addition & 1 deletion scripts/fork_go_templates/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (

func main() {
// TODO(bep) git checkout tag
// The current is built with Go version da54dfb6a1f3bef827b9ec3780c98fde77a97d11 / go1.16dev
// The current is built with Go version c8bd8010ff7c0115bf186443119216ba51f09d2b / go1.16dev
fmt.Println("Forking ...")
defer fmt.Println("Done ...")

Expand Down
3 changes: 1 addition & 2 deletions tpl/internal/go_templates/htmltemplate/examplefiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package template_test

import (
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
Expand All @@ -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)
}
Expand Down
126 changes: 126 additions & 0 deletions tpl/internal/go_templates/htmltemplate/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
}
4 changes: 2 additions & 2 deletions tpl/internal/go_templates/htmltemplate/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path"
"path/filepath"
"sync"
Expand Down Expand Up @@ -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
}

Expand Down
8 changes: 3 additions & 5 deletions tpl/internal/go_templates/testenv/testenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package testenv
import (
"errors"
"flag"
"github.com/gohugoio/hugo/tpl/internal/go_templates/cfg"
"os"
"os/exec"
"path/filepath"
Expand All @@ -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
Expand Down Expand Up @@ -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())
}
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions tpl/internal/go_templates/testenv/testenv_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package testenv

import (
"io/ioutil"
"os"
"path/filepath"
"sync"
Expand All @@ -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())
}
Expand Down
3 changes: 1 addition & 2 deletions tpl/internal/go_templates/texttemplate/examplefiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package template_test

import (
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
Expand All @@ -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)
}
Expand Down
4 changes: 4 additions & 0 deletions tpl/internal/go_templates/texttemplate/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 13 additions & 0 deletions tpl/internal/go_templates/texttemplate/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
4 changes: 2 additions & 2 deletions tpl/internal/go_templates/texttemplate/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package template
import (
"fmt"
"io/fs"
"io/ioutil"
"os"
"path"
"path/filepath"
)
Expand Down Expand Up @@ -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
}

Expand Down
7 changes: 3 additions & 4 deletions tpl/internal/go_templates/texttemplate/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -42,21 +41,21 @@ 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")
cmd.Dir = td
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)
}
Expand Down

0 comments on commit ccb822e

Please sign in to comment.