funcs.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package template
  5. import (
  6. "bytes"
  7. "errors"
  8. "fmt"
  9. "io"
  10. "net/url"
  11. "reflect"
  12. "strings"
  13. "unicode"
  14. "unicode/utf8"
  15. )
  16. // FuncMap is the type of the map defining the mapping from names to functions.
  17. // Each function must have either a single return value, or two return values of
  18. // which the second has type error. In that case, if the second (error)
  19. // return value evaluates to non-nil during execution, execution terminates and
  20. // Execute returns that error.
  21. type FuncMap map[string]interface{}
  22. var builtins = FuncMap{
  23. "and": and,
  24. "call": call,
  25. "html": HTMLEscaper,
  26. "index": index,
  27. "js": JSEscaper,
  28. "len": length,
  29. "not": not,
  30. "or": or,
  31. "print": fmt.Sprint,
  32. "printf": fmt.Sprintf,
  33. "println": fmt.Sprintln,
  34. "urlquery": URLQueryEscaper,
  35. // Comparisons
  36. "eq": eq, // ==
  37. "ge": ge, // >=
  38. "gt": gt, // >
  39. "le": le, // <=
  40. "lt": lt, // <
  41. "ne": ne, // !=
  42. }
  43. var builtinFuncs = createValueFuncs(builtins)
  44. // createValueFuncs turns a FuncMap into a map[string]reflect.Value
  45. func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
  46. m := make(map[string]reflect.Value)
  47. addValueFuncs(m, funcMap)
  48. return m
  49. }
  50. // addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
  51. func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
  52. for name, fn := range in {
  53. v := reflect.ValueOf(fn)
  54. if v.Kind() != reflect.Func {
  55. panic("value for " + name + " not a function")
  56. }
  57. if !goodFunc(v.Type()) {
  58. panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
  59. }
  60. out[name] = v
  61. }
  62. }
  63. // addFuncs adds to values the functions in funcs. It does no checking of the input -
  64. // call addValueFuncs first.
  65. func addFuncs(out, in FuncMap) {
  66. for name, fn := range in {
  67. out[name] = fn
  68. }
  69. }
  70. // goodFunc checks that the function or method has the right result signature.
  71. func goodFunc(typ reflect.Type) bool {
  72. // We allow functions with 1 result or 2 results where the second is an error.
  73. switch {
  74. case typ.NumOut() == 1:
  75. return true
  76. case typ.NumOut() == 2 && typ.Out(1) == errorType:
  77. return true
  78. }
  79. return false
  80. }
  81. // findFunction looks for a function in the template, and global map.
  82. func findFunction(name string, tmpl *Template) (reflect.Value, bool) {
  83. if tmpl != nil && tmpl.common != nil {
  84. if fn := tmpl.execFuncs[name]; fn.IsValid() {
  85. return fn, true
  86. }
  87. }
  88. if fn := builtinFuncs[name]; fn.IsValid() {
  89. return fn, true
  90. }
  91. return reflect.Value{}, false
  92. }
  93. // Indexing.
  94. // index returns the result of indexing its first argument by the following
  95. // arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
  96. // indexed item must be a map, slice, or array.
  97. func index(item interface{}, indices ...interface{}) (interface{}, error) {
  98. v := reflect.ValueOf(item)
  99. for _, i := range indices {
  100. index := reflect.ValueOf(i)
  101. var isNil bool
  102. if v, isNil = indirect(v); isNil {
  103. return nil, fmt.Errorf("index of nil pointer")
  104. }
  105. switch v.Kind() {
  106. case reflect.Array, reflect.Slice, reflect.String:
  107. var x int64
  108. switch index.Kind() {
  109. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  110. x = index.Int()
  111. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  112. x = int64(index.Uint())
  113. default:
  114. return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
  115. }
  116. if x < 0 || x >= int64(v.Len()) {
  117. return nil, fmt.Errorf("index out of range: %d", x)
  118. }
  119. v = v.Index(int(x))
  120. case reflect.Map:
  121. if !index.IsValid() {
  122. index = reflect.Zero(v.Type().Key())
  123. }
  124. if !index.Type().AssignableTo(v.Type().Key()) {
  125. return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
  126. }
  127. if x := v.MapIndex(index); x.IsValid() {
  128. v = x
  129. } else {
  130. v = reflect.Zero(v.Type().Elem())
  131. }
  132. default:
  133. return nil, fmt.Errorf("can't index item of type %s", v.Type())
  134. }
  135. }
  136. return v.Interface(), nil
  137. }
  138. // Length
  139. // length returns the length of the item, with an error if it has no defined length.
  140. func length(item interface{}) (int, error) {
  141. v, isNil := indirect(reflect.ValueOf(item))
  142. if isNil {
  143. return 0, fmt.Errorf("len of nil pointer")
  144. }
  145. switch v.Kind() {
  146. case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
  147. return v.Len(), nil
  148. }
  149. return 0, fmt.Errorf("len of type %s", v.Type())
  150. }
  151. // Function invocation
  152. // call returns the result of evaluating the first argument as a function.
  153. // The function must return 1 result, or 2 results, the second of which is an error.
  154. func call(fn interface{}, args ...interface{}) (interface{}, error) {
  155. v := reflect.ValueOf(fn)
  156. typ := v.Type()
  157. if typ.Kind() != reflect.Func {
  158. return nil, fmt.Errorf("non-function of type %s", typ)
  159. }
  160. if !goodFunc(typ) {
  161. return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
  162. }
  163. numIn := typ.NumIn()
  164. var dddType reflect.Type
  165. if typ.IsVariadic() {
  166. if len(args) < numIn-1 {
  167. return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
  168. }
  169. dddType = typ.In(numIn - 1).Elem()
  170. } else {
  171. if len(args) != numIn {
  172. return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
  173. }
  174. }
  175. argv := make([]reflect.Value, len(args))
  176. for i, arg := range args {
  177. value := reflect.ValueOf(arg)
  178. // Compute the expected type. Clumsy because of variadics.
  179. var argType reflect.Type
  180. if !typ.IsVariadic() || i < numIn-1 {
  181. argType = typ.In(i)
  182. } else {
  183. argType = dddType
  184. }
  185. if !value.IsValid() && canBeNil(argType) {
  186. value = reflect.Zero(argType)
  187. }
  188. if !value.Type().AssignableTo(argType) {
  189. return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
  190. }
  191. argv[i] = value
  192. }
  193. result := v.Call(argv)
  194. if len(result) == 2 && !result[1].IsNil() {
  195. return result[0].Interface(), result[1].Interface().(error)
  196. }
  197. return result[0].Interface(), nil
  198. }
  199. // Boolean logic.
  200. func truth(a interface{}) bool {
  201. t, _ := isTrue(reflect.ValueOf(a))
  202. return t
  203. }
  204. // and computes the Boolean AND of its arguments, returning
  205. // the first false argument it encounters, or the last argument.
  206. func and(arg0 interface{}, args ...interface{}) interface{} {
  207. if !truth(arg0) {
  208. return arg0
  209. }
  210. for i := range args {
  211. arg0 = args[i]
  212. if !truth(arg0) {
  213. break
  214. }
  215. }
  216. return arg0
  217. }
  218. // or computes the Boolean OR of its arguments, returning
  219. // the first true argument it encounters, or the last argument.
  220. func or(arg0 interface{}, args ...interface{}) interface{} {
  221. if truth(arg0) {
  222. return arg0
  223. }
  224. for i := range args {
  225. arg0 = args[i]
  226. if truth(arg0) {
  227. break
  228. }
  229. }
  230. return arg0
  231. }
  232. // not returns the Boolean negation of its argument.
  233. func not(arg interface{}) (truth bool) {
  234. truth, _ = isTrue(reflect.ValueOf(arg))
  235. return !truth
  236. }
  237. // Comparison.
  238. // TODO: Perhaps allow comparison between signed and unsigned integers.
  239. var (
  240. errBadComparisonType = errors.New("invalid type for comparison")
  241. errBadComparison = errors.New("incompatible types for comparison")
  242. errNoComparison = errors.New("missing argument for comparison")
  243. )
  244. type kind int
  245. const (
  246. invalidKind kind = iota
  247. boolKind
  248. complexKind
  249. intKind
  250. floatKind
  251. integerKind
  252. stringKind
  253. uintKind
  254. )
  255. func basicKind(v reflect.Value) (kind, error) {
  256. switch v.Kind() {
  257. case reflect.Bool:
  258. return boolKind, nil
  259. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  260. return intKind, nil
  261. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  262. return uintKind, nil
  263. case reflect.Float32, reflect.Float64:
  264. return floatKind, nil
  265. case reflect.Complex64, reflect.Complex128:
  266. return complexKind, nil
  267. case reflect.String:
  268. return stringKind, nil
  269. }
  270. return invalidKind, errBadComparisonType
  271. }
  272. // eq evaluates the comparison a == b || a == c || ...
  273. func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
  274. v1 := reflect.ValueOf(arg1)
  275. k1, err := basicKind(v1)
  276. if err != nil {
  277. return false, err
  278. }
  279. if len(arg2) == 0 {
  280. return false, errNoComparison
  281. }
  282. for _, arg := range arg2 {
  283. v2 := reflect.ValueOf(arg)
  284. k2, err := basicKind(v2)
  285. if err != nil {
  286. return false, err
  287. }
  288. truth := false
  289. if k1 != k2 {
  290. // Special case: Can compare integer values regardless of type's sign.
  291. switch {
  292. case k1 == intKind && k2 == uintKind:
  293. truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint()
  294. case k1 == uintKind && k2 == intKind:
  295. truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int())
  296. default:
  297. return false, errBadComparison
  298. }
  299. } else {
  300. switch k1 {
  301. case boolKind:
  302. truth = v1.Bool() == v2.Bool()
  303. case complexKind:
  304. truth = v1.Complex() == v2.Complex()
  305. case floatKind:
  306. truth = v1.Float() == v2.Float()
  307. case intKind:
  308. truth = v1.Int() == v2.Int()
  309. case stringKind:
  310. truth = v1.String() == v2.String()
  311. case uintKind:
  312. truth = v1.Uint() == v2.Uint()
  313. default:
  314. panic("invalid kind")
  315. }
  316. }
  317. if truth {
  318. return true, nil
  319. }
  320. }
  321. return false, nil
  322. }
  323. // ne evaluates the comparison a != b.
  324. func ne(arg1, arg2 interface{}) (bool, error) {
  325. // != is the inverse of ==.
  326. equal, err := eq(arg1, arg2)
  327. return !equal, err
  328. }
  329. // lt evaluates the comparison a < b.
  330. func lt(arg1, arg2 interface{}) (bool, error) {
  331. v1 := reflect.ValueOf(arg1)
  332. k1, err := basicKind(v1)
  333. if err != nil {
  334. return false, err
  335. }
  336. v2 := reflect.ValueOf(arg2)
  337. k2, err := basicKind(v2)
  338. if err != nil {
  339. return false, err
  340. }
  341. truth := false
  342. if k1 != k2 {
  343. // Special case: Can compare integer values regardless of type's sign.
  344. switch {
  345. case k1 == intKind && k2 == uintKind:
  346. truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint()
  347. case k1 == uintKind && k2 == intKind:
  348. truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int())
  349. default:
  350. return false, errBadComparison
  351. }
  352. } else {
  353. switch k1 {
  354. case boolKind, complexKind:
  355. return false, errBadComparisonType
  356. case floatKind:
  357. truth = v1.Float() < v2.Float()
  358. case intKind:
  359. truth = v1.Int() < v2.Int()
  360. case stringKind:
  361. truth = v1.String() < v2.String()
  362. case uintKind:
  363. truth = v1.Uint() < v2.Uint()
  364. default:
  365. panic("invalid kind")
  366. }
  367. }
  368. return truth, nil
  369. }
  370. // le evaluates the comparison <= b.
  371. func le(arg1, arg2 interface{}) (bool, error) {
  372. // <= is < or ==.
  373. lessThan, err := lt(arg1, arg2)
  374. if lessThan || err != nil {
  375. return lessThan, err
  376. }
  377. return eq(arg1, arg2)
  378. }
  379. // gt evaluates the comparison a > b.
  380. func gt(arg1, arg2 interface{}) (bool, error) {
  381. // > is the inverse of <=.
  382. lessOrEqual, err := le(arg1, arg2)
  383. if err != nil {
  384. return false, err
  385. }
  386. return !lessOrEqual, nil
  387. }
  388. // ge evaluates the comparison a >= b.
  389. func ge(arg1, arg2 interface{}) (bool, error) {
  390. // >= is the inverse of <.
  391. lessThan, err := lt(arg1, arg2)
  392. if err != nil {
  393. return false, err
  394. }
  395. return !lessThan, nil
  396. }
  397. // HTML escaping.
  398. var (
  399. htmlQuot = []byte("&#34;") // shorter than "&quot;"
  400. htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
  401. htmlAmp = []byte("&amp;")
  402. htmlLt = []byte("&lt;")
  403. htmlGt = []byte("&gt;")
  404. )
  405. // HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
  406. func HTMLEscape(w io.Writer, b []byte) {
  407. last := 0
  408. for i, c := range b {
  409. var html []byte
  410. switch c {
  411. case '"':
  412. html = htmlQuot
  413. case '\'':
  414. html = htmlApos
  415. case '&':
  416. html = htmlAmp
  417. case '<':
  418. html = htmlLt
  419. case '>':
  420. html = htmlGt
  421. default:
  422. continue
  423. }
  424. w.Write(b[last:i])
  425. w.Write(html)
  426. last = i + 1
  427. }
  428. w.Write(b[last:])
  429. }
  430. // HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
  431. func HTMLEscapeString(s string) string {
  432. // Avoid allocation if we can.
  433. if strings.IndexAny(s, `'"&<>`) < 0 {
  434. return s
  435. }
  436. var b bytes.Buffer
  437. HTMLEscape(&b, []byte(s))
  438. return b.String()
  439. }
  440. // HTMLEscaper returns the escaped HTML equivalent of the textual
  441. // representation of its arguments.
  442. func HTMLEscaper(args ...interface{}) string {
  443. return HTMLEscapeString(evalArgs(args))
  444. }
  445. // JavaScript escaping.
  446. var (
  447. jsLowUni = []byte(`\u00`)
  448. hex = []byte("0123456789ABCDEF")
  449. jsBackslash = []byte(`\\`)
  450. jsApos = []byte(`\'`)
  451. jsQuot = []byte(`\"`)
  452. jsLt = []byte(`\x3C`)
  453. jsGt = []byte(`\x3E`)
  454. )
  455. // JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
  456. func JSEscape(w io.Writer, b []byte) {
  457. last := 0
  458. for i := 0; i < len(b); i++ {
  459. c := b[i]
  460. if !jsIsSpecial(rune(c)) {
  461. // fast path: nothing to do
  462. continue
  463. }
  464. w.Write(b[last:i])
  465. if c < utf8.RuneSelf {
  466. // Quotes, slashes and angle brackets get quoted.
  467. // Control characters get written as \u00XX.
  468. switch c {
  469. case '\\':
  470. w.Write(jsBackslash)
  471. case '\'':
  472. w.Write(jsApos)
  473. case '"':
  474. w.Write(jsQuot)
  475. case '<':
  476. w.Write(jsLt)
  477. case '>':
  478. w.Write(jsGt)
  479. default:
  480. w.Write(jsLowUni)
  481. t, b := c>>4, c&0x0f
  482. w.Write(hex[t : t+1])
  483. w.Write(hex[b : b+1])
  484. }
  485. } else {
  486. // Unicode rune.
  487. r, size := utf8.DecodeRune(b[i:])
  488. if unicode.IsPrint(r) {
  489. w.Write(b[i : i+size])
  490. } else {
  491. fmt.Fprintf(w, "\\u%04X", r)
  492. }
  493. i += size - 1
  494. }
  495. last = i + 1
  496. }
  497. w.Write(b[last:])
  498. }
  499. // JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
  500. func JSEscapeString(s string) string {
  501. // Avoid allocation if we can.
  502. if strings.IndexFunc(s, jsIsSpecial) < 0 {
  503. return s
  504. }
  505. var b bytes.Buffer
  506. JSEscape(&b, []byte(s))
  507. return b.String()
  508. }
  509. func jsIsSpecial(r rune) bool {
  510. switch r {
  511. case '\\', '\'', '"', '<', '>':
  512. return true
  513. }
  514. return r < ' ' || utf8.RuneSelf <= r
  515. }
  516. // JSEscaper returns the escaped JavaScript equivalent of the textual
  517. // representation of its arguments.
  518. func JSEscaper(args ...interface{}) string {
  519. return JSEscapeString(evalArgs(args))
  520. }
  521. // URLQueryEscaper returns the escaped value of the textual representation of
  522. // its arguments in a form suitable for embedding in a URL query.
  523. func URLQueryEscaper(args ...interface{}) string {
  524. return url.QueryEscape(evalArgs(args))
  525. }
  526. // evalArgs formats the list of arguments into a string. It is therefore equivalent to
  527. // fmt.Sprint(args...)
  528. // except that each argument is indirected (if a pointer), as required,
  529. // using the same rules as the default string evaluation during template
  530. // execution.
  531. func evalArgs(args []interface{}) string {
  532. ok := false
  533. var s string
  534. // Fast path for simple common case.
  535. if len(args) == 1 {
  536. s, ok = args[0].(string)
  537. }
  538. if !ok {
  539. for i, arg := range args {
  540. a, ok := printableValue(reflect.ValueOf(arg))
  541. if ok {
  542. args[i] = a
  543. } // else left fmt do its thing
  544. }
  545. s = fmt.Sprint(args...)
  546. }
  547. return s
  548. }