Skip to content

text/template: Call using string as type int #10800

Closed
@dvyukov

Description

@dvyukov

The following program crashes with panic:

package main

import (
    "errors"
    "html/template"
    "io/ioutil"
)

func main() {
    data := "{{R html}}"
    t, err := template.New("foo").Funcs(funcs).Parse(string(data))
    if err != nil {
        if t != nil {
            panic("non nil template on error")
        }
        return
    }
    d := &Data{
        A: 42,
        B: "foo",
        C: []int{1, 2, 3},
        D: map[int]string{1: "foo", 2: "bar"},
        E: Data1{42, "foo"},
    }
    t.Execute(ioutil.Discard, d)
    return
}

type Data struct {
    A int
    B string
    C []int
    D map[int]string
    E Data1
}

type Data1 struct {
    A int
    B string
}

func (Data1) Q() string {
    return "foo"
}

func (Data1) W() (string, error) {
    return "foo", nil
}

func (Data1) E() (string, error) {
    return "foo", errors.New("Data.E error")
}

func (Data1) R(v int) (string, error) {
    return "foo", nil
}

func (Data1) T(s string) (string, error) {
    return s, nil
}

var funcs = map[string]interface{}{
    "Q": func1,
    "W": func2,
    "E": func3,
    "R": func4,
    "T": func5,
    "Y": func6,
    "U": func7,
    "I": func8,
}

func func1(s string) string {
    return s
}

func func2(s string) (string, error) {
    return s, nil
}

func func3(s string) (string, error) {
    return s, errors.New("func3 error")
}

func func4(v int) int {
    return v
}

func func5(v int) (int, error) {
    return v, nil
}

func func6() int {
    return 42
}

func func7() (int, error) {
    return 42, nil
}

func func8() (int, error) {
    return 42, errors.New("func8 error")
}
panic: reflect: Call using string as type int [recovered]
    panic: reflect: Call using string as type int

goroutine 1 [running]:
text/template.errRecover(0xc208043e50)
    src/text/template/exec.go:104 +0x146
reflect.Value.call(0x55bf00, 0x62eaa0, 0x13, 0x5bf4f0, 0x4, 0xc20800a4c0, 0x1, 0x1, 0x0, 0x0, ...)
    src/reflect/value.go:369 +0x749
reflect.Value.Call(0x55bf00, 0x62eaa0, 0x13, 0xc20800a4c0, 0x1, 0x1, 0x0, 0x0, 0x0)
    src/reflect/value.go:300 +0xb4
text/template.(*state).evalCall(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0x55bf00, 0x62eaa0, 0x13, 0x7f97307ee3b0, 0xc2080148a0, 0xc20800e5b2, ...)
    src/text/template/exec.go:592 +0xb04
text/template.(*state).evalFunction(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0xc2080148d0, 0x7f97307ee3b0, 0xc2080148a0, 0xc208014930, 0x2, 0x3, ...)
    src/text/template/exec.go:473 +0x427
text/template.(*state).evalCommand(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0xc2080148a0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    src/text/template/exec.go:370 +0x1ec
text/template.(*state).evalPipeline(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0xc208012280, 0x0, 0x0, 0x0)
    src/text/template/exec.go:343 +0x184
text/template.(*state).walk(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0x7f97307ee2d8, 0xc208014960)
    src/text/template/exec.go:178 +0x138
text/template.(*state).walk(0xc208043de0, 0x52fc40, 0xc2080122d0, 0x16, 0x7f97307ee320, 0xc208014870)
    src/text/template/exec.go:186 +0x78b
text/template.(*Template).Execute(0xc208010440, 0x7f97307ee1f0, 0xc20800e4f0, 0x52fc40, 0xc2080122d0, 0x0, 0x0)
    src/text/template/exec.go:141 +0x3ea
html/template.(*Template).Execute(0xc208014780, 0x7f97307ee1f0, 0xc20800e4f0, 0x52fc40, 0xc2080122d0, 0x0, 0x0)
    src/html/template/template.go:104 +0x9d
main.main()
    /tmp/ht.go:26 +0x543

on commit abb818b

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions