gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/yaml/decode.go (about) 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) callScalarUnmarshaler(n *Node, u ScalarUnmarshaler) (good bool) { 378 err := u.UnmarshalYAMLScalar(n) 379 if e, ok := err.(*TypeError); ok { 380 d.terrors = append(d.terrors, e.Errors...) 381 return false 382 } 383 if err != nil { 384 fail(err) 385 } 386 return true 387 } 388 389 func (d *decoder) callMappingUnmarshaler(n *Node, u MappingUnmarshaler) (good bool) { 390 err := u.UnmarshalYAMLMapping(n) 391 if e, ok := err.(*TypeError); ok { 392 d.terrors = append(d.terrors, e.Errors...) 393 return false 394 } 395 if err != nil { 396 fail(err) 397 } 398 return true 399 } 400 401 func (d *decoder) callSequenceUnmarshaler(n *Node, u SequenceUnmarshaler) (good bool) { 402 err := u.UnmarshalYAMLSequence(n) 403 if e, ok := err.(*TypeError); ok { 404 d.terrors = append(d.terrors, e.Errors...) 405 return false 406 } 407 if err != nil { 408 fail(err) 409 } 410 return true 411 } 412 413 func (d *decoder) callElemUnmarshaler(n *Node, u ElemUnmarshaler) (good bool) { 414 err := u.UnmarshalYAMLElem(n) 415 if e, ok := err.(*TypeError); ok { 416 d.terrors = append(d.terrors, e.Errors...) 417 return false 418 } 419 if err != nil { 420 fail(err) 421 } 422 return true 423 } 424 425 func (d *decoder) callEntryUnmarshaler(k *Node, n *Node, u EntryUnmarshaler) (unmarshaled, good bool) { 426 unmarshaled, err := u.UnmarshalYAMLEntry(k, n) 427 if e, ok := err.(*TypeError); ok { 428 d.terrors = append(d.terrors, e.Errors...) 429 return false, false 430 } 431 if err != nil { 432 fail(err) 433 } 434 return unmarshaled, true 435 } 436 437 func (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) { 438 terrlen := len(d.terrors) 439 err := u.UnmarshalYAML(func(v interface{}) (err error) { 440 defer handleErr(&err) 441 d.unmarshal(n, reflect.ValueOf(v)) 442 if len(d.terrors) > terrlen { 443 issues := d.terrors[terrlen:] 444 d.terrors = d.terrors[:terrlen] 445 return &TypeError{issues} 446 } 447 return nil 448 }) 449 if e, ok := err.(*TypeError); ok { 450 d.terrors = append(d.terrors, e.Errors...) 451 return false 452 } 453 if err != nil { 454 fail(err) 455 } 456 return true 457 } 458 459 // d.prepare initializes and dereferences pointers and calls UnmarshalYAML 460 // if a value is found to implement it. 461 // It returns the initialized and dereferenced out value, whether 462 // unmarshalling was already done by UnmarshalYAML, and if so whether 463 // its types unmarshalled appropriately. 464 // 465 // If n holds a null value, prepare returns before doing anything. 466 func (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { 467 if n.ShortTag() == nullTag { 468 return out, false, false 469 } 470 again := true 471 for again { 472 again = false 473 if out.Kind() == reflect.Ptr { 474 if out.IsNil() { 475 out.Set(reflect.New(out.Type().Elem())) 476 } 477 out = out.Elem() 478 again = true 479 } 480 if out.CanAddr() { 481 outi := out.Addr().Interface() 482 if u, ok := outi.(Unmarshaler); ok { 483 good = d.callUnmarshaler(n, u) 484 return out, true, good 485 } 486 if u, ok := outi.(obsoleteUnmarshaler); ok { 487 good = d.callObsoleteUnmarshaler(n, u) 488 return out, true, good 489 } 490 switch n.Kind { 491 case ScalarNode: 492 if u, ok := outi.(ScalarUnmarshaler); ok { 493 good = d.callScalarUnmarshaler(n, u) 494 return out, true, good 495 } 496 case MappingNode: 497 if u, ok := outi.(MappingUnmarshaler); ok { 498 good = d.callMappingUnmarshaler(n, u) 499 return out, true, good 500 } 501 case SequenceNode: 502 if u, ok := outi.(SequenceUnmarshaler); ok { 503 good = d.callSequenceUnmarshaler(n, u) 504 return out, true, good 505 } 506 } 507 } 508 } 509 return out, false, false 510 } 511 512 func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) { 513 if n.ShortTag() == nullTag { 514 return reflect.Value{} 515 } 516 for _, num := range index { 517 for { 518 if v.Kind() == reflect.Ptr { 519 if v.IsNil() { 520 v.Set(reflect.New(v.Type().Elem())) 521 } 522 v = v.Elem() 523 continue 524 } 525 break 526 } 527 v = v.Field(num) 528 } 529 return v 530 } 531 532 const ( 533 // 400,000 decode operations is ~500kb of dense object declarations, or 534 // ~5kb of dense object declarations with 10000% alias expansion 535 alias_ratio_range_low = 400000 536 537 // 4,000,000 decode operations is ~5MB of dense object declarations, or 538 // ~4.5MB of dense object declarations with 10% alias expansion 539 alias_ratio_range_high = 4000000 540 541 // alias_ratio_range is the range over which we scale allowed alias ratios 542 alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low) 543 ) 544 545 func allowedAliasRatio(decodeCount int) float64 { 546 switch { 547 case decodeCount <= alias_ratio_range_low: 548 // allow 99% to come from alias expansion for small-to-medium documents 549 return 0.99 550 case decodeCount >= alias_ratio_range_high: 551 // allow 10% to come from alias expansion for very large documents 552 return 0.10 553 default: 554 // scale smoothly from 99% down to 10% over the range. 555 // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range. 556 // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps). 557 return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range) 558 } 559 } 560 561 func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) { 562 d.decodeCount++ 563 if d.aliasDepth > 0 { 564 d.aliasCount++ 565 } 566 if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) { 567 failf("document contains excessive aliasing") 568 } 569 if out.Type() == nodeType { 570 out.Set(reflect.ValueOf(n).Elem()) 571 return true 572 } 573 switch n.Kind { 574 case DocumentNode: 575 return d.document(n, out) 576 case AliasNode: 577 return d.alias(n, out) 578 } 579 out, unmarshaled, good := d.prepare(n, out) 580 if unmarshaled { 581 return good 582 } 583 switch n.Kind { 584 case ScalarNode: 585 good = d.scalar(n, out) 586 case MappingNode: 587 good = d.mapping(n, out) 588 case SequenceNode: 589 good = d.sequence(n, out) 590 case 0: 591 if n.IsZero() { 592 return d.null(out) 593 } 594 fallthrough 595 default: 596 failf("cannot decode node with unknown kind %d", n.Kind) 597 } 598 return good 599 } 600 601 func (d *decoder) document(n *Node, out reflect.Value) (good bool) { 602 if len(n.Content) == 1 { 603 d.doc = n 604 d.unmarshal(n.Content[0], out) 605 return true 606 } 607 return false 608 } 609 610 func (d *decoder) alias(n *Node, out reflect.Value) (good bool) { 611 if d.aliases[n] { 612 // TODO this could actually be allowed in some circumstances. 613 failf("anchor '%s' value contains itself", n.Value) 614 } 615 d.aliases[n] = true 616 d.aliasDepth++ 617 good = d.unmarshal(n.Alias, out) 618 d.aliasDepth-- 619 delete(d.aliases, n) 620 return good 621 } 622 623 var zeroValue reflect.Value 624 625 func resetMap(out reflect.Value) { 626 for _, k := range out.MapKeys() { 627 out.SetMapIndex(k, zeroValue) 628 } 629 } 630 631 func (d *decoder) null(out reflect.Value) bool { 632 if out.CanAddr() { 633 switch out.Kind() { 634 case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: 635 out.Set(reflect.Zero(out.Type())) 636 return true 637 } 638 } 639 return false 640 } 641 642 func (d *decoder) scalar(n *Node, out reflect.Value) bool { 643 var tag string 644 var resolved interface{} 645 if n.indicatedString() { 646 tag = strTag 647 resolved = n.Value 648 } else { 649 tag, resolved = resolve(n.Tag, n.Value) 650 if tag == binaryTag { 651 data, err := base64.StdEncoding.DecodeString(resolved.(string)) 652 if err != nil { 653 failf("!!binary value contains invalid base64 data") 654 } 655 resolved = string(data) 656 } 657 } 658 if resolved == nil { 659 return d.null(out) 660 } 661 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 662 // We've resolved to exactly the type we want, so use that. 663 out.Set(resolvedv) 664 return true 665 } 666 // Perhaps we can use the value as a TextUnmarshaler to 667 // set its value. 668 if out.CanAddr() { 669 u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) 670 if ok { 671 var text []byte 672 if tag == binaryTag { 673 text = []byte(resolved.(string)) 674 } else { 675 // We let any value be unmarshaled into TextUnmarshaler. 676 // That might be more lax than we'd like, but the 677 // TextUnmarshaler itself should bowl out any dubious values. 678 text = []byte(n.Value) 679 } 680 err := u.UnmarshalText(text) 681 if err != nil { 682 fail(err) 683 } 684 return true 685 } 686 } 687 switch out.Kind() { 688 case reflect.String: 689 if tag == binaryTag { 690 out.SetString(resolved.(string)) 691 return true 692 } 693 out.SetString(n.Value) 694 return true 695 case reflect.Interface: 696 out.Set(reflect.ValueOf(resolved)) 697 return true 698 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 699 // This used to work in v2, but it's very unfriendly. 700 isDuration := out.Type() == durationType 701 702 switch resolved := resolved.(type) { 703 case int: 704 if !isDuration && !out.OverflowInt(int64(resolved)) { 705 out.SetInt(int64(resolved)) 706 return true 707 } 708 case int64: 709 if !isDuration && !out.OverflowInt(resolved) { 710 out.SetInt(resolved) 711 return true 712 } 713 case uint64: 714 if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 715 out.SetInt(int64(resolved)) 716 return true 717 } 718 case float64: 719 if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 720 out.SetInt(int64(resolved)) 721 return true 722 } 723 case string: 724 if out.Type() == durationType { 725 d, err := time.ParseDuration(resolved) 726 if err == nil { 727 out.SetInt(int64(d)) 728 return true 729 } 730 } 731 } 732 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 733 switch resolved := resolved.(type) { 734 case int: 735 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 736 out.SetUint(uint64(resolved)) 737 return true 738 } 739 case int64: 740 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 741 out.SetUint(uint64(resolved)) 742 return true 743 } 744 case uint64: 745 if !out.OverflowUint(uint64(resolved)) { 746 out.SetUint(uint64(resolved)) 747 return true 748 } 749 case float64: 750 if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { 751 out.SetUint(uint64(resolved)) 752 return true 753 } 754 } 755 case reflect.Bool: 756 switch resolved := resolved.(type) { 757 case bool: 758 out.SetBool(resolved) 759 return true 760 case string: 761 // This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html). 762 // It only works if explicitly attempting to unmarshal into a typed bool value. 763 switch resolved { 764 case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON": 765 out.SetBool(true) 766 return true 767 case "n", "N", "no", "No", "NO", "off", "Off", "OFF": 768 out.SetBool(false) 769 return true 770 } 771 } 772 case reflect.Float32, reflect.Float64: 773 switch resolved := resolved.(type) { 774 case int: 775 out.SetFloat(float64(resolved)) 776 return true 777 case int64: 778 out.SetFloat(float64(resolved)) 779 return true 780 case uint64: 781 out.SetFloat(float64(resolved)) 782 return true 783 case float64: 784 out.SetFloat(resolved) 785 return true 786 } 787 case reflect.Struct: 788 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 789 out.Set(resolvedv) 790 return true 791 } 792 case reflect.Ptr: 793 panic("yaml internal error: please report the issue") 794 } 795 d.terror(n, tag, out) 796 return false 797 } 798 799 func settableValueOf(i interface{}) reflect.Value { 800 v := reflect.ValueOf(i) 801 sv := reflect.New(v.Type()).Elem() 802 sv.Set(v) 803 return sv 804 } 805 806 func (d *decoder) sequence(n *Node, out reflect.Value) (good bool) { 807 unmarshaled, good := d.sequenceElems(n, out) 808 if unmarshaled { 809 return good 810 } 811 812 l := len(n.Content) 813 814 var iface reflect.Value 815 switch out.Kind() { 816 case reflect.Slice: 817 out.Set(reflect.MakeSlice(out.Type(), l, l)) 818 case reflect.Array: 819 if l != out.Len() { 820 failf("invalid array: want %d elements but got %d", out.Len(), l) 821 } 822 case reflect.Interface: 823 // No type hints. Will have to use a generic sequence. 824 iface = out 825 out = settableValueOf(make([]interface{}, l)) 826 default: 827 d.terror(n, seqTag, out) 828 return false 829 } 830 et := out.Type().Elem() 831 832 j := 0 833 for i := 0; i < l; i++ { 834 e := reflect.New(et).Elem() 835 if ok := d.unmarshal(n.Content[i], e); ok { 836 out.Index(j).Set(e) 837 j++ 838 } 839 } 840 if out.Kind() != reflect.Array { 841 out.Set(out.Slice(0, j)) 842 } 843 if iface.IsValid() { 844 iface.Set(out) 845 } 846 return true 847 } 848 849 func (d *decoder) sequenceElems(n *Node, out reflect.Value) (unmarshaled, good bool) { 850 if n.ShortTag() == nullTag { 851 return false, false 852 } 853 again := true 854 for again { 855 again = false 856 if out.Kind() == reflect.Ptr { 857 if out.IsNil() { 858 out.Set(reflect.New(out.Type().Elem())) 859 } 860 out = out.Elem() 861 again = true 862 } 863 if out.CanAddr() { 864 outi := out.Addr().Interface() 865 if u, ok := outi.(ElemUnmarshaler); ok { 866 l := len(n.Content) 867 for i := 0; i < l; i++ { 868 if good = d.callElemUnmarshaler(n.Content[i], u); !good { 869 return true, false 870 } 871 } 872 return true, true 873 } 874 } 875 } 876 return false, false 877 } 878 879 func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) { 880 l := len(n.Content) 881 if d.uniqueKeys { 882 nerrs := len(d.terrors) 883 for i := 0; i < l; i += 2 { 884 ni := n.Content[i] 885 for j := i + 2; j < l; j += 2 { 886 nj := n.Content[j] 887 if ni.Kind == nj.Kind && ni.Value == nj.Value { 888 d.terrors = append(d.terrors, fmt.Sprintf("line %d: mapping key %#v already defined at line %d", nj.Line, nj.Value, ni.Line)) 889 } 890 } 891 } 892 if len(d.terrors) > nerrs { 893 return false 894 } 895 } 896 if out.Kind() == reflect.Struct { 897 return d.mappingStruct(n, out) 898 } 899 unmarshaled, good := d.mappingEntries(n, out) 900 if unmarshaled { 901 return good 902 } 903 switch out.Kind() { 904 case reflect.Map: 905 // okay 906 case reflect.Interface: 907 iface := out 908 if isStringMap(n) { 909 out = reflect.MakeMap(d.stringMapType) 910 } else { 911 out = reflect.MakeMap(d.generalMapType) 912 } 913 iface.Set(out) 914 default: 915 d.terror(n, mapTag, out) 916 return false 917 } 918 919 outt := out.Type() 920 kt := outt.Key() 921 et := outt.Elem() 922 923 stringMapType := d.stringMapType 924 generalMapType := d.generalMapType 925 if outt.Elem() == ifaceType { 926 if outt.Key().Kind() == reflect.String { 927 d.stringMapType = outt 928 } else if outt.Key() == ifaceType { 929 d.generalMapType = outt 930 } 931 } 932 933 mergedFields := d.mergedFields 934 d.mergedFields = nil 935 936 var mergeNode *Node 937 938 mapIsNew := false 939 if out.IsNil() { 940 out.Set(reflect.MakeMap(outt)) 941 mapIsNew = true 942 } 943 for i := 0; i < l; i += 2 { 944 if isMerge(n.Content[i]) { 945 mergeNode = n.Content[i+1] 946 continue 947 } 948 k := reflect.New(kt).Elem() 949 if d.unmarshal(n.Content[i], k) { 950 if mergedFields != nil { 951 ki := k.Interface() 952 if mergedFields[ki] { 953 continue 954 } 955 mergedFields[ki] = true 956 } 957 kkind := k.Kind() 958 if kkind == reflect.Interface { 959 kkind = k.Elem().Kind() 960 } 961 if kkind == reflect.Map || kkind == reflect.Slice { 962 failf("invalid map key: %#v", k.Interface()) 963 } 964 e := reflect.New(et).Elem() 965 if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) { 966 out.SetMapIndex(k, e) 967 } 968 } 969 } 970 971 d.mergedFields = mergedFields 972 if mergeNode != nil { 973 d.merge(n, mergeNode, out) 974 } 975 976 d.stringMapType = stringMapType 977 d.generalMapType = generalMapType 978 return true 979 } 980 981 func isStringMap(n *Node) bool { 982 if n.Kind != MappingNode { 983 return false 984 } 985 l := len(n.Content) 986 for i := 0; i < l; i += 2 { 987 shortTag := n.Content[i].ShortTag() 988 if shortTag != strTag && shortTag != mergeTag { 989 return false 990 } 991 } 992 return true 993 } 994 995 func (d *decoder) mappingEntries(n *Node, out reflect.Value) (unmarshaled, good bool) { 996 if n.ShortTag() == nullTag { 997 return false, false 998 } 999 again := true 1000 for again { 1001 again = false 1002 if out.Kind() == reflect.Ptr { 1003 if out.IsNil() { 1004 out.Set(reflect.New(out.Type().Elem())) 1005 } 1006 out = out.Elem() 1007 again = true 1008 } 1009 if out.CanAddr() { 1010 outi := out.Addr().Interface() 1011 if u, ok := outi.(EntryUnmarshaler); ok { 1012 l := len(n.Content) 1013 1014 stringMapType := d.stringMapType 1015 generalMapType := d.generalMapType 1016 1017 mergedFields := d.mergedFields 1018 d.mergedFields = nil 1019 1020 var mergeNode *Node 1021 1022 for i := 0; i < l; i += 2 { 1023 if isMerge(n.Content[i]) { 1024 mergeNode = n.Content[i+1] 1025 continue 1026 } 1027 k := reflect.New(ifaceType).Elem() 1028 if d.unmarshal(n.Content[i], k) { 1029 ki := k.Interface() 1030 if mergedFields != nil { 1031 if mergedFields[ki] { 1032 continue 1033 } 1034 mergedFields[ki] = true 1035 } 1036 unmarshaled, good = d.callEntryUnmarshaler(n.Content[i], n.Content[i+1], u) 1037 if unmarshaled && !good { 1038 return true, false 1039 } 1040 } 1041 } 1042 1043 d.mergedFields = mergedFields 1044 if mergeNode != nil { 1045 d.merge(n, mergeNode, out) 1046 } 1047 1048 d.stringMapType = stringMapType 1049 d.generalMapType = generalMapType 1050 return true, true 1051 } 1052 } 1053 } 1054 return false, false 1055 } 1056 1057 func (d *decoder) entry(k *Node, n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { 1058 if n.ShortTag() == nullTag { 1059 return out, false, false 1060 } 1061 again := true 1062 for again { 1063 again = false 1064 if out.Kind() == reflect.Ptr { 1065 if out.IsNil() { 1066 out.Set(reflect.New(out.Type().Elem())) 1067 } 1068 out = out.Elem() 1069 again = true 1070 } 1071 if out.CanAddr() { 1072 outi := out.Addr().Interface() 1073 if u, ok := outi.(EntryUnmarshaler); ok { 1074 unmarshaled, good = d.callEntryUnmarshaler(k, n, u) 1075 return out, unmarshaled, good 1076 } 1077 } 1078 } 1079 return out, false, false 1080 } 1081 1082 func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) { 1083 sinfo, err := getStructInfo(out.Type()) 1084 if err != nil { 1085 panic(err) 1086 } 1087 1088 var inlineMap reflect.Value 1089 var elemType reflect.Type 1090 if sinfo.InlineMap != -1 { 1091 inlineMap = out.Field(sinfo.InlineMap) 1092 elemType = inlineMap.Type().Elem() 1093 } 1094 1095 for _, index := range sinfo.InlineUnmarshalers { 1096 field := d.fieldByIndex(n, out, index) 1097 d.prepare(n, field) 1098 } 1099 1100 mergedFields := d.mergedFields 1101 d.mergedFields = nil 1102 var mergeNode *Node 1103 var doneFields []bool 1104 if d.uniqueKeys { 1105 doneFields = make([]bool, len(sinfo.FieldsList)) 1106 } 1107 name := settableValueOf("") 1108 l := len(n.Content) 1109 for i := 0; i < l; i += 2 { 1110 ni := n.Content[i] 1111 if isMerge(ni) { 1112 mergeNode = n.Content[i+1] 1113 continue 1114 } 1115 if !d.unmarshal(ni, name) { 1116 continue 1117 } 1118 sname := name.String() 1119 if mergedFields != nil { 1120 if mergedFields[sname] { 1121 continue 1122 } 1123 mergedFields[sname] = true 1124 } 1125 if info, ok := sinfo.FieldsMap[sname]; ok { 1126 if d.uniqueKeys { 1127 if doneFields[info.Id] { 1128 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type())) 1129 continue 1130 } 1131 doneFields[info.Id] = true 1132 } 1133 var field reflect.Value 1134 if info.Inline == nil { 1135 field = out.Field(info.Num) 1136 } else { 1137 field = d.fieldByIndex(n, out, info.Inline) 1138 } 1139 d.unmarshal(n.Content[i+1], field) 1140 } else if sinfo.InlineMap != -1 || len(sinfo.InlineEntryUnmarshalers) > 0 { 1141 if sinfo.InlineMap != -1 { 1142 if inlineMap.IsNil() { 1143 inlineMap.Set(reflect.MakeMap(inlineMap.Type())) 1144 } 1145 value := reflect.New(elemType).Elem() 1146 d.unmarshal(n.Content[i+1], value) 1147 inlineMap.SetMapIndex(name, value) 1148 } 1149 if len(sinfo.InlineEntryUnmarshalers) > 0 { 1150 for _, index := range sinfo.InlineEntryUnmarshalers { 1151 field := d.fieldByIndex(n, out, index) 1152 d.entry(ni, n.Content[i+1], field) 1153 } 1154 } 1155 } else if d.knownFields { 1156 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type())) 1157 } 1158 } 1159 1160 d.mergedFields = mergedFields 1161 if mergeNode != nil { 1162 d.merge(n, mergeNode, out) 1163 } 1164 return true 1165 } 1166 1167 func failWantMap() { 1168 failf("map merge requires map or sequence of maps as the value") 1169 } 1170 1171 func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) { 1172 mergedFields := d.mergedFields 1173 if mergedFields == nil { 1174 d.mergedFields = make(map[interface{}]bool) 1175 for i := 0; i < len(parent.Content); i += 2 { 1176 k := reflect.New(ifaceType).Elem() 1177 if d.unmarshal(parent.Content[i], k) { 1178 d.mergedFields[k.Interface()] = true 1179 } 1180 } 1181 } 1182 1183 switch merge.Kind { 1184 case MappingNode: 1185 d.unmarshal(merge, out) 1186 case AliasNode: 1187 if merge.Alias != nil && merge.Alias.Kind != MappingNode { 1188 failWantMap() 1189 } 1190 d.unmarshal(merge, out) 1191 case SequenceNode: 1192 for i := 0; i < len(merge.Content); i++ { 1193 ni := merge.Content[i] 1194 if ni.Kind == AliasNode { 1195 if ni.Alias != nil && ni.Alias.Kind != MappingNode { 1196 failWantMap() 1197 } 1198 } else if ni.Kind != MappingNode { 1199 failWantMap() 1200 } 1201 d.unmarshal(ni, out) 1202 } 1203 default: 1204 failWantMap() 1205 } 1206 1207 d.mergedFields = mergedFields 1208 } 1209 1210 func isMerge(n *Node) bool { 1211 return n.Kind == ScalarNode && n.Value == "<<" && (n.Tag == "" || n.Tag == "!" || shortTag(n.Tag) == mergeTag) 1212 }