tpl: avoid panic on too few args to apply - hugo - [fork] hugo port for 9front
HTML git clone git@git.drkhsh.at/hugo.git
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
DIR commit be3b8a132ba72aa3a797101f942e555610553f72
DIR parent beacfcf865ed8c38e8f17f4b5cb158a315d42174
HTML Author: bep <bjorn.erik.pedersen@gmail.com>
Date: Thu, 30 Apr 2015 10:51:01 +0200
tpl: avoid panic on too few args to apply
Fixes #1089
Diffstat:
M tpl/template_funcs.go | 10 ++++++++++
M tpl/template_test.go | 73 ++++++++++++++++++++++++++++++-
2 files changed, 82 insertions(+), 1 deletion(-)
---
DIR diff --git a/tpl/template_funcs.go b/tpl/template_funcs.go
@@ -653,6 +653,16 @@ func applyFnToThis(fn, this reflect.Value, args ...interface{}) (reflect.Value,
}
}
+ num := fn.Type().NumIn()
+
+ if fn.Type().IsVariadic() {
+ num--
+ }
+
+ if len(args) < num {
+ return reflect.ValueOf(nil), errors.New("Too few arguments")
+ }
+
res := fn.Call(n)
if len(res) == 1 || res[1].IsNil() {
DIR diff --git a/tpl/template_test.go b/tpl/template_test.go
@@ -1,3 +1,74 @@
package tpl
-// TODO(bep) test it
+import (
+ "errors"
+ "io/ioutil"
+ "testing"
+)
+
+// Test for bugs discovered by https://github.com/dvyukov/go-fuzz
+func TestTplGoFuzzReports(t *testing.T) {
+ for i, this := range []struct {
+ data string
+ expectErr int
+ }{{"{{apply .C \"first\" }}", 2}} {
+ templ := New()
+
+ d := &Data{
+ A: 42,
+ B: "foo",
+ C: []int{1, 2, 3},
+ D: map[int]string{1: "foo", 2: "bar"},
+ E: Data1{42, "foo"},
+ }
+
+ err := templ.AddTemplate("fuzz", this.data)
+
+ if err != nil && this.expectErr == 0 {
+ t.Fatalf("Test %d errored: %s", i, err)
+ } else if err == nil && this.expectErr == 1 {
+ t.Fatalf("#1 Test %d should have errored", i)
+ }
+
+ err = templ.ExecuteTemplate(ioutil.Discard, "fuzz", d)
+
+ if err != nil && this.expectErr == 0 {
+ t.Fatalf("Test %d errored: %s", i, err)
+ } else if err == nil && this.expectErr == 2 {
+ t.Fatalf("#2 Test %d should have errored", i)
+ }
+ }
+}
+
+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
+}