funcs.go 15 KB

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