github.com/pankona/gometalinter@v2.0.11+incompatible/_linters/src/gopkg.in/yaml.v2/decode.go (about) 1 package yaml 2 3 import ( 4 "encoding" 5 "encoding/base64" 6 "fmt" 7 "io" 8 "math" 9 "reflect" 10 "strconv" 11 "time" 12 ) 13 14 const ( 15 documentNode = 1 << iota 16 mappingNode 17 sequenceNode 18 scalarNode 19 aliasNode 20 ) 21 22 type node struct { 23 kind int 24 line, column int 25 tag string 26 // For an alias node, alias holds the resolved alias. 27 alias *node 28 value string 29 implicit bool 30 children []*node 31 anchors map[string]*node 32 } 33 34 // ---------------------------------------------------------------------------- 35 // Parser, produces a node tree out of a libyaml event stream. 36 37 type parser struct { 38 parser yaml_parser_t 39 event yaml_event_t 40 doc *node 41 doneInit bool 42 } 43 44 func newParser(b []byte) *parser { 45 p := parser{} 46 if !yaml_parser_initialize(&p.parser) { 47 panic("failed to initialize YAML emitter") 48 } 49 if len(b) == 0 { 50 b = []byte{'\n'} 51 } 52 yaml_parser_set_input_string(&p.parser, b) 53 return &p 54 } 55 56 func newParserFromReader(r io.Reader) *parser { 57 p := parser{} 58 if !yaml_parser_initialize(&p.parser) { 59 panic("failed to initialize YAML emitter") 60 } 61 yaml_parser_set_input_reader(&p.parser, r) 62 return &p 63 } 64 65 func (p *parser) init() { 66 if p.doneInit { 67 return 68 } 69 p.expect(yaml_STREAM_START_EVENT) 70 p.doneInit = true 71 } 72 73 func (p *parser) destroy() { 74 if p.event.typ != yaml_NO_EVENT { 75 yaml_event_delete(&p.event) 76 } 77 yaml_parser_delete(&p.parser) 78 } 79 80 // expect consumes an event from the event stream and 81 // checks that it's of the expected type. 82 func (p *parser) expect(e yaml_event_type_t) { 83 if p.event.typ == yaml_NO_EVENT { 84 if !yaml_parser_parse(&p.parser, &p.event) { 85 p.fail() 86 } 87 } 88 if p.event.typ == yaml_STREAM_END_EVENT { 89 failf("attempted to go past the end of stream; corrupted value?") 90 } 91 if p.event.typ != e { 92 p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ) 93 p.fail() 94 } 95 yaml_event_delete(&p.event) 96 p.event.typ = yaml_NO_EVENT 97 } 98 99 // peek peeks at the next event in the event stream, 100 // puts the results into p.event and returns the event type. 101 func (p *parser) peek() yaml_event_type_t { 102 if p.event.typ != yaml_NO_EVENT { 103 return p.event.typ 104 } 105 if !yaml_parser_parse(&p.parser, &p.event) { 106 p.fail() 107 } 108 return p.event.typ 109 } 110 111 func (p *parser) fail() { 112 var where string 113 var line int 114 if p.parser.problem_mark.line != 0 { 115 line = p.parser.problem_mark.line 116 // Scanner errors don't iterate line before returning error 117 if p.parser.error == yaml_SCANNER_ERROR { 118 line++ 119 } 120 } else if p.parser.context_mark.line != 0 { 121 line = p.parser.context_mark.line 122 } 123 if line != 0 { 124 where = "line " + strconv.Itoa(line) + ": " 125 } 126 var msg string 127 if len(p.parser.problem) > 0 { 128 msg = p.parser.problem 129 } else { 130 msg = "unknown problem parsing YAML content" 131 } 132 failf("%s%s", where, msg) 133 } 134 135 func (p *parser) anchor(n *node, anchor []byte) { 136 if anchor != nil { 137 p.doc.anchors[string(anchor)] = n 138 } 139 } 140 141 func (p *parser) parse() *node { 142 p.init() 143 switch p.peek() { 144 case yaml_SCALAR_EVENT: 145 return p.scalar() 146 case yaml_ALIAS_EVENT: 147 return p.alias() 148 case yaml_MAPPING_START_EVENT: 149 return p.mapping() 150 case yaml_SEQUENCE_START_EVENT: 151 return p.sequence() 152 case yaml_DOCUMENT_START_EVENT: 153 return p.document() 154 case yaml_STREAM_END_EVENT: 155 // Happens when attempting to decode an empty buffer. 156 return nil 157 default: 158 panic("attempted to parse unknown event: " + p.event.typ.String()) 159 } 160 } 161 162 func (p *parser) node(kind int) *node { 163 return &node{ 164 kind: kind, 165 line: p.event.start_mark.line, 166 column: p.event.start_mark.column, 167 } 168 } 169 170 func (p *parser) document() *node { 171 n := p.node(documentNode) 172 n.anchors = make(map[string]*node) 173 p.doc = n 174 p.expect(yaml_DOCUMENT_START_EVENT) 175 n.children = append(n.children, p.parse()) 176 p.expect(yaml_DOCUMENT_END_EVENT) 177 return n 178 } 179 180 func (p *parser) alias() *node { 181 n := p.node(aliasNode) 182 n.value = string(p.event.anchor) 183 n.alias = p.doc.anchors[n.value] 184 if n.alias == nil { 185 failf("unknown anchor '%s' referenced", n.value) 186 } 187 p.expect(yaml_ALIAS_EVENT) 188 return n 189 } 190 191 func (p *parser) scalar() *node { 192 n := p.node(scalarNode) 193 n.value = string(p.event.value) 194 n.tag = string(p.event.tag) 195 n.implicit = p.event.implicit 196 p.anchor(n, p.event.anchor) 197 p.expect(yaml_SCALAR_EVENT) 198 return n 199 } 200 201 func (p *parser) sequence() *node { 202 n := p.node(sequenceNode) 203 p.anchor(n, p.event.anchor) 204 p.expect(yaml_SEQUENCE_START_EVENT) 205 for p.peek() != yaml_SEQUENCE_END_EVENT { 206 n.children = append(n.children, p.parse()) 207 } 208 p.expect(yaml_SEQUENCE_END_EVENT) 209 return n 210 } 211 212 func (p *parser) mapping() *node { 213 n := p.node(mappingNode) 214 p.anchor(n, p.event.anchor) 215 p.expect(yaml_MAPPING_START_EVENT) 216 for p.peek() != yaml_MAPPING_END_EVENT { 217 n.children = append(n.children, p.parse(), p.parse()) 218 } 219 p.expect(yaml_MAPPING_END_EVENT) 220 return n 221 } 222 223 // ---------------------------------------------------------------------------- 224 // Decoder, unmarshals a node into a provided value. 225 226 type decoder struct { 227 doc *node 228 aliases map[*node]bool 229 mapType reflect.Type 230 terrors []string 231 strict bool 232 } 233 234 var ( 235 mapItemType = reflect.TypeOf(MapItem{}) 236 durationType = reflect.TypeOf(time.Duration(0)) 237 defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) 238 ifaceType = defaultMapType.Elem() 239 timeType = reflect.TypeOf(time.Time{}) 240 ptrTimeType = reflect.TypeOf(&time.Time{}) 241 ) 242 243 func newDecoder(strict bool) *decoder { 244 d := &decoder{mapType: defaultMapType, strict: strict} 245 d.aliases = make(map[*node]bool) 246 return d 247 } 248 249 func (d *decoder) terror(n *node, tag string, out reflect.Value) { 250 if n.tag != "" { 251 tag = n.tag 252 } 253 value := n.value 254 if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { 255 if len(value) > 10 { 256 value = " `" + value[:7] + "...`" 257 } else { 258 value = " `" + value + "`" 259 } 260 } 261 d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) 262 } 263 264 func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { 265 terrlen := len(d.terrors) 266 err := u.UnmarshalYAML(func(v interface{}) (err error) { 267 defer handleErr(&err) 268 d.unmarshal(n, reflect.ValueOf(v)) 269 if len(d.terrors) > terrlen { 270 issues := d.terrors[terrlen:] 271 d.terrors = d.terrors[:terrlen] 272 return &TypeError{issues} 273 } 274 return nil 275 }) 276 if e, ok := err.(*TypeError); ok { 277 d.terrors = append(d.terrors, e.Errors...) 278 return false 279 } 280 if err != nil { 281 fail(err) 282 } 283 return true 284 } 285 286 // d.prepare initializes and dereferences pointers and calls UnmarshalYAML 287 // if a value is found to implement it. 288 // It returns the initialized and dereferenced out value, whether 289 // unmarshalling was already done by UnmarshalYAML, and if so whether 290 // its types unmarshalled appropriately. 291 // 292 // If n holds a null value, prepare returns before doing anything. 293 func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { 294 if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) { 295 return out, false, false 296 } 297 again := true 298 for again { 299 again = false 300 if out.Kind() == reflect.Ptr { 301 if out.IsNil() { 302 out.Set(reflect.New(out.Type().Elem())) 303 } 304 out = out.Elem() 305 again = true 306 } 307 if out.CanAddr() { 308 if u, ok := out.Addr().Interface().(Unmarshaler); ok { 309 good = d.callUnmarshaler(n, u) 310 return out, true, good 311 } 312 } 313 } 314 return out, false, false 315 } 316 317 func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { 318 switch n.kind { 319 case documentNode: 320 return d.document(n, out) 321 case aliasNode: 322 return d.alias(n, out) 323 } 324 out, unmarshaled, good := d.prepare(n, out) 325 if unmarshaled { 326 return good 327 } 328 switch n.kind { 329 case scalarNode: 330 good = d.scalar(n, out) 331 case mappingNode: 332 good = d.mapping(n, out) 333 case sequenceNode: 334 good = d.sequence(n, out) 335 default: 336 panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) 337 } 338 return good 339 } 340 341 func (d *decoder) document(n *node, out reflect.Value) (good bool) { 342 if len(n.children) == 1 { 343 d.doc = n 344 d.unmarshal(n.children[0], out) 345 return true 346 } 347 return false 348 } 349 350 func (d *decoder) alias(n *node, out reflect.Value) (good bool) { 351 if d.aliases[n] { 352 // TODO this could actually be allowed in some circumstances. 353 failf("anchor '%s' value contains itself", n.value) 354 } 355 d.aliases[n] = true 356 good = d.unmarshal(n.alias, out) 357 delete(d.aliases, n) 358 return good 359 } 360 361 var zeroValue reflect.Value 362 363 func resetMap(out reflect.Value) { 364 for _, k := range out.MapKeys() { 365 out.SetMapIndex(k, zeroValue) 366 } 367 } 368 369 func (d *decoder) scalar(n *node, out reflect.Value) bool { 370 var tag string 371 var resolved interface{} 372 if n.tag == "" && !n.implicit { 373 tag = yaml_STR_TAG 374 resolved = n.value 375 } else { 376 tag, resolved = resolve(n.tag, n.value) 377 if tag == yaml_BINARY_TAG { 378 data, err := base64.StdEncoding.DecodeString(resolved.(string)) 379 if err != nil { 380 failf("!!binary value contains invalid base64 data") 381 } 382 resolved = string(data) 383 } 384 } 385 if resolved == nil { 386 if out.Kind() == reflect.Map && !out.CanAddr() { 387 resetMap(out) 388 } else { 389 out.Set(reflect.Zero(out.Type())) 390 } 391 return true 392 } 393 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 394 // We've resolved to exactly the type we want, so use that. 395 out.Set(resolvedv) 396 return true 397 } 398 // Perhaps we can use the value as a TextUnmarshaler to 399 // set its value. 400 if out.CanAddr() { 401 u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) 402 if ok { 403 var text []byte 404 if tag == yaml_BINARY_TAG { 405 text = []byte(resolved.(string)) 406 } else { 407 // We let any value be unmarshaled into TextUnmarshaler. 408 // That might be more lax than we'd like, but the 409 // TextUnmarshaler itself should bowl out any dubious values. 410 text = []byte(n.value) 411 } 412 err := u.UnmarshalText(text) 413 if err != nil { 414 fail(err) 415 } 416 return true 417 } 418 } 419 switch out.Kind() { 420 case reflect.String: 421 if tag == yaml_BINARY_TAG { 422 out.SetString(resolved.(string)) 423 return true 424 } 425 if resolved != nil { 426 out.SetString(n.value) 427 return true 428 } 429 case reflect.Interface: 430 if resolved == nil { 431 out.Set(reflect.Zero(out.Type())) 432 } else if tag == yaml_TIMESTAMP_TAG { 433 // It looks like a timestamp but for backward compatibility 434 // reasons we set it as a string, so that code that unmarshals 435 // timestamp-like values into interface{} will continue to 436 // see a string and not a time.Time. 437 // TODO(v3) Drop this. 438 out.Set(reflect.ValueOf(n.value)) 439 } else { 440 out.Set(reflect.ValueOf(resolved)) 441 } 442 return true 443 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 444 switch resolved := resolved.(type) { 445 case int: 446 if !out.OverflowInt(int64(resolved)) { 447 out.SetInt(int64(resolved)) 448 return true 449 } 450 case int64: 451 if !out.OverflowInt(resolved) { 452 out.SetInt(resolved) 453 return true 454 } 455 case uint64: 456 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 457 out.SetInt(int64(resolved)) 458 return true 459 } 460 case float64: 461 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 462 out.SetInt(int64(resolved)) 463 return true 464 } 465 case string: 466 if out.Type() == durationType { 467 d, err := time.ParseDuration(resolved) 468 if err == nil { 469 out.SetInt(int64(d)) 470 return true 471 } 472 } 473 } 474 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 475 switch resolved := resolved.(type) { 476 case int: 477 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 478 out.SetUint(uint64(resolved)) 479 return true 480 } 481 case int64: 482 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 483 out.SetUint(uint64(resolved)) 484 return true 485 } 486 case uint64: 487 if !out.OverflowUint(uint64(resolved)) { 488 out.SetUint(uint64(resolved)) 489 return true 490 } 491 case float64: 492 if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { 493 out.SetUint(uint64(resolved)) 494 return true 495 } 496 } 497 case reflect.Bool: 498 switch resolved := resolved.(type) { 499 case bool: 500 out.SetBool(resolved) 501 return true 502 } 503 case reflect.Float32, reflect.Float64: 504 switch resolved := resolved.(type) { 505 case int: 506 out.SetFloat(float64(resolved)) 507 return true 508 case int64: 509 out.SetFloat(float64(resolved)) 510 return true 511 case uint64: 512 out.SetFloat(float64(resolved)) 513 return true 514 case float64: 515 out.SetFloat(resolved) 516 return true 517 } 518 case reflect.Struct: 519 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 520 out.Set(resolvedv) 521 return true 522 } 523 case reflect.Ptr: 524 if out.Type().Elem() == reflect.TypeOf(resolved) { 525 // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? 526 elem := reflect.New(out.Type().Elem()) 527 elem.Elem().Set(reflect.ValueOf(resolved)) 528 out.Set(elem) 529 return true 530 } 531 } 532 d.terror(n, tag, out) 533 return false 534 } 535 536 func settableValueOf(i interface{}) reflect.Value { 537 v := reflect.ValueOf(i) 538 sv := reflect.New(v.Type()).Elem() 539 sv.Set(v) 540 return sv 541 } 542 543 func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { 544 l := len(n.children) 545 546 var iface reflect.Value 547 switch out.Kind() { 548 case reflect.Slice: 549 out.Set(reflect.MakeSlice(out.Type(), l, l)) 550 case reflect.Array: 551 if l != out.Len() { 552 failf("invalid array: want %d elements but got %d", out.Len(), l) 553 } 554 case reflect.Interface: 555 // No type hints. Will have to use a generic sequence. 556 iface = out 557 out = settableValueOf(make([]interface{}, l)) 558 default: 559 d.terror(n, yaml_SEQ_TAG, out) 560 return false 561 } 562 et := out.Type().Elem() 563 564 j := 0 565 for i := 0; i < l; i++ { 566 e := reflect.New(et).Elem() 567 if ok := d.unmarshal(n.children[i], e); ok { 568 out.Index(j).Set(e) 569 j++ 570 } 571 } 572 if out.Kind() != reflect.Array { 573 out.Set(out.Slice(0, j)) 574 } 575 if iface.IsValid() { 576 iface.Set(out) 577 } 578 return true 579 } 580 581 func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 582 switch out.Kind() { 583 case reflect.Struct: 584 return d.mappingStruct(n, out) 585 case reflect.Slice: 586 return d.mappingSlice(n, out) 587 case reflect.Map: 588 // okay 589 case reflect.Interface: 590 if d.mapType.Kind() == reflect.Map { 591 iface := out 592 out = reflect.MakeMap(d.mapType) 593 iface.Set(out) 594 } else { 595 slicev := reflect.New(d.mapType).Elem() 596 if !d.mappingSlice(n, slicev) { 597 return false 598 } 599 out.Set(slicev) 600 return true 601 } 602 default: 603 d.terror(n, yaml_MAP_TAG, out) 604 return false 605 } 606 outt := out.Type() 607 kt := outt.Key() 608 et := outt.Elem() 609 610 mapType := d.mapType 611 if outt.Key() == ifaceType && outt.Elem() == ifaceType { 612 d.mapType = outt 613 } 614 615 if out.IsNil() { 616 out.Set(reflect.MakeMap(outt)) 617 } 618 l := len(n.children) 619 for i := 0; i < l; i += 2 { 620 if isMerge(n.children[i]) { 621 d.merge(n.children[i+1], out) 622 continue 623 } 624 k := reflect.New(kt).Elem() 625 if d.unmarshal(n.children[i], k) { 626 kkind := k.Kind() 627 if kkind == reflect.Interface { 628 kkind = k.Elem().Kind() 629 } 630 if kkind == reflect.Map || kkind == reflect.Slice { 631 failf("invalid map key: %#v", k.Interface()) 632 } 633 e := reflect.New(et).Elem() 634 if d.unmarshal(n.children[i+1], e) { 635 d.setMapIndex(n.children[i+1], out, k, e) 636 } 637 } 638 } 639 d.mapType = mapType 640 return true 641 } 642 643 func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) { 644 if d.strict && out.MapIndex(k) != zeroValue { 645 d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface())) 646 return 647 } 648 out.SetMapIndex(k, v) 649 } 650 651 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { 652 outt := out.Type() 653 if outt.Elem() != mapItemType { 654 d.terror(n, yaml_MAP_TAG, out) 655 return false 656 } 657 658 mapType := d.mapType 659 d.mapType = outt 660 661 var slice []MapItem 662 var l = len(n.children) 663 for i := 0; i < l; i += 2 { 664 if isMerge(n.children[i]) { 665 d.merge(n.children[i+1], out) 666 continue 667 } 668 item := MapItem{} 669 k := reflect.ValueOf(&item.Key).Elem() 670 if d.unmarshal(n.children[i], k) { 671 v := reflect.ValueOf(&item.Value).Elem() 672 if d.unmarshal(n.children[i+1], v) { 673 slice = append(slice, item) 674 } 675 } 676 } 677 out.Set(reflect.ValueOf(slice)) 678 d.mapType = mapType 679 return true 680 } 681 682 func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 683 sinfo, err := getStructInfo(out.Type()) 684 if err != nil { 685 panic(err) 686 } 687 name := settableValueOf("") 688 l := len(n.children) 689 690 var inlineMap reflect.Value 691 var elemType reflect.Type 692 if sinfo.InlineMap != -1 { 693 inlineMap = out.Field(sinfo.InlineMap) 694 inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) 695 elemType = inlineMap.Type().Elem() 696 } 697 698 var doneFields []bool 699 if d.strict { 700 doneFields = make([]bool, len(sinfo.FieldsList)) 701 } 702 for i := 0; i < l; i += 2 { 703 ni := n.children[i] 704 if isMerge(ni) { 705 d.merge(n.children[i+1], out) 706 continue 707 } 708 if !d.unmarshal(ni, name) { 709 continue 710 } 711 if info, ok := sinfo.FieldsMap[name.String()]; ok { 712 if d.strict { 713 if doneFields[info.Id] { 714 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type())) 715 continue 716 } 717 doneFields[info.Id] = true 718 } 719 var field reflect.Value 720 if info.Inline == nil { 721 field = out.Field(info.Num) 722 } else { 723 field = out.FieldByIndex(info.Inline) 724 } 725 d.unmarshal(n.children[i+1], field) 726 } else if sinfo.InlineMap != -1 { 727 if inlineMap.IsNil() { 728 inlineMap.Set(reflect.MakeMap(inlineMap.Type())) 729 } 730 value := reflect.New(elemType).Elem() 731 d.unmarshal(n.children[i+1], value) 732 d.setMapIndex(n.children[i+1], inlineMap, name, value) 733 } else if d.strict { 734 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type())) 735 } 736 } 737 return true 738 } 739 740 func failWantMap() { 741 failf("map merge requires map or sequence of maps as the value") 742 } 743 744 func (d *decoder) merge(n *node, out reflect.Value) { 745 switch n.kind { 746 case mappingNode: 747 d.unmarshal(n, out) 748 case aliasNode: 749 an, ok := d.doc.anchors[n.value] 750 if ok && an.kind != mappingNode { 751 failWantMap() 752 } 753 d.unmarshal(n, out) 754 case sequenceNode: 755 // Step backwards as earlier nodes take precedence. 756 for i := len(n.children) - 1; i >= 0; i-- { 757 ni := n.children[i] 758 if ni.kind == aliasNode { 759 an, ok := d.doc.anchors[ni.value] 760 if ok && an.kind != mappingNode { 761 failWantMap() 762 } 763 } else if ni.kind != mappingNode { 764 failWantMap() 765 } 766 d.unmarshal(ni, out) 767 } 768 default: 769 failWantMap() 770 } 771 } 772 773 func isMerge(n *node) bool { 774 return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) 775 }