decode.go (24953B)
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 }