You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

decode.go 23 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. //
  2. // Copyright (c) 2011-2019 Canonical Ltd
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. package yaml
  16. import (
  17. "encoding"
  18. "encoding/base64"
  19. "fmt"
  20. "io"
  21. "math"
  22. "reflect"
  23. "strconv"
  24. "time"
  25. )
  26. // ----------------------------------------------------------------------------
  27. // Parser, produces a node tree out of a libyaml event stream.
  28. type parser struct {
  29. parser yaml_parser_t
  30. event yaml_event_t
  31. doc *Node
  32. anchors map[string]*Node
  33. doneInit bool
  34. }
  35. func newParser(b []byte) *parser {
  36. p := parser{}
  37. if !yaml_parser_initialize(&p.parser) {
  38. panic("failed to initialize YAML emitter")
  39. }
  40. if len(b) == 0 {
  41. b = []byte{'\n'}
  42. }
  43. yaml_parser_set_input_string(&p.parser, b)
  44. return &p
  45. }
  46. func newParserFromReader(r io.Reader) *parser {
  47. p := parser{}
  48. if !yaml_parser_initialize(&p.parser) {
  49. panic("failed to initialize YAML emitter")
  50. }
  51. yaml_parser_set_input_reader(&p.parser, r)
  52. return &p
  53. }
  54. func (p *parser) init() {
  55. if p.doneInit {
  56. return
  57. }
  58. p.anchors = make(map[string]*Node)
  59. p.expect(yaml_STREAM_START_EVENT)
  60. p.doneInit = true
  61. }
  62. func (p *parser) destroy() {
  63. if p.event.typ != yaml_NO_EVENT {
  64. yaml_event_delete(&p.event)
  65. }
  66. yaml_parser_delete(&p.parser)
  67. }
  68. // expect consumes an event from the event stream and
  69. // checks that it's of the expected type.
  70. func (p *parser) expect(e yaml_event_type_t) {
  71. if p.event.typ == yaml_NO_EVENT {
  72. if !yaml_parser_parse(&p.parser, &p.event) {
  73. p.fail()
  74. }
  75. }
  76. if p.event.typ == yaml_STREAM_END_EVENT {
  77. failf("attempted to go past the end of stream; corrupted value?")
  78. }
  79. if p.event.typ != e {
  80. p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
  81. p.fail()
  82. }
  83. yaml_event_delete(&p.event)
  84. p.event.typ = yaml_NO_EVENT
  85. }
  86. // peek peeks at the next event in the event stream,
  87. // puts the results into p.event and returns the event type.
  88. func (p *parser) peek() yaml_event_type_t {
  89. if p.event.typ != yaml_NO_EVENT {
  90. return p.event.typ
  91. }
  92. if !yaml_parser_parse(&p.parser, &p.event) {
  93. p.fail()
  94. }
  95. return p.event.typ
  96. }
  97. func (p *parser) fail() {
  98. var where string
  99. var line int
  100. if p.parser.problem_mark.line != 0 {
  101. line = p.parser.problem_mark.line
  102. // Scanner errors don't iterate line before returning error
  103. if p.parser.error == yaml_SCANNER_ERROR {
  104. line++
  105. }
  106. } else if p.parser.context_mark.line != 0 {
  107. line = p.parser.context_mark.line
  108. }
  109. if line != 0 {
  110. where = "line " + strconv.Itoa(line) + ": "
  111. }
  112. var msg string
  113. if len(p.parser.problem) > 0 {
  114. msg = p.parser.problem
  115. } else {
  116. msg = "unknown problem parsing YAML content"
  117. }
  118. failf("%s%s", where, msg)
  119. }
  120. func (p *parser) anchor(n *Node, anchor []byte) {
  121. if anchor != nil {
  122. n.Anchor = string(anchor)
  123. p.anchors[n.Anchor] = n
  124. }
  125. }
  126. func (p *parser) parse() *Node {
  127. p.init()
  128. switch p.peek() {
  129. case yaml_SCALAR_EVENT:
  130. return p.scalar()
  131. case yaml_ALIAS_EVENT:
  132. return p.alias()
  133. case yaml_MAPPING_START_EVENT:
  134. return p.mapping()
  135. case yaml_SEQUENCE_START_EVENT:
  136. return p.sequence()
  137. case yaml_DOCUMENT_START_EVENT:
  138. return p.document()
  139. case yaml_STREAM_END_EVENT:
  140. // Happens when attempting to decode an empty buffer.
  141. return nil
  142. case yaml_TAIL_COMMENT_EVENT:
  143. panic("internal error: unexpected tail comment event (please report)")
  144. default:
  145. panic("internal error: attempted to parse unknown event (please report): " + p.event.typ.String())
  146. }
  147. }
  148. func (p *parser) node(kind Kind, defaultTag, tag, value string) *Node {
  149. var style Style
  150. if tag != "" && tag != "!" {
  151. tag = shortTag(tag)
  152. style = TaggedStyle
  153. } else if defaultTag != "" {
  154. tag = defaultTag
  155. } else if kind == ScalarNode {
  156. tag, _ = resolve("", value)
  157. }
  158. return &Node{
  159. Kind: kind,
  160. Tag: tag,
  161. Value: value,
  162. Style: style,
  163. Line: p.event.start_mark.line + 1,
  164. Column: p.event.start_mark.column + 1,
  165. HeadComment: string(p.event.head_comment),
  166. LineComment: string(p.event.line_comment),
  167. FootComment: string(p.event.foot_comment),
  168. }
  169. }
  170. func (p *parser) parseChild(parent *Node) *Node {
  171. child := p.parse()
  172. parent.Content = append(parent.Content, child)
  173. return child
  174. }
  175. func (p *parser) document() *Node {
  176. n := p.node(DocumentNode, "", "", "")
  177. p.doc = n
  178. p.expect(yaml_DOCUMENT_START_EVENT)
  179. p.parseChild(n)
  180. if p.peek() == yaml_DOCUMENT_END_EVENT {
  181. n.FootComment = string(p.event.foot_comment)
  182. }
  183. p.expect(yaml_DOCUMENT_END_EVENT)
  184. return n
  185. }
  186. func (p *parser) alias() *Node {
  187. n := p.node(AliasNode, "", "", string(p.event.anchor))
  188. n.Alias = p.anchors[n.Value]
  189. if n.Alias == nil {
  190. failf("unknown anchor '%s' referenced", n.Value)
  191. }
  192. p.expect(yaml_ALIAS_EVENT)
  193. return n
  194. }
  195. func (p *parser) scalar() *Node {
  196. var parsedStyle = p.event.scalar_style()
  197. var nodeStyle Style
  198. switch {
  199. case parsedStyle&yaml_DOUBLE_QUOTED_SCALAR_STYLE != 0:
  200. nodeStyle = DoubleQuotedStyle
  201. case parsedStyle&yaml_SINGLE_QUOTED_SCALAR_STYLE != 0:
  202. nodeStyle = SingleQuotedStyle
  203. case parsedStyle&yaml_LITERAL_SCALAR_STYLE != 0:
  204. nodeStyle = LiteralStyle
  205. case parsedStyle&yaml_FOLDED_SCALAR_STYLE != 0:
  206. nodeStyle = FoldedStyle
  207. }
  208. var nodeValue = string(p.event.value)
  209. var nodeTag = string(p.event.tag)
  210. var defaultTag string
  211. if nodeStyle == 0 {
  212. if nodeValue == "<<" {
  213. defaultTag = mergeTag
  214. }
  215. } else {
  216. defaultTag = strTag
  217. }
  218. n := p.node(ScalarNode, defaultTag, nodeTag, nodeValue)
  219. n.Style |= nodeStyle
  220. p.anchor(n, p.event.anchor)
  221. p.expect(yaml_SCALAR_EVENT)
  222. return n
  223. }
  224. func (p *parser) sequence() *Node {
  225. n := p.node(SequenceNode, seqTag, string(p.event.tag), "")
  226. if p.event.sequence_style()&yaml_FLOW_SEQUENCE_STYLE != 0 {
  227. n.Style |= FlowStyle
  228. }
  229. p.anchor(n, p.event.anchor)
  230. p.expect(yaml_SEQUENCE_START_EVENT)
  231. for p.peek() != yaml_SEQUENCE_END_EVENT {
  232. p.parseChild(n)
  233. }
  234. n.LineComment = string(p.event.line_comment)
  235. n.FootComment = string(p.event.foot_comment)
  236. p.expect(yaml_SEQUENCE_END_EVENT)
  237. return n
  238. }
  239. func (p *parser) mapping() *Node {
  240. n := p.node(MappingNode, mapTag, string(p.event.tag), "")
  241. block := true
  242. if p.event.mapping_style()&yaml_FLOW_MAPPING_STYLE != 0 {
  243. block = false
  244. n.Style |= FlowStyle
  245. }
  246. p.anchor(n, p.event.anchor)
  247. p.expect(yaml_MAPPING_START_EVENT)
  248. for p.peek() != yaml_MAPPING_END_EVENT {
  249. k := p.parseChild(n)
  250. if block && k.FootComment != "" {
  251. // Must be a foot comment for the prior value when being dedented.
  252. if len(n.Content) > 2 {
  253. n.Content[len(n.Content)-3].FootComment = k.FootComment
  254. k.FootComment = ""
  255. }
  256. }
  257. v := p.parseChild(n)
  258. if k.FootComment == "" && v.FootComment != "" {
  259. k.FootComment = v.FootComment
  260. v.FootComment = ""
  261. }
  262. if p.peek() == yaml_TAIL_COMMENT_EVENT {
  263. if k.FootComment == "" {
  264. k.FootComment = string(p.event.foot_comment)
  265. }
  266. p.expect(yaml_TAIL_COMMENT_EVENT)
  267. }
  268. }
  269. n.LineComment = string(p.event.line_comment)
  270. n.FootComment = string(p.event.foot_comment)
  271. if n.Style&FlowStyle == 0 && n.FootComment != "" && len(n.Content) > 1 {
  272. n.Content[len(n.Content)-2].FootComment = n.FootComment
  273. n.FootComment = ""
  274. }
  275. p.expect(yaml_MAPPING_END_EVENT)
  276. return n
  277. }
  278. // ----------------------------------------------------------------------------
  279. // Decoder, unmarshals a node into a provided value.
  280. type decoder struct {
  281. doc *Node
  282. aliases map[*Node]bool
  283. terrors []string
  284. stringMapType reflect.Type
  285. generalMapType reflect.Type
  286. knownFields bool
  287. uniqueKeys bool
  288. decodeCount int
  289. aliasCount int
  290. aliasDepth int
  291. }
  292. var (
  293. nodeType = reflect.TypeOf(Node{})
  294. durationType = reflect.TypeOf(time.Duration(0))
  295. stringMapType = reflect.TypeOf(map[string]interface{}{})
  296. generalMapType = reflect.TypeOf(map[interface{}]interface{}{})
  297. ifaceType = generalMapType.Elem()
  298. timeType = reflect.TypeOf(time.Time{})
  299. ptrTimeType = reflect.TypeOf(&time.Time{})
  300. )
  301. func newDecoder() *decoder {
  302. d := &decoder{
  303. stringMapType: stringMapType,
  304. generalMapType: generalMapType,
  305. uniqueKeys: true,
  306. }
  307. d.aliases = make(map[*Node]bool)
  308. return d
  309. }
  310. func (d *decoder) terror(n *Node, tag string, out reflect.Value) {
  311. if n.Tag != "" {
  312. tag = n.Tag
  313. }
  314. value := n.Value
  315. if tag != seqTag && tag != mapTag {
  316. if len(value) > 10 {
  317. value = " `" + value[:7] + "...`"
  318. } else {
  319. value = " `" + value + "`"
  320. }
  321. }
  322. d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.Line, shortTag(tag), value, out.Type()))
  323. }
  324. func (d *decoder) callUnmarshaler(n *Node, u Unmarshaler) (good bool) {
  325. err := u.UnmarshalYAML(n)
  326. if e, ok := err.(*TypeError); ok {
  327. d.terrors = append(d.terrors, e.Errors...)
  328. return false
  329. }
  330. if err != nil {
  331. fail(err)
  332. }
  333. return true
  334. }
  335. func (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) {
  336. terrlen := len(d.terrors)
  337. err := u.UnmarshalYAML(func(v interface{}) (err error) {
  338. defer handleErr(&err)
  339. d.unmarshal(n, reflect.ValueOf(v))
  340. if len(d.terrors) > terrlen {
  341. issues := d.terrors[terrlen:]
  342. d.terrors = d.terrors[:terrlen]
  343. return &TypeError{issues}
  344. }
  345. return nil
  346. })
  347. if e, ok := err.(*TypeError); ok {
  348. d.terrors = append(d.terrors, e.Errors...)
  349. return false
  350. }
  351. if err != nil {
  352. fail(err)
  353. }
  354. return true
  355. }
  356. // d.prepare initializes and dereferences pointers and calls UnmarshalYAML
  357. // if a value is found to implement it.
  358. // It returns the initialized and dereferenced out value, whether
  359. // unmarshalling was already done by UnmarshalYAML, and if so whether
  360. // its types unmarshalled appropriately.
  361. //
  362. // If n holds a null value, prepare returns before doing anything.
  363. func (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
  364. if n.ShortTag() == nullTag {
  365. return out, false, false
  366. }
  367. again := true
  368. for again {
  369. again = false
  370. if out.Kind() == reflect.Ptr {
  371. if out.IsNil() {
  372. out.Set(reflect.New(out.Type().Elem()))
  373. }
  374. out = out.Elem()
  375. again = true
  376. }
  377. if out.CanAddr() {
  378. outi := out.Addr().Interface()
  379. if u, ok := outi.(Unmarshaler); ok {
  380. good = d.callUnmarshaler(n, u)
  381. return out, true, good
  382. }
  383. if u, ok := outi.(obsoleteUnmarshaler); ok {
  384. good = d.callObsoleteUnmarshaler(n, u)
  385. return out, true, good
  386. }
  387. }
  388. }
  389. return out, false, false
  390. }
  391. func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) {
  392. if n.ShortTag() == nullTag {
  393. return reflect.Value{}
  394. }
  395. for _, num := range index {
  396. for {
  397. if v.Kind() == reflect.Ptr {
  398. if v.IsNil() {
  399. v.Set(reflect.New(v.Type().Elem()))
  400. }
  401. v = v.Elem()
  402. continue
  403. }
  404. break
  405. }
  406. v = v.Field(num)
  407. }
  408. return v
  409. }
  410. const (
  411. // 400,000 decode operations is ~500kb of dense object declarations, or
  412. // ~5kb of dense object declarations with 10000% alias expansion
  413. alias_ratio_range_low = 400000
  414. // 4,000,000 decode operations is ~5MB of dense object declarations, or
  415. // ~4.5MB of dense object declarations with 10% alias expansion
  416. alias_ratio_range_high = 4000000
  417. // alias_ratio_range is the range over which we scale allowed alias ratios
  418. alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)
  419. )
  420. func allowedAliasRatio(decodeCount int) float64 {
  421. switch {
  422. case decodeCount <= alias_ratio_range_low:
  423. // allow 99% to come from alias expansion for small-to-medium documents
  424. return 0.99
  425. case decodeCount >= alias_ratio_range_high:
  426. // allow 10% to come from alias expansion for very large documents
  427. return 0.10
  428. default:
  429. // scale smoothly from 99% down to 10% over the range.
  430. // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.
  431. // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).
  432. return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)
  433. }
  434. }
  435. func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {
  436. d.decodeCount++
  437. if d.aliasDepth > 0 {
  438. d.aliasCount++
  439. }
  440. if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {
  441. failf("document contains excessive aliasing")
  442. }
  443. if out.Type() == nodeType {
  444. out.Set(reflect.ValueOf(n).Elem())
  445. return true
  446. }
  447. switch n.Kind {
  448. case DocumentNode:
  449. return d.document(n, out)
  450. case AliasNode:
  451. return d.alias(n, out)
  452. }
  453. out, unmarshaled, good := d.prepare(n, out)
  454. if unmarshaled {
  455. return good
  456. }
  457. switch n.Kind {
  458. case ScalarNode:
  459. good = d.scalar(n, out)
  460. case MappingNode:
  461. good = d.mapping(n, out)
  462. case SequenceNode:
  463. good = d.sequence(n, out)
  464. default:
  465. panic("internal error: unknown node kind: " + strconv.Itoa(int(n.Kind)))
  466. }
  467. return good
  468. }
  469. func (d *decoder) document(n *Node, out reflect.Value) (good bool) {
  470. if len(n.Content) == 1 {
  471. d.doc = n
  472. d.unmarshal(n.Content[0], out)
  473. return true
  474. }
  475. return false
  476. }
  477. func (d *decoder) alias(n *Node, out reflect.Value) (good bool) {
  478. if d.aliases[n] {
  479. // TODO this could actually be allowed in some circumstances.
  480. failf("anchor '%s' value contains itself", n.Value)
  481. }
  482. d.aliases[n] = true
  483. d.aliasDepth++
  484. good = d.unmarshal(n.Alias, out)
  485. d.aliasDepth--
  486. delete(d.aliases, n)
  487. return good
  488. }
  489. var zeroValue reflect.Value
  490. func resetMap(out reflect.Value) {
  491. for _, k := range out.MapKeys() {
  492. out.SetMapIndex(k, zeroValue)
  493. }
  494. }
  495. func (d *decoder) scalar(n *Node, out reflect.Value) bool {
  496. var tag string
  497. var resolved interface{}
  498. if n.indicatedString() {
  499. tag = strTag
  500. resolved = n.Value
  501. } else {
  502. tag, resolved = resolve(n.Tag, n.Value)
  503. if tag == binaryTag {
  504. data, err := base64.StdEncoding.DecodeString(resolved.(string))
  505. if err != nil {
  506. failf("!!binary value contains invalid base64 data")
  507. }
  508. resolved = string(data)
  509. }
  510. }
  511. if resolved == nil {
  512. if out.CanAddr() {
  513. switch out.Kind() {
  514. case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
  515. out.Set(reflect.Zero(out.Type()))
  516. return true
  517. }
  518. }
  519. return false
  520. }
  521. if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
  522. // We've resolved to exactly the type we want, so use that.
  523. out.Set(resolvedv)
  524. return true
  525. }
  526. // Perhaps we can use the value as a TextUnmarshaler to
  527. // set its value.
  528. if out.CanAddr() {
  529. u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
  530. if ok {
  531. var text []byte
  532. if tag == binaryTag {
  533. text = []byte(resolved.(string))
  534. } else {
  535. // We let any value be unmarshaled into TextUnmarshaler.
  536. // That might be more lax than we'd like, but the
  537. // TextUnmarshaler itself should bowl out any dubious values.
  538. text = []byte(n.Value)
  539. }
  540. err := u.UnmarshalText(text)
  541. if err != nil {
  542. fail(err)
  543. }
  544. return true
  545. }
  546. }
  547. switch out.Kind() {
  548. case reflect.String:
  549. if tag == binaryTag {
  550. out.SetString(resolved.(string))
  551. return true
  552. }
  553. out.SetString(n.Value)
  554. return true
  555. case reflect.Interface:
  556. out.Set(reflect.ValueOf(resolved))
  557. return true
  558. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  559. // This used to work in v2, but it's very unfriendly.
  560. isDuration := out.Type() == durationType
  561. switch resolved := resolved.(type) {
  562. case int:
  563. if !isDuration && !out.OverflowInt(int64(resolved)) {
  564. out.SetInt(int64(resolved))
  565. return true
  566. }
  567. case int64:
  568. if !isDuration && !out.OverflowInt(resolved) {
  569. out.SetInt(resolved)
  570. return true
  571. }
  572. case uint64:
  573. if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
  574. out.SetInt(int64(resolved))
  575. return true
  576. }
  577. case float64:
  578. if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
  579. out.SetInt(int64(resolved))
  580. return true
  581. }
  582. case string:
  583. if out.Type() == durationType {
  584. d, err := time.ParseDuration(resolved)
  585. if err == nil {
  586. out.SetInt(int64(d))
  587. return true
  588. }
  589. }
  590. }
  591. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  592. switch resolved := resolved.(type) {
  593. case int:
  594. if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
  595. out.SetUint(uint64(resolved))
  596. return true
  597. }
  598. case int64:
  599. if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
  600. out.SetUint(uint64(resolved))
  601. return true
  602. }
  603. case uint64:
  604. if !out.OverflowUint(uint64(resolved)) {
  605. out.SetUint(uint64(resolved))
  606. return true
  607. }
  608. case float64:
  609. if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
  610. out.SetUint(uint64(resolved))
  611. return true
  612. }
  613. }
  614. case reflect.Bool:
  615. switch resolved := resolved.(type) {
  616. case bool:
  617. out.SetBool(resolved)
  618. return true
  619. case string:
  620. // This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html).
  621. // It only works if explicitly attempting to unmarshal into a typed bool value.
  622. switch resolved {
  623. case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON":
  624. out.SetBool(true)
  625. return true
  626. case "n", "N", "no", "No", "NO", "off", "Off", "OFF":
  627. out.SetBool(false)
  628. return true
  629. }
  630. }
  631. case reflect.Float32, reflect.Float64:
  632. switch resolved := resolved.(type) {
  633. case int:
  634. out.SetFloat(float64(resolved))
  635. return true
  636. case int64:
  637. out.SetFloat(float64(resolved))
  638. return true
  639. case uint64:
  640. out.SetFloat(float64(resolved))
  641. return true
  642. case float64:
  643. out.SetFloat(resolved)
  644. return true
  645. }
  646. case reflect.Struct:
  647. if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
  648. out.Set(resolvedv)
  649. return true
  650. }
  651. case reflect.Ptr:
  652. panic("yaml internal error: please report the issue")
  653. }
  654. d.terror(n, tag, out)
  655. return false
  656. }
  657. func settableValueOf(i interface{}) reflect.Value {
  658. v := reflect.ValueOf(i)
  659. sv := reflect.New(v.Type()).Elem()
  660. sv.Set(v)
  661. return sv
  662. }
  663. func (d *decoder) sequence(n *Node, out reflect.Value) (good bool) {
  664. l := len(n.Content)
  665. var iface reflect.Value
  666. switch out.Kind() {
  667. case reflect.Slice:
  668. out.Set(reflect.MakeSlice(out.Type(), l, l))
  669. case reflect.Array:
  670. if l != out.Len() {
  671. failf("invalid array: want %d elements but got %d", out.Len(), l)
  672. }
  673. case reflect.Interface:
  674. // No type hints. Will have to use a generic sequence.
  675. iface = out
  676. out = settableValueOf(make([]interface{}, l))
  677. default:
  678. d.terror(n, seqTag, out)
  679. return false
  680. }
  681. et := out.Type().Elem()
  682. j := 0
  683. for i := 0; i < l; i++ {
  684. e := reflect.New(et).Elem()
  685. if ok := d.unmarshal(n.Content[i], e); ok {
  686. out.Index(j).Set(e)
  687. j++
  688. }
  689. }
  690. if out.Kind() != reflect.Array {
  691. out.Set(out.Slice(0, j))
  692. }
  693. if iface.IsValid() {
  694. iface.Set(out)
  695. }
  696. return true
  697. }
  698. func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {
  699. l := len(n.Content)
  700. if d.uniqueKeys {
  701. nerrs := len(d.terrors)
  702. for i := 0; i < l; i += 2 {
  703. ni := n.Content[i]
  704. for j := i + 2; j < l; j += 2 {
  705. nj := n.Content[j]
  706. if ni.Kind == nj.Kind && ni.Value == nj.Value {
  707. d.terrors = append(d.terrors, fmt.Sprintf("line %d: mapping key %#v already defined at line %d", nj.Line, nj.Value, ni.Line))
  708. }
  709. }
  710. }
  711. if len(d.terrors) > nerrs {
  712. return false
  713. }
  714. }
  715. switch out.Kind() {
  716. case reflect.Struct:
  717. return d.mappingStruct(n, out)
  718. case reflect.Map:
  719. // okay
  720. case reflect.Interface:
  721. iface := out
  722. if isStringMap(n) {
  723. out = reflect.MakeMap(d.stringMapType)
  724. } else {
  725. out = reflect.MakeMap(d.generalMapType)
  726. }
  727. iface.Set(out)
  728. default:
  729. d.terror(n, mapTag, out)
  730. return false
  731. }
  732. outt := out.Type()
  733. kt := outt.Key()
  734. et := outt.Elem()
  735. stringMapType := d.stringMapType
  736. generalMapType := d.generalMapType
  737. if outt.Elem() == ifaceType {
  738. if outt.Key().Kind() == reflect.String {
  739. d.stringMapType = outt
  740. } else if outt.Key() == ifaceType {
  741. d.generalMapType = outt
  742. }
  743. }
  744. if out.IsNil() {
  745. out.Set(reflect.MakeMap(outt))
  746. }
  747. for i := 0; i < l; i += 2 {
  748. if isMerge(n.Content[i]) {
  749. d.merge(n.Content[i+1], out)
  750. continue
  751. }
  752. k := reflect.New(kt).Elem()
  753. if d.unmarshal(n.Content[i], k) {
  754. kkind := k.Kind()
  755. if kkind == reflect.Interface {
  756. kkind = k.Elem().Kind()
  757. }
  758. if kkind == reflect.Map || kkind == reflect.Slice {
  759. failf("invalid map key: %#v", k.Interface())
  760. }
  761. e := reflect.New(et).Elem()
  762. if d.unmarshal(n.Content[i+1], e) {
  763. out.SetMapIndex(k, e)
  764. }
  765. }
  766. }
  767. d.stringMapType = stringMapType
  768. d.generalMapType = generalMapType
  769. return true
  770. }
  771. func isStringMap(n *Node) bool {
  772. if n.Kind != MappingNode {
  773. return false
  774. }
  775. l := len(n.Content)
  776. for i := 0; i < l; i += 2 {
  777. if n.Content[i].ShortTag() != strTag {
  778. return false
  779. }
  780. }
  781. return true
  782. }
  783. func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
  784. sinfo, err := getStructInfo(out.Type())
  785. if err != nil {
  786. panic(err)
  787. }
  788. var inlineMap reflect.Value
  789. var elemType reflect.Type
  790. if sinfo.InlineMap != -1 {
  791. inlineMap = out.Field(sinfo.InlineMap)
  792. inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
  793. elemType = inlineMap.Type().Elem()
  794. }
  795. for _, index := range sinfo.InlineUnmarshalers {
  796. field := d.fieldByIndex(n, out, index)
  797. d.prepare(n, field)
  798. }
  799. var doneFields []bool
  800. if d.uniqueKeys {
  801. doneFields = make([]bool, len(sinfo.FieldsList))
  802. }
  803. name := settableValueOf("")
  804. l := len(n.Content)
  805. for i := 0; i < l; i += 2 {
  806. ni := n.Content[i]
  807. if isMerge(ni) {
  808. d.merge(n.Content[i+1], out)
  809. continue
  810. }
  811. if !d.unmarshal(ni, name) {
  812. continue
  813. }
  814. if info, ok := sinfo.FieldsMap[name.String()]; ok {
  815. if d.uniqueKeys {
  816. if doneFields[info.Id] {
  817. d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type()))
  818. continue
  819. }
  820. doneFields[info.Id] = true
  821. }
  822. var field reflect.Value
  823. if info.Inline == nil {
  824. field = out.Field(info.Num)
  825. } else {
  826. field = d.fieldByIndex(n, out, info.Inline)
  827. }
  828. d.unmarshal(n.Content[i+1], field)
  829. } else if sinfo.InlineMap != -1 {
  830. if inlineMap.IsNil() {
  831. inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
  832. }
  833. value := reflect.New(elemType).Elem()
  834. d.unmarshal(n.Content[i+1], value)
  835. inlineMap.SetMapIndex(name, value)
  836. } else if d.knownFields {
  837. d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type()))
  838. }
  839. }
  840. return true
  841. }
  842. func failWantMap() {
  843. failf("map merge requires map or sequence of maps as the value")
  844. }
  845. func (d *decoder) merge(n *Node, out reflect.Value) {
  846. switch n.Kind {
  847. case MappingNode:
  848. d.unmarshal(n, out)
  849. case AliasNode:
  850. if n.Alias != nil && n.Alias.Kind != MappingNode {
  851. failWantMap()
  852. }
  853. d.unmarshal(n, out)
  854. case SequenceNode:
  855. // Step backwards as earlier nodes take precedence.
  856. for i := len(n.Content) - 1; i >= 0; i-- {
  857. ni := n.Content[i]
  858. if ni.Kind == AliasNode {
  859. if ni.Alias != nil && ni.Alias.Kind != MappingNode {
  860. failWantMap()
  861. }
  862. } else if ni.Kind != MappingNode {
  863. failWantMap()
  864. }
  865. d.unmarshal(ni, out)
  866. }
  867. default:
  868. failWantMap()
  869. }
  870. }
  871. func isMerge(n *Node) bool {
  872. return n.Kind == ScalarNode && n.Value == "<<" && (n.Tag == "" || n.Tag == "!" || shortTag(n.Tag) == mergeTag)
  873. }