Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

text/template: Call using complex128 as type string #10946

Closed
dvyukov opened this issue May 25, 2015 · 2 comments
Closed

text/template: Call using complex128 as type string #10946

dvyukov opened this issue May 25, 2015 · 2 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented May 25, 2015

The following program crashes with a panic:

package main

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

func main() {
    data := "{{0i|printf}}"
    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 complex128 as type string [recovered]
    panic: reflect: Call using complex128 as type string

goroutine 1 [running]:
text/template.errRecover(0xc208041ee8)
    src/text/template/exec.go:104 +0x146
reflect.Value.call(0x52db60, 0x5bbe98, 0x13, 0x56c8f0, 0x4, 0xc20800e440, 0x1, 0x1, 0x0, 0x0, ...)
    src/reflect/value.go:369 +0x74d
reflect.Value.Call(0x52db60, 0x5bbe98, 0x13, 0xc20800e440, 0x1, 0x1, 0x0, 0x0, 0x0)
    src/reflect/value.go:300 +0xb4
text/template.(*state).evalCall(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0x52db60, 0x5bbe98, 0x13, 0x7f702f59a350, 0xc2080145a0, 0x5828d5, ...)
    src/text/template/exec.go:592 +0xb04
text/template.(*state).evalFunction(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0xc2080145d0, 0x7f702f59a350, 0xc2080145a0, 0xc20800a500, 0x1, 0x1, ...)
    src/text/template/exec.go:473 +0x340
text/template.(*state).evalCommand(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0xc2080145a0, 0x505840, 0xc20800a520, 0x50, 0x0, 0x0, ...)
    src/text/template/exec.go:370 +0x1ec
text/template.(*state).evalPipeline(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0xc2080121e0, 0x505840, 0xc20800a520, 0x50)
    src/text/template/exec.go:343 +0x183
text/template.(*state).walk(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0x7f702f59a278, 0xc208014600)
    src/text/template/exec.go:178 +0x138
text/template.(*state).walk(0xc208041e78, 0x4f8500, 0xc208012230, 0x16, 0x7f702f59a2c0, 0xc208014540)
    src/text/template/exec.go:186 +0x779
text/template.(*Template).Execute(0xc208010440, 0x7f702f59a1c0, 0xc20800a490, 0x4f8500, 0xc208012230, 0x0, 0x0)
    src/text/template/exec.go:141 +0x406
main.main()
    template.go:25 +0x35d

on commit 8017ace

@dvyukov dvyukov added this to the Go1.5 milestone May 25, 2015
@dspezia
Copy link
Contributor

dspezia commented May 27, 2015

It is unrelated to complex numbers. It fails in the same way with any value which is not a string, such as:

 {{true | printf}}
 {{1|printf}}
 {{1.1|printf}}
 {{'x'|printf}}

I think it is due to a unmanaged corner case involving variadic functions featuring a []interface{} slice.
Working on a fix.

@gopherbot
Copy link

CL https://golang.org/cl/10403 mentions this issue.

@robpike robpike closed this as completed in 5c60a4f Jun 1, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
@rsc rsc unassigned robpike Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants