decode.go raw

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