1// Copyright (c) Faye Amacker. All rights reserved. 2// Licensed under the MIT License. See LICENSE in the project root for license information. 3 4package cbor 5 6import ( 7 "encoding" 8 "encoding/binary" 9 "errors" 10 "fmt" 11 "io" 12 "math" 13 "math/big" 14 "reflect" 15 "strconv" 16 "strings" 17 "time" 18 "unicode/utf8" 19 20 "github.com/x448/float16" 21) 22 23// Unmarshal parses the CBOR-encoded data into the value pointed to by v 24// using default decoding options. If v is nil, not a pointer, or 25// a nil pointer, Unmarshal returns an error. 26// 27// To unmarshal CBOR into a value implementing the Unmarshaler interface, 28// Unmarshal calls that value's UnmarshalCBOR method with a valid 29// CBOR value. 30// 31// To unmarshal CBOR byte string into a value implementing the 32// encoding.BinaryUnmarshaler interface, Unmarshal calls that value's 33// UnmarshalBinary method with decoded CBOR byte string. 34// 35// To unmarshal CBOR into a pointer, Unmarshal sets the pointer to nil 36// if CBOR data is null (0xf6) or undefined (0xf7). Otherwise, Unmarshal 37// unmarshals CBOR into the value pointed to by the pointer. If the 38// pointer is nil, Unmarshal creates a new value for it to point to. 39// 40// To unmarshal CBOR into an empty interface value, Unmarshal uses the 41// following rules: 42// 43// CBOR booleans decode to bool. 44// CBOR positive integers decode to uint64. 45// CBOR negative integers decode to int64 (big.Int if value overflows). 46// CBOR floating points decode to float64. 47// CBOR byte strings decode to []byte. 48// CBOR text strings decode to string. 49// CBOR arrays decode to []interface{}. 50// CBOR maps decode to map[interface{}]interface{}. 51// CBOR null and undefined values decode to nil. 52// CBOR times (tag 0 and 1) decode to time.Time. 53// CBOR bignums (tag 2 and 3) decode to big.Int. 54// 55// To unmarshal a CBOR array into a slice, Unmarshal allocates a new slice 56// if the CBOR array is empty or slice capacity is less than CBOR array length. 57// Otherwise Unmarshal overwrites existing elements, and sets slice length 58// to CBOR array length. 59// 60// To unmarshal a CBOR array into a Go array, Unmarshal decodes CBOR array 61// elements into Go array elements. If the Go array is smaller than the 62// CBOR array, the extra CBOR array elements are discarded. If the CBOR 63// array is smaller than the Go array, the extra Go array elements are 64// set to zero values. 65// 66// To unmarshal a CBOR array into a struct, struct must have a special field "_" 67// with struct tag `cbor:",toarray"`. Go array elements are decoded into struct 68// fields. Any "omitempty" struct field tag option is ignored in this case. 69// 70// To unmarshal a CBOR map into a map, Unmarshal allocates a new map only if the 71// map is nil. Otherwise Unmarshal reuses the existing map and keeps existing 72// entries. Unmarshal stores key-value pairs from the CBOR map into Go map. 73// See DecOptions.DupMapKey to enable duplicate map key detection. 74// 75// To unmarshal a CBOR map into a struct, Unmarshal matches CBOR map keys to the 76// keys in the following priority: 77// 78// 1. "cbor" key in struct field tag, 79// 2. "json" key in struct field tag, 80// 3. struct field name. 81// 82// Unmarshal tries an exact match for field name, then a case-insensitive match. 83// Map key-value pairs without corresponding struct fields are ignored. See 84// DecOptions.ExtraReturnErrors to return error at unknown field. 85// 86// To unmarshal a CBOR text string into a time.Time value, Unmarshal parses text 87// string formatted in RFC3339. To unmarshal a CBOR integer/float into a 88// time.Time value, Unmarshal creates an unix time with integer/float as seconds 89// and fractional seconds since January 1, 1970 UTC. 90// 91// To unmarshal CBOR null (0xf6) and undefined (0xf7) values into a 92// slice/map/pointer, Unmarshal sets Go value to nil. Because null is often 93// used to mean "not present", unmarshalling CBOR null and undefined value 94// into any other Go type has no effect and returns no error. 95// 96// Unmarshal supports CBOR tag 55799 (self-describe CBOR), tag 0 and 1 (time), 97// and tag 2 and 3 (bignum). 98func Unmarshal(data []byte, v interface{}) error { 99 return defaultDecMode.Unmarshal(data, v) 100} 101 102// Valid checks whether the CBOR data is complete and well-formed. 103func Valid(data []byte) error { 104 return defaultDecMode.Valid(data) 105} 106 107// Unmarshaler is the interface implemented by types that wish to unmarshal 108// CBOR data themselves. The input is a valid CBOR value. UnmarshalCBOR 109// must copy the CBOR data if it needs to use it after returning. 110type Unmarshaler interface { 111 UnmarshalCBOR([]byte) error 112} 113 114// InvalidUnmarshalError describes an invalid argument passed to Unmarshal. 115type InvalidUnmarshalError struct { 116 s string 117} 118 119func (e *InvalidUnmarshalError) Error() string { 120 return e.s 121} 122 123// UnmarshalTypeError describes a CBOR value that can't be decoded to a Go type. 124type UnmarshalTypeError struct { 125 CBORType string // type of CBOR value 126 GoType string // type of Go value it could not be decoded into 127 StructFieldName string // name of the struct field holding the Go value (optional) 128 errorMsg string // additional error message (optional) 129} 130 131func (e *UnmarshalTypeError) Error() string { 132 var s string 133 if e.StructFieldName != "" { 134 s = "cbor: cannot unmarshal " + e.CBORType + " into Go struct field " + e.StructFieldName + " of type " + e.GoType 135 } else { 136 s = "cbor: cannot unmarshal " + e.CBORType + " into Go value of type " + e.GoType 137 } 138 if e.errorMsg != "" { 139 s += " (" + e.errorMsg + ")" 140 } 141 return s 142} 143 144// DupMapKeyError describes detected duplicate map key in CBOR map. 145type DupMapKeyError struct { 146 Key interface{} 147 Index int 148} 149 150func (e *DupMapKeyError) Error() string { 151 return fmt.Sprintf("cbor: found duplicate map key \"%v\" at map element index %d", e.Key, e.Index) 152} 153 154// UnknownFieldError describes detected unknown field in CBOR map when decoding to Go struct. 155type UnknownFieldError struct { 156 Index int 157} 158 159func (e *UnknownFieldError) Error() string { 160 return fmt.Sprintf("cbor: found unknown field at map element index %d", e.Index) 161} 162 163// DupMapKeyMode specifies how to enforce duplicate map key. 164type DupMapKeyMode int 165 166const ( 167 // DupMapKeyQuiet doesn't enforce duplicate map key. Decoder quietly (no error) 168 // uses faster of "keep first" or "keep last" depending on Go data type and other factors. 169 DupMapKeyQuiet DupMapKeyMode = iota 170 171 // DupMapKeyEnforcedAPF enforces detection and rejection of duplicate map keys. 172 // APF means "Allow Partial Fill" and the destination map or struct can be partially filled. 173 // If a duplicate map key is detected, DupMapKeyError is returned without further decoding 174 // of the map. It's the caller's responsibility to respond to DupMapKeyError by 175 // discarding the partially filled result if their protocol requires it. 176 // WARNING: using DupMapKeyEnforcedAPF will decrease performance and increase memory use. 177 DupMapKeyEnforcedAPF 178 179 maxDupMapKeyMode 180) 181 182func (dmkm DupMapKeyMode) valid() bool { 183 return dmkm < maxDupMapKeyMode 184} 185 186// IndefLengthMode specifies whether to allow indefinite length items. 187type IndefLengthMode int 188 189const ( 190 // IndefLengthAllowed allows indefinite length items. 191 IndefLengthAllowed IndefLengthMode = iota 192 193 // IndefLengthForbidden disallows indefinite length items. 194 IndefLengthForbidden 195 196 maxIndefLengthMode 197) 198 199func (m IndefLengthMode) valid() bool { 200 return m < maxIndefLengthMode 201} 202 203// TagsMode specifies whether to allow CBOR tags. 204type TagsMode int 205 206const ( 207 // TagsAllowed allows CBOR tags. 208 TagsAllowed TagsMode = iota 209 210 // TagsForbidden disallows CBOR tags. 211 TagsForbidden 212 213 maxTagsMode 214) 215 216func (tm TagsMode) valid() bool { 217 return tm < maxTagsMode 218} 219 220// IntDecMode specifies which Go int type (int64 or uint64) should 221// be used when decoding CBOR int (major type 0 and 1) to Go interface{}. 222type IntDecMode int 223 224const ( 225 // IntDecConvertNone affects how CBOR int (major type 0 and 1) decodes to Go interface{}. 226 // It makes CBOR positive int (major type 0) decode to uint64 value, and 227 // CBOR negative int (major type 1) decode to int64 value. 228 IntDecConvertNone IntDecMode = iota 229 230 // IntDecConvertSigned affects how CBOR int (major type 0 and 1) decodes to Go interface{}. 231 // It makes CBOR positive/negative int (major type 0 and 1) decode to int64 value. 232 // If value overflows int64, UnmarshalTypeError is returned. 233 IntDecConvertSigned 234 235 maxIntDec 236) 237 238func (idm IntDecMode) valid() bool { 239 return idm < maxIntDec 240} 241 242// ExtraDecErrorCond specifies extra conditions that should be treated as errors. 243type ExtraDecErrorCond uint 244 245// ExtraDecErrorNone indicates no extra error condition. 246const ExtraDecErrorNone ExtraDecErrorCond = 0 247 248const ( 249 // ExtraDecErrorUnknownField indicates error condition when destination 250 // Go struct doesn't have a field matching a CBOR map key. 251 ExtraDecErrorUnknownField ExtraDecErrorCond = 1 << iota 252 253 maxExtraDecError 254) 255 256func (ec ExtraDecErrorCond) valid() bool { 257 return ec < maxExtraDecError 258} 259 260// DecOptions specifies decoding options. 261type DecOptions struct { 262 // DupMapKey specifies whether to enforce duplicate map key. 263 DupMapKey DupMapKeyMode 264 265 // TimeTag specifies whether to check validity of time.Time (e.g. valid tag number and tag content type). 266 // For now, valid tag number means 0 or 1 as specified in RFC 7049 if the Go type is time.Time. 267 TimeTag DecTagMode 268 269 // MaxNestedLevels specifies the max nested levels allowed for any combination of CBOR array, maps, and tags. 270 // Default is 32 levels and it can be set to [4, 256]. 271 MaxNestedLevels int 272 273 // MaxArrayElements specifies the max number of elements for CBOR arrays. 274 // Default is 128*1024=131072 and it can be set to [16, 2147483647] 275 MaxArrayElements int 276 277 // MaxMapPairs specifies the max number of key-value pairs for CBOR maps. 278 // Default is 128*1024=131072 and it can be set to [16, 2147483647] 279 MaxMapPairs int 280 281 // IndefLength specifies whether to allow indefinite length CBOR items. 282 IndefLength IndefLengthMode 283 284 // TagsMd specifies whether to allow CBOR tags (major type 6). 285 TagsMd TagsMode 286 287 // IntDec specifies which Go integer type (int64 or uint64) to use 288 // when decoding CBOR int (major type 0 and 1) to Go interface{}. 289 IntDec IntDecMode 290 291 // ExtraReturnErrors specifies extra conditions that should be treated as errors. 292 ExtraReturnErrors ExtraDecErrorCond 293 294 // DefaultMapType specifies Go map type to create and decode to 295 // when unmarshalling CBOR into an empty interface value. 296 // By default, unmarshal uses map[interface{}]interface{}. 297 DefaultMapType reflect.Type 298} 299 300// DecMode returns DecMode with immutable options and no tags (safe for concurrency). 301func (opts DecOptions) DecMode() (DecMode, error) { 302 return opts.decMode() 303} 304 305// DecModeWithTags returns DecMode with options and tags that are both immutable (safe for concurrency). 306func (opts DecOptions) DecModeWithTags(tags TagSet) (DecMode, error) { 307 if opts.TagsMd == TagsForbidden { 308 return nil, errors.New("cbor: cannot create DecMode with TagSet when TagsMd is TagsForbidden") 309 } 310 if tags == nil { 311 return nil, errors.New("cbor: cannot create DecMode with nil value as TagSet") 312 } 313 314 dm, err := opts.decMode() 315 if err != nil { 316 return nil, err 317 } 318 319 // Copy tags 320 ts := tagSet(make(map[reflect.Type]*tagItem)) 321 syncTags := tags.(*syncTagSet) 322 syncTags.RLock() 323 for contentType, tag := range syncTags.t { 324 if tag.opts.DecTag != DecTagIgnored { 325 ts[contentType] = tag 326 } 327 } 328 syncTags.RUnlock() 329 330 if len(ts) > 0 { 331 dm.tags = ts 332 } 333 334 return dm, nil 335} 336 337// DecModeWithSharedTags returns DecMode with immutable options and mutable shared tags (safe for concurrency). 338func (opts DecOptions) DecModeWithSharedTags(tags TagSet) (DecMode, error) { 339 if opts.TagsMd == TagsForbidden { 340 return nil, errors.New("cbor: cannot create DecMode with TagSet when TagsMd is TagsForbidden") 341 } 342 if tags == nil { 343 return nil, errors.New("cbor: cannot create DecMode with nil value as TagSet") 344 } 345 dm, err := opts.decMode() 346 if err != nil { 347 return nil, err 348 } 349 dm.tags = tags 350 return dm, nil 351} 352 353const ( 354 defaultMaxArrayElements = 131072 355 minMaxArrayElements = 16 356 maxMaxArrayElements = 2147483647 357 358 defaultMaxMapPairs = 131072 359 minMaxMapPairs = 16 360 maxMaxMapPairs = 2147483647 361) 362 363func (opts DecOptions) decMode() (*decMode, error) { 364 if !opts.DupMapKey.valid() { 365 return nil, errors.New("cbor: invalid DupMapKey " + strconv.Itoa(int(opts.DupMapKey))) 366 } 367 if !opts.TimeTag.valid() { 368 return nil, errors.New("cbor: invalid TimeTag " + strconv.Itoa(int(opts.TimeTag))) 369 } 370 if !opts.IndefLength.valid() { 371 return nil, errors.New("cbor: invalid IndefLength " + strconv.Itoa(int(opts.IndefLength))) 372 } 373 if !opts.TagsMd.valid() { 374 return nil, errors.New("cbor: invalid TagsMd " + strconv.Itoa(int(opts.TagsMd))) 375 } 376 if !opts.IntDec.valid() { 377 return nil, errors.New("cbor: invalid IntDec " + strconv.Itoa(int(opts.IntDec))) 378 } 379 if opts.MaxNestedLevels == 0 { 380 opts.MaxNestedLevels = 32 381 } else if opts.MaxNestedLevels < 4 || opts.MaxNestedLevels > 256 { 382 return nil, errors.New("cbor: invalid MaxNestedLevels " + strconv.Itoa(opts.MaxNestedLevels) + " (range is [4, 256])") 383 } 384 if opts.MaxArrayElements == 0 { 385 opts.MaxArrayElements = defaultMaxArrayElements 386 } else if opts.MaxArrayElements < minMaxArrayElements || opts.MaxArrayElements > maxMaxArrayElements { 387 return nil, errors.New("cbor: invalid MaxArrayElements " + strconv.Itoa(opts.MaxArrayElements) + " (range is [" + strconv.Itoa(minMaxArrayElements) + ", " + strconv.Itoa(maxMaxArrayElements) + "])") 388 } 389 if opts.MaxMapPairs == 0 { 390 opts.MaxMapPairs = defaultMaxMapPairs 391 } else if opts.MaxMapPairs < minMaxMapPairs || opts.MaxMapPairs > maxMaxMapPairs { 392 return nil, errors.New("cbor: invalid MaxMapPairs " + strconv.Itoa(opts.MaxMapPairs) + " (range is [" + strconv.Itoa(minMaxMapPairs) + ", " + strconv.Itoa(maxMaxMapPairs) + "])") 393 } 394 if !opts.ExtraReturnErrors.valid() { 395 return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) 396 } 397 if opts.DefaultMapType != nil && opts.DefaultMapType.Kind() != reflect.Map { 398 return nil, fmt.Errorf("cbor: invalid DefaultMapType %s", opts.DefaultMapType) 399 } 400 dm := decMode{ 401 dupMapKey: opts.DupMapKey, 402 timeTag: opts.TimeTag, 403 maxNestedLevels: opts.MaxNestedLevels, 404 maxArrayElements: opts.MaxArrayElements, 405 maxMapPairs: opts.MaxMapPairs, 406 indefLength: opts.IndefLength, 407 tagsMd: opts.TagsMd, 408 intDec: opts.IntDec, 409 extraReturnErrors: opts.ExtraReturnErrors, 410 defaultMapType: opts.DefaultMapType, 411 } 412 return &dm, nil 413} 414 415// DecMode is the main interface for CBOR decoding. 416type DecMode interface { 417 // Unmarshal parses the CBOR-encoded data into the value pointed to by v 418 // using the decoding mode. If v is nil, not a pointer, or a nil pointer, 419 // Unmarshal returns an error. 420 // 421 // See the documentation for Unmarshal for details. 422 Unmarshal(data []byte, v interface{}) error 423 // Valid checks whether the CBOR data is complete and well-formed. 424 Valid(data []byte) error 425 // NewDecoder returns a new decoder that reads from r using dm DecMode. 426 NewDecoder(r io.Reader) *Decoder 427 // DecOptions returns user specified options used to create this DecMode. 428 DecOptions() DecOptions 429} 430 431type decMode struct { 432 tags tagProvider 433 dupMapKey DupMapKeyMode 434 timeTag DecTagMode 435 maxNestedLevels int 436 maxArrayElements int 437 maxMapPairs int 438 indefLength IndefLengthMode 439 tagsMd TagsMode 440 intDec IntDecMode 441 extraReturnErrors ExtraDecErrorCond 442 defaultMapType reflect.Type 443} 444 445var defaultDecMode, _ = DecOptions{}.decMode() 446 447// DecOptions returns user specified options used to create this DecMode. 448func (dm *decMode) DecOptions() DecOptions { 449 return DecOptions{ 450 DupMapKey: dm.dupMapKey, 451 TimeTag: dm.timeTag, 452 MaxNestedLevels: dm.maxNestedLevels, 453 MaxArrayElements: dm.maxArrayElements, 454 MaxMapPairs: dm.maxMapPairs, 455 IndefLength: dm.indefLength, 456 TagsMd: dm.tagsMd, 457 IntDec: dm.intDec, 458 ExtraReturnErrors: dm.extraReturnErrors, 459 } 460} 461 462// Unmarshal parses the CBOR-encoded data into the value pointed to by v 463// using dm decoding mode. If v is nil, not a pointer, or a nil pointer, 464// Unmarshal returns an error. 465// 466// See the documentation for Unmarshal for details. 467func (dm *decMode) Unmarshal(data []byte, v interface{}) error { 468 d := decoder{data: data, dm: dm} 469 return d.value(v) 470} 471 472// Valid checks whether the CBOR data is complete and well-formed. 473func (dm *decMode) Valid(data []byte) error { 474 d := decoder{data: data, dm: dm} 475 return d.valid() 476} 477 478// NewDecoder returns a new decoder that reads from r using dm DecMode. 479func (dm *decMode) NewDecoder(r io.Reader) *Decoder { 480 return &Decoder{r: r, d: decoder{dm: dm}} 481} 482 483type decoder struct { 484 data []byte 485 off int // next read offset in data 486 dm *decMode 487} 488 489func (d *decoder) value(v interface{}) error { 490 // v can't be nil, non-pointer, or nil pointer value. 491 if v == nil { 492 return &InvalidUnmarshalError{"cbor: Unmarshal(nil)"} 493 } 494 rv := reflect.ValueOf(v) 495 if rv.Kind() != reflect.Ptr { 496 return &InvalidUnmarshalError{"cbor: Unmarshal(non-pointer " + rv.Type().String() + ")"} 497 } else if rv.IsNil() { 498 return &InvalidUnmarshalError{"cbor: Unmarshal(nil " + rv.Type().String() + ")"} 499 } 500 501 off := d.off // Save offset before data validation 502 err := d.valid() 503 d.off = off // Restore offset 504 if err != nil { 505 return err 506 } 507 508 rv = rv.Elem() 509 return d.parseToValue(rv, getTypeInfo(rv.Type())) 510} 511 512type cborType uint8 513 514const ( 515 cborTypePositiveInt cborType = 0x00 516 cborTypeNegativeInt cborType = 0x20 517 cborTypeByteString cborType = 0x40 518 cborTypeTextString cborType = 0x60 519 cborTypeArray cborType = 0x80 520 cborTypeMap cborType = 0xa0 521 cborTypeTag cborType = 0xc0 522 cborTypePrimitives cborType = 0xe0 523) 524 525func (t cborType) String() string { 526 switch t { 527 case cborTypePositiveInt: 528 return "positive integer" 529 case cborTypeNegativeInt: 530 return "negative integer" 531 case cborTypeByteString: 532 return "byte string" 533 case cborTypeTextString: 534 return "UTF-8 text string" 535 case cborTypeArray: 536 return "array" 537 case cborTypeMap: 538 return "map" 539 case cborTypeTag: 540 return "tag" 541 case cborTypePrimitives: 542 return "primitives" 543 default: 544 return "Invalid type " + strconv.Itoa(int(t)) 545 } 546} 547 548const ( 549 selfDescribedCBORTagNum = 55799 550) 551 552// parseToValue decodes CBOR data to value. It assumes data is well-formed, 553// and does not perform bounds checking. 554func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo 555 556 if tInfo.spclType == specialTypeIface { 557 if !v.IsNil() { 558 // Use value type 559 v = v.Elem() 560 tInfo = getTypeInfo(v.Type()) 561 } else { 562 // Create and use registered type if CBOR data is registered tag 563 if d.dm.tags != nil && d.nextCBORType() == cborTypeTag { 564 565 off := d.off 566 var tagNums []uint64 567 for d.nextCBORType() == cborTypeTag { 568 _, _, tagNum := d.getHead() 569 tagNums = append(tagNums, tagNum) 570 } 571 d.off = off 572 573 registeredType := d.dm.tags.getTypeFromTagNum(tagNums) 574 if registeredType != nil { 575 if registeredType.Implements(tInfo.nonPtrType) || 576 reflect.PtrTo(registeredType).Implements(tInfo.nonPtrType) { 577 v.Set(reflect.New(registeredType)) 578 v = v.Elem() 579 tInfo = getTypeInfo(registeredType) 580 } 581 } 582 } 583 } 584 } 585 586 // Create new value for the pointer v to point to if CBOR value is not nil/undefined. 587 if !d.nextCBORNil() { 588 for v.Kind() == reflect.Ptr { 589 if v.IsNil() { 590 if !v.CanSet() { 591 d.skip() 592 return errors.New("cbor: cannot set new value for " + v.Type().String()) 593 } 594 v.Set(reflect.New(v.Type().Elem())) 595 } 596 v = v.Elem() 597 } 598 } 599 600 // Strip self-described CBOR tag number. 601 for d.nextCBORType() == cborTypeTag { 602 off := d.off 603 _, _, tagNum := d.getHead() 604 if tagNum != selfDescribedCBORTagNum { 605 d.off = off 606 break 607 } 608 } 609 610 // Check validity of supported built-in tags. 611 if d.nextCBORType() == cborTypeTag { 612 off := d.off 613 _, _, tagNum := d.getHead() 614 if err := validBuiltinTag(tagNum, d.data[d.off]); err != nil { 615 d.skip() 616 return err 617 } 618 d.off = off 619 } 620 621 if tInfo.spclType != specialTypeNone { 622 switch tInfo.spclType { 623 case specialTypeEmptyIface: 624 iv, err := d.parse(false) // Skipped self-described CBOR tag number already. 625 if iv != nil { 626 v.Set(reflect.ValueOf(iv)) 627 } 628 return err 629 case specialTypeTag: 630 return d.parseToTag(v) 631 case specialTypeTime: 632 if d.nextCBORNil() { 633 // Decoding CBOR null and undefined to time.Time is no-op. 634 d.skip() 635 return nil 636 } 637 tm, err := d.parseToTime() 638 if err != nil { 639 return err 640 } 641 v.Set(reflect.ValueOf(tm)) 642 return nil 643 case specialTypeUnmarshalerIface: 644 return d.parseToUnmarshaler(v) 645 } 646 } 647 648 // Check registered tag number 649 if tagItem := d.getRegisteredTagItem(tInfo.nonPtrType); tagItem != nil { 650 t := d.nextCBORType() 651 if t != cborTypeTag { 652 if tagItem.opts.DecTag == DecTagRequired { 653 d.skip() // Required tag number is absent, skip entire tag 654 return &UnmarshalTypeError{ 655 CBORType: t.String(), 656 GoType: tInfo.typ.String(), 657 errorMsg: "expect CBOR tag value"} 658 } 659 } else if err := d.validRegisteredTagNums(tagItem); err != nil { 660 d.skip() // Skip tag content 661 return err 662 } 663 } 664 665 t := d.nextCBORType() 666 667 switch t { 668 case cborTypePositiveInt: 669 _, _, val := d.getHead() 670 return fillPositiveInt(t, val, v) 671 case cborTypeNegativeInt: 672 _, _, val := d.getHead() 673 if val > math.MaxInt64 { 674 // CBOR negative integer overflows int64, use big.Int to store value. 675 bi := new(big.Int) 676 bi.SetUint64(val) 677 bi.Add(bi, big.NewInt(1)) 678 bi.Neg(bi) 679 680 if tInfo.nonPtrType == typeBigInt { 681 v.Set(reflect.ValueOf(*bi)) 682 return nil 683 } 684 return &UnmarshalTypeError{ 685 CBORType: t.String(), 686 GoType: tInfo.nonPtrType.String(), 687 errorMsg: bi.String() + " overflows Go's int64", 688 } 689 } 690 nValue := int64(-1) ^ int64(val) 691 return fillNegativeInt(t, nValue, v) 692 case cborTypeByteString: 693 b := d.parseByteString() 694 return fillByteString(t, b, v) 695 case cborTypeTextString: 696 b, err := d.parseTextString() 697 if err != nil { 698 return err 699 } 700 return fillTextString(t, b, v) 701 case cborTypePrimitives: 702 _, ai, val := d.getHead() 703 if ai < 20 || ai == 24 { 704 return fillPositiveInt(t, val, v) 705 } 706 switch ai { 707 case 20, 21: 708 return fillBool(t, ai == 21, v) 709 case 22, 23: 710 return fillNil(t, v) 711 case 25: 712 f := float64(float16.Frombits(uint16(val)).Float32()) 713 return fillFloat(t, f, v) 714 case 26: 715 f := float64(math.Float32frombits(uint32(val))) 716 return fillFloat(t, f, v) 717 case 27: 718 f := math.Float64frombits(val) 719 return fillFloat(t, f, v) 720 } 721 case cborTypeTag: 722 _, _, tagNum := d.getHead() 723 switch tagNum { 724 case 2: 725 // Bignum (tag 2) can be decoded to uint, int, float, slice, array, or big.Int. 726 b := d.parseByteString() 727 bi := new(big.Int).SetBytes(b) 728 729 if tInfo.nonPtrType == typeBigInt { 730 v.Set(reflect.ValueOf(*bi)) 731 return nil 732 } 733 if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array { 734 return fillByteString(t, b, v) 735 } 736 if bi.IsUint64() { 737 return fillPositiveInt(t, bi.Uint64(), v) 738 } 739 return &UnmarshalTypeError{ 740 CBORType: t.String(), 741 GoType: tInfo.nonPtrType.String(), 742 errorMsg: bi.String() + " overflows " + v.Type().String(), 743 } 744 case 3: 745 // Bignum (tag 3) can be decoded to int, float, slice, array, or big.Int. 746 b := d.parseByteString() 747 bi := new(big.Int).SetBytes(b) 748 bi.Add(bi, big.NewInt(1)) 749 bi.Neg(bi) 750 751 if tInfo.nonPtrType == typeBigInt { 752 v.Set(reflect.ValueOf(*bi)) 753 return nil 754 } 755 if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array { 756 return fillByteString(t, b, v) 757 } 758 if bi.IsInt64() { 759 return fillNegativeInt(t, bi.Int64(), v) 760 } 761 return &UnmarshalTypeError{ 762 CBORType: t.String(), 763 GoType: tInfo.nonPtrType.String(), 764 errorMsg: bi.String() + " overflows " + v.Type().String(), 765 } 766 } 767 return d.parseToValue(v, tInfo) 768 case cborTypeArray: 769 if tInfo.nonPtrKind == reflect.Slice { 770 return d.parseArrayToSlice(v, tInfo) 771 } else if tInfo.nonPtrKind == reflect.Array { 772 return d.parseArrayToArray(v, tInfo) 773 } else if tInfo.nonPtrKind == reflect.Struct { 774 return d.parseArrayToStruct(v, tInfo) 775 } 776 d.skip() 777 return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()} 778 case cborTypeMap: 779 if tInfo.nonPtrKind == reflect.Struct { 780 return d.parseMapToStruct(v, tInfo) 781 } else if tInfo.nonPtrKind == reflect.Map { 782 return d.parseMapToMap(v, tInfo) 783 } 784 d.skip() 785 return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()} 786 } 787 return nil 788} 789 790func (d *decoder) parseToTag(v reflect.Value) error { 791 if d.nextCBORNil() { 792 // Decoding CBOR null and undefined to cbor.Tag is no-op. 793 d.skip() 794 return nil 795 } 796 797 t := d.nextCBORType() 798 if t != cborTypeTag { 799 d.skip() 800 return &UnmarshalTypeError{CBORType: t.String(), GoType: typeTag.String()} 801 } 802 803 // Unmarshal tag number 804 _, _, num := d.getHead() 805 806 // Unmarshal tag content 807 content, err := d.parse(false) 808 if err != nil { 809 return err 810 } 811 812 v.Set(reflect.ValueOf(Tag{num, content})) 813 return nil 814} 815 816func (d *decoder) parseToTime() (tm time.Time, err error) { 817 t := d.nextCBORType() 818 819 // Verify that tag number or absence of tag number is acceptable to specified timeTag. 820 if t == cborTypeTag { 821 if d.dm.timeTag == DecTagIgnored { 822 // Skip tag number 823 for t == cborTypeTag { 824 d.getHead() 825 t = d.nextCBORType() 826 } 827 } else { 828 // Read tag number 829 _, _, tagNum := d.getHead() 830 if tagNum != 0 && tagNum != 1 { 831 d.skip() 832 err = errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") 833 return 834 } 835 } 836 } else { 837 if d.dm.timeTag == DecTagRequired { 838 d.skip() 839 err = &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String(), errorMsg: "expect CBOR tag value"} 840 return 841 } 842 } 843 844 var content interface{} 845 content, err = d.parse(false) 846 if err != nil { 847 return 848 } 849 850 switch c := content.(type) { 851 case nil: 852 return 853 case uint64: 854 return time.Unix(int64(c), 0), nil 855 case int64: 856 return time.Unix(c, 0), nil 857 case float64: 858 if math.IsNaN(c) || math.IsInf(c, 0) { 859 return 860 } 861 f1, f2 := math.Modf(c) 862 return time.Unix(int64(f1), int64(f2*1e9)), nil 863 case string: 864 tm, err = time.Parse(time.RFC3339, c) 865 if err != nil { 866 tm = time.Time{} 867 err = errors.New("cbor: cannot set " + c + " for time.Time: " + err.Error()) 868 return 869 } 870 return 871 default: 872 err = &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()} 873 return 874 } 875} 876 877// parseToUnmarshaler parses CBOR data to value implementing Unmarshaler interface. 878// It assumes data is well-formed, and does not perform bounds checking. 879func (d *decoder) parseToUnmarshaler(v reflect.Value) error { 880 if d.nextCBORNil() && v.Kind() == reflect.Ptr && v.IsNil() { 881 d.skip() 882 return nil 883 } 884 885 if v.Kind() != reflect.Ptr && v.CanAddr() { 886 v = v.Addr() 887 } 888 if u, ok := v.Interface().(Unmarshaler); ok { 889 start := d.off 890 d.skip() 891 return u.UnmarshalCBOR(d.data[start:d.off]) 892 } 893 d.skip() 894 return errors.New("cbor: failed to assert " + v.Type().String() + " as cbor.Unmarshaler") 895} 896 897// parse parses CBOR data and returns value in default Go type. 898// It assumes data is well-formed, and does not perform bounds checking. 899func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //nolint:gocyclo 900 // Strip self-described CBOR tag number. 901 if skipSelfDescribedTag { 902 for d.nextCBORType() == cborTypeTag { 903 off := d.off 904 _, _, tagNum := d.getHead() 905 if tagNum != selfDescribedCBORTagNum { 906 d.off = off 907 break 908 } 909 } 910 } 911 912 // Check validity of supported built-in tags. 913 if d.nextCBORType() == cborTypeTag { 914 off := d.off 915 _, _, tagNum := d.getHead() 916 if err := validBuiltinTag(tagNum, d.data[d.off]); err != nil { 917 d.skip() 918 return nil, err 919 } 920 d.off = off 921 } 922 923 t := d.nextCBORType() 924 switch t { 925 case cborTypePositiveInt: 926 _, _, val := d.getHead() 927 if d.dm.intDec == IntDecConvertNone { 928 return val, nil 929 } 930 if val > math.MaxInt64 { 931 return nil, &UnmarshalTypeError{ 932 CBORType: t.String(), 933 GoType: reflect.TypeOf(int64(0)).String(), 934 errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64", 935 } 936 } 937 return int64(val), nil 938 case cborTypeNegativeInt: 939 _, _, val := d.getHead() 940 if val > math.MaxInt64 { 941 // CBOR negative integer value overflows Go int64, use big.Int instead. 942 bi := new(big.Int).SetUint64(val) 943 bi.Add(bi, big.NewInt(1)) 944 bi.Neg(bi) 945 return *bi, nil 946 } 947 nValue := int64(-1) ^ int64(val) 948 return nValue, nil 949 case cborTypeByteString: 950 return d.parseByteString(), nil 951 case cborTypeTextString: 952 b, err := d.parseTextString() 953 if err != nil { 954 return nil, err 955 } 956 return string(b), nil 957 case cborTypeTag: 958 tagOff := d.off 959 _, _, tagNum := d.getHead() 960 contentOff := d.off 961 962 switch tagNum { 963 case 0, 1: 964 d.off = tagOff 965 return d.parseToTime() 966 case 2: 967 b := d.parseByteString() 968 bi := new(big.Int).SetBytes(b) 969 return *bi, nil 970 case 3: 971 b := d.parseByteString() 972 bi := new(big.Int).SetBytes(b) 973 bi.Add(bi, big.NewInt(1)) 974 bi.Neg(bi) 975 return *bi, nil 976 } 977 978 if d.dm.tags != nil { 979 // Parse to specified type if tag number is registered. 980 tagNums := []uint64{tagNum} 981 for d.nextCBORType() == cborTypeTag { 982 _, _, num := d.getHead() 983 tagNums = append(tagNums, num) 984 } 985 registeredType := d.dm.tags.getTypeFromTagNum(tagNums) 986 if registeredType != nil { 987 d.off = tagOff 988 rv := reflect.New(registeredType) 989 if err := d.parseToValue(rv.Elem(), getTypeInfo(registeredType)); err != nil { 990 return nil, err 991 } 992 return rv.Elem().Interface(), nil 993 } 994 } 995 996 // Parse tag content 997 d.off = contentOff 998 content, err := d.parse(false) 999 if err != nil { 1000 return nil, err 1001 } 1002 return Tag{tagNum, content}, nil 1003 case cborTypePrimitives: 1004 _, ai, val := d.getHead() 1005 if ai < 20 || ai == 24 { 1006 return val, nil 1007 } 1008 switch ai { 1009 case 20, 21: 1010 return (ai == 21), nil 1011 case 22, 23: 1012 return nil, nil 1013 case 25: 1014 f := float64(float16.Frombits(uint16(val)).Float32()) 1015 return f, nil 1016 case 26: 1017 f := float64(math.Float32frombits(uint32(val))) 1018 return f, nil 1019 case 27: 1020 f := math.Float64frombits(val) 1021 return f, nil 1022 } 1023 case cborTypeArray: 1024 return d.parseArray() 1025 case cborTypeMap: 1026 if d.dm.defaultMapType != nil { 1027 m := reflect.New(d.dm.defaultMapType) 1028 err := d.parseToValue(m, getTypeInfo(m.Elem().Type())) 1029 if err != nil { 1030 return nil, err 1031 } 1032 return m.Elem().Interface(), nil 1033 } 1034 return d.parseMap() 1035 } 1036 return nil, nil 1037} 1038 1039// parseByteString parses CBOR encoded byte string. It returns a byte slice 1040// pointing to a copy of parsed data. 1041func (d *decoder) parseByteString() []byte { 1042 _, ai, val := d.getHead() 1043 if ai != 31 { 1044 b := make([]byte, int(val)) 1045 copy(b, d.data[d.off:d.off+int(val)]) 1046 d.off += int(val) 1047 return b 1048 } 1049 // Process indefinite length string chunks. 1050 b := []byte{} 1051 for !d.foundBreak() { 1052 _, _, val = d.getHead() 1053 b = append(b, d.data[d.off:d.off+int(val)]...) 1054 d.off += int(val) 1055 } 1056 return b 1057} 1058 1059// parseTextString parses CBOR encoded text string. It returns a byte slice 1060// to prevent creating an extra copy of string. Caller should wrap returned 1061// byte slice as string when needed. 1062func (d *decoder) parseTextString() ([]byte, error) { 1063 _, ai, val := d.getHead() 1064 if ai != 31 { 1065 b := d.data[d.off : d.off+int(val)] 1066 d.off += int(val) 1067 if !utf8.Valid(b) { 1068 return nil, &SemanticError{"cbor: invalid UTF-8 string"} 1069 } 1070 return b, nil 1071 } 1072 // Process indefinite length string chunks. 1073 b := []byte{} 1074 for !d.foundBreak() { 1075 _, _, val = d.getHead() 1076 x := d.data[d.off : d.off+int(val)] 1077 d.off += int(val) 1078 if !utf8.Valid(x) { 1079 for !d.foundBreak() { 1080 d.skip() // Skip remaining chunk on error 1081 } 1082 return nil, &SemanticError{"cbor: invalid UTF-8 string"} 1083 } 1084 b = append(b, x...) 1085 } 1086 return b, nil 1087} 1088 1089func (d *decoder) parseArray() ([]interface{}, error) { 1090 _, ai, val := d.getHead() 1091 hasSize := (ai != 31) 1092 count := int(val) 1093 if !hasSize { 1094 count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance 1095 } 1096 v := make([]interface{}, count) 1097 var e interface{} 1098 var err, lastErr error 1099 for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1100 if e, lastErr = d.parse(true); lastErr != nil { 1101 if err == nil { 1102 err = lastErr 1103 } 1104 continue 1105 } 1106 v[i] = e 1107 } 1108 return v, err 1109} 1110 1111func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { 1112 _, ai, val := d.getHead() 1113 hasSize := (ai != 31) 1114 count := int(val) 1115 if !hasSize { 1116 count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance 1117 } 1118 if v.IsNil() || v.Cap() < count || count == 0 { 1119 v.Set(reflect.MakeSlice(tInfo.nonPtrType, count, count)) 1120 } 1121 v.SetLen(count) 1122 var err error 1123 for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1124 if lastErr := d.parseToValue(v.Index(i), tInfo.elemTypeInfo); lastErr != nil { 1125 if err == nil { 1126 err = lastErr 1127 } 1128 } 1129 } 1130 return err 1131} 1132 1133func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { 1134 _, ai, val := d.getHead() 1135 hasSize := (ai != 31) 1136 count := int(val) 1137 gi := 0 1138 vLen := v.Len() 1139 var err error 1140 for ci := 0; (hasSize && ci < count) || (!hasSize && !d.foundBreak()); ci++ { 1141 if gi < vLen { 1142 // Read CBOR array element and set array element 1143 if lastErr := d.parseToValue(v.Index(gi), tInfo.elemTypeInfo); lastErr != nil { 1144 if err == nil { 1145 err = lastErr 1146 } 1147 } 1148 gi++ 1149 } else { 1150 d.skip() // Skip remaining CBOR array element 1151 } 1152 } 1153 // Set remaining Go array elements to zero values. 1154 if gi < vLen { 1155 zeroV := reflect.Zero(tInfo.elemTypeInfo.typ) 1156 for ; gi < vLen; gi++ { 1157 v.Index(gi).Set(zeroV) 1158 } 1159 } 1160 return err 1161} 1162 1163func (d *decoder) parseMap() (interface{}, error) { 1164 _, ai, val := d.getHead() 1165 hasSize := (ai != 31) 1166 count := int(val) 1167 m := make(map[interface{}]interface{}) 1168 var k, e interface{} 1169 var err, lastErr error 1170 keyCount := 0 1171 for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1172 // Parse CBOR map key. 1173 if k, lastErr = d.parse(true); lastErr != nil { 1174 if err == nil { 1175 err = lastErr 1176 } 1177 d.skip() 1178 continue 1179 } 1180 1181 // Detect if CBOR map key can be used as Go map key. 1182 rv := reflect.ValueOf(k) 1183 if !isHashableValue(rv) { 1184 if err == nil { 1185 err = errors.New("cbor: invalid map key type: " + rv.Type().String()) 1186 } 1187 d.skip() 1188 continue 1189 } 1190 1191 // Parse CBOR map value. 1192 if e, lastErr = d.parse(true); lastErr != nil { 1193 if err == nil { 1194 err = lastErr 1195 } 1196 continue 1197 } 1198 1199 // Add key-value pair to Go map. 1200 m[k] = e 1201 1202 // Detect duplicate map key. 1203 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1204 newKeyCount := len(m) 1205 if newKeyCount == keyCount { 1206 m[k] = nil 1207 err = &DupMapKeyError{k, i} 1208 i++ 1209 // skip the rest of the map 1210 for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1211 d.skip() // Skip map key 1212 d.skip() // Skip map value 1213 } 1214 return m, err 1215 } 1216 keyCount = newKeyCount 1217 } 1218 } 1219 return m, err 1220} 1221 1222func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo 1223 _, ai, val := d.getHead() 1224 hasSize := (ai != 31) 1225 count := int(val) 1226 if v.IsNil() { 1227 mapsize := count 1228 if !hasSize { 1229 mapsize = 0 1230 } 1231 v.Set(reflect.MakeMapWithSize(tInfo.nonPtrType, mapsize)) 1232 } 1233 keyType, eleType := tInfo.keyTypeInfo.typ, tInfo.elemTypeInfo.typ 1234 reuseKey, reuseEle := isImmutableKind(tInfo.keyTypeInfo.kind), isImmutableKind(tInfo.elemTypeInfo.kind) 1235 var keyValue, eleValue, zeroKeyValue, zeroEleValue reflect.Value 1236 keyIsInterfaceType := keyType == typeIntf // If key type is interface{}, need to check if key value is hashable. 1237 var err, lastErr error 1238 keyCount := v.Len() 1239 var existingKeys map[interface{}]bool // Store existing map keys, used for detecting duplicate map key. 1240 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1241 existingKeys = make(map[interface{}]bool, keyCount) 1242 if keyCount > 0 { 1243 vKeys := v.MapKeys() 1244 for i := 0; i < len(vKeys); i++ { 1245 existingKeys[vKeys[i].Interface()] = true 1246 } 1247 } 1248 } 1249 for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1250 // Parse CBOR map key. 1251 if !keyValue.IsValid() { 1252 keyValue = reflect.New(keyType).Elem() 1253 } else if !reuseKey { 1254 if !zeroKeyValue.IsValid() { 1255 zeroKeyValue = reflect.Zero(keyType) 1256 } 1257 keyValue.Set(zeroKeyValue) 1258 } 1259 if lastErr = d.parseToValue(keyValue, tInfo.keyTypeInfo); lastErr != nil { 1260 if err == nil { 1261 err = lastErr 1262 } 1263 d.skip() 1264 continue 1265 } 1266 1267 // Detect if CBOR map key can be used as Go map key. 1268 if keyIsInterfaceType && keyValue.Elem().IsValid() { 1269 if !isHashableValue(keyValue.Elem()) { 1270 if err == nil { 1271 err = errors.New("cbor: invalid map key type: " + keyValue.Elem().Type().String()) 1272 } 1273 d.skip() 1274 continue 1275 } 1276 } 1277 1278 // Parse CBOR map value. 1279 if !eleValue.IsValid() { 1280 eleValue = reflect.New(eleType).Elem() 1281 } else if !reuseEle { 1282 if !zeroEleValue.IsValid() { 1283 zeroEleValue = reflect.Zero(eleType) 1284 } 1285 eleValue.Set(zeroEleValue) 1286 } 1287 if lastErr := d.parseToValue(eleValue, tInfo.elemTypeInfo); lastErr != nil { 1288 if err == nil { 1289 err = lastErr 1290 } 1291 continue 1292 } 1293 1294 // Add key-value pair to Go map. 1295 v.SetMapIndex(keyValue, eleValue) 1296 1297 // Detect duplicate map key. 1298 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1299 newKeyCount := v.Len() 1300 if newKeyCount == keyCount { 1301 kvi := keyValue.Interface() 1302 if !existingKeys[kvi] { 1303 v.SetMapIndex(keyValue, reflect.New(eleType).Elem()) 1304 err = &DupMapKeyError{kvi, i} 1305 i++ 1306 // skip the rest of the map 1307 for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1308 d.skip() // skip map key 1309 d.skip() // skip map value 1310 } 1311 return err 1312 } 1313 delete(existingKeys, kvi) 1314 } 1315 keyCount = newKeyCount 1316 } 1317 } 1318 return err 1319} 1320 1321func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { 1322 structType := getDecodingStructType(tInfo.nonPtrType) 1323 if structType.err != nil { 1324 return structType.err 1325 } 1326 1327 if !structType.toArray { 1328 t := d.nextCBORType() 1329 d.skip() 1330 return &UnmarshalTypeError{ 1331 CBORType: t.String(), 1332 GoType: tInfo.nonPtrType.String(), 1333 errorMsg: "cannot decode CBOR array to struct without toarray option", 1334 } 1335 } 1336 1337 start := d.off 1338 t, ai, val := d.getHead() 1339 hasSize := (ai != 31) 1340 count := int(val) 1341 if !hasSize { 1342 count = d.numOfItemsUntilBreak() // peek ahead to get array size 1343 } 1344 if count != len(structType.fields) { 1345 d.off = start 1346 d.skip() 1347 return &UnmarshalTypeError{ 1348 CBORType: t.String(), 1349 GoType: tInfo.typ.String(), 1350 errorMsg: "cannot decode CBOR array to struct with different number of elements", 1351 } 1352 } 1353 var err, lastErr error 1354 for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { 1355 f := structType.fields[i] 1356 1357 // Get field value by index 1358 var fv reflect.Value 1359 if len(f.idx) == 1 { 1360 fv = v.Field(f.idx[0]) 1361 } else { 1362 fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { 1363 // Return a new value for embedded field null pointer to point to, or return error. 1364 if !v.CanSet() { 1365 return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) 1366 } 1367 v.Set(reflect.New(v.Type().Elem())) 1368 return v, nil 1369 }) 1370 if lastErr != nil && err == nil { 1371 err = lastErr 1372 } 1373 if !fv.IsValid() { 1374 d.skip() 1375 continue 1376 } 1377 } 1378 1379 if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil { 1380 if err == nil { 1381 if typeError, ok := lastErr.(*UnmarshalTypeError); ok { 1382 typeError.StructFieldName = tInfo.typ.String() + "." + f.name 1383 err = typeError 1384 } else { 1385 err = lastErr 1386 } 1387 } 1388 } 1389 } 1390 return err 1391} 1392 1393// parseMapToStruct needs to be fast so gocyclo can be ignored for now. 1394func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo 1395 structType := getDecodingStructType(tInfo.nonPtrType) 1396 if structType.err != nil { 1397 return structType.err 1398 } 1399 1400 if structType.toArray { 1401 t := d.nextCBORType() 1402 d.skip() 1403 return &UnmarshalTypeError{ 1404 CBORType: t.String(), 1405 GoType: tInfo.nonPtrType.String(), 1406 errorMsg: "cannot decode CBOR map to struct with toarray option", 1407 } 1408 } 1409 1410 var err, lastErr error 1411 1412 // Get CBOR map size 1413 _, ai, val := d.getHead() 1414 hasSize := (ai != 31) 1415 count := int(val) 1416 1417 // Keeps track of matched struct fields 1418 foundFldIdx := make([]bool, len(structType.fields)) 1419 1420 // Keeps track of CBOR map keys to detect duplicate map key 1421 keyCount := 0 1422 var mapKeys map[interface{}]struct{} 1423 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1424 mapKeys = make(map[interface{}]struct{}, len(structType.fields)) 1425 } 1426 1427 errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 1428 1429 for j := 0; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { 1430 var f *field 1431 var k interface{} // Used by duplicate map key detection 1432 1433 t := d.nextCBORType() 1434 if t == cborTypeTextString { 1435 var keyBytes []byte 1436 keyBytes, lastErr = d.parseTextString() 1437 if lastErr != nil { 1438 if err == nil { 1439 err = lastErr 1440 } 1441 d.skip() // skip value 1442 continue 1443 } 1444 1445 keyLen := len(keyBytes) 1446 // Find field with exact match 1447 for i := 0; i < len(structType.fields); i++ { 1448 fld := structType.fields[i] 1449 if !foundFldIdx[i] && len(fld.name) == keyLen && fld.name == string(keyBytes) { 1450 f = fld 1451 foundFldIdx[i] = true 1452 break 1453 } 1454 } 1455 // Find field with case-insensitive match 1456 if f == nil { 1457 keyString := string(keyBytes) 1458 for i := 0; i < len(structType.fields); i++ { 1459 fld := structType.fields[i] 1460 if !foundFldIdx[i] && len(fld.name) == keyLen && strings.EqualFold(fld.name, keyString) { 1461 f = fld 1462 foundFldIdx[i] = true 1463 break 1464 } 1465 } 1466 } 1467 1468 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1469 k = string(keyBytes) 1470 } 1471 } else if t <= cborTypeNegativeInt { // uint/int 1472 var nameAsInt int64 1473 1474 if t == cborTypePositiveInt { 1475 _, _, val := d.getHead() 1476 nameAsInt = int64(val) 1477 } else { 1478 _, _, val := d.getHead() 1479 if val > math.MaxInt64 { 1480 if err == nil { 1481 err = &UnmarshalTypeError{ 1482 CBORType: t.String(), 1483 GoType: reflect.TypeOf(int64(0)).String(), 1484 errorMsg: "-1-" + strconv.FormatUint(val, 10) + " overflows Go's int64", 1485 } 1486 } 1487 d.skip() // skip value 1488 continue 1489 } 1490 nameAsInt = int64(-1) ^ int64(val) 1491 } 1492 1493 // Find field 1494 for i := 0; i < len(structType.fields); i++ { 1495 fld := structType.fields[i] 1496 if !foundFldIdx[i] && fld.keyAsInt && fld.nameAsInt == nameAsInt { 1497 f = fld 1498 foundFldIdx[i] = true 1499 break 1500 } 1501 } 1502 1503 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1504 k = nameAsInt 1505 } 1506 } else { 1507 if err == nil { 1508 err = &UnmarshalTypeError{ 1509 CBORType: t.String(), 1510 GoType: reflect.TypeOf("").String(), 1511 errorMsg: "map key is of type " + t.String() + " and cannot be used to match struct field name", 1512 } 1513 } 1514 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1515 // parse key 1516 k, lastErr = d.parse(true) 1517 if lastErr != nil { 1518 d.skip() // skip value 1519 continue 1520 } 1521 // Detect if CBOR map key can be used as Go map key. 1522 if !isHashableValue(reflect.ValueOf(k)) { 1523 d.skip() // skip value 1524 continue 1525 } 1526 } else { 1527 d.skip() // skip key 1528 } 1529 } 1530 1531 if d.dm.dupMapKey == DupMapKeyEnforcedAPF { 1532 mapKeys[k] = struct{}{} 1533 newKeyCount := len(mapKeys) 1534 if newKeyCount == keyCount { 1535 err = &DupMapKeyError{k, j} 1536 d.skip() // skip value 1537 j++ 1538 // skip the rest of the map 1539 for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { 1540 d.skip() 1541 d.skip() 1542 } 1543 return err 1544 } 1545 keyCount = newKeyCount 1546 } 1547 1548 if f == nil { 1549 if errOnUnknownField { 1550 err = &UnknownFieldError{j} 1551 d.skip() // Skip value 1552 j++ 1553 // skip the rest of the map 1554 for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { 1555 d.skip() 1556 d.skip() 1557 } 1558 return err 1559 } 1560 d.skip() // Skip value 1561 continue 1562 } 1563 1564 // Get field value by index 1565 var fv reflect.Value 1566 if len(f.idx) == 1 { 1567 fv = v.Field(f.idx[0]) 1568 } else { 1569 fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { 1570 // Return a new value for embedded field null pointer to point to, or return error. 1571 if !v.CanSet() { 1572 return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) 1573 } 1574 v.Set(reflect.New(v.Type().Elem())) 1575 return v, nil 1576 }) 1577 if lastErr != nil && err == nil { 1578 err = lastErr 1579 } 1580 if !fv.IsValid() { 1581 d.skip() 1582 continue 1583 } 1584 } 1585 1586 if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil { 1587 if err == nil { 1588 if typeError, ok := lastErr.(*UnmarshalTypeError); ok { 1589 typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name 1590 err = typeError 1591 } else { 1592 err = lastErr 1593 } 1594 } 1595 } 1596 } 1597 return err 1598} 1599 1600// validRegisteredTagNums verifies that tag numbers match registered tag numbers of type t. 1601// validRegisteredTagNums assumes next CBOR data type is tag. It scans all tag numbers, and stops at tag content. 1602func (d *decoder) validRegisteredTagNums(registeredTag *tagItem) error { 1603 // Scan until next cbor data is tag content. 1604 tagNums := make([]uint64, 0, 1) 1605 for d.nextCBORType() == cborTypeTag { 1606 _, _, val := d.getHead() 1607 tagNums = append(tagNums, val) 1608 } 1609 1610 if !registeredTag.equalTagNum(tagNums) { 1611 return &WrongTagError{registeredTag.contentType, registeredTag.num, tagNums} 1612 } 1613 return nil 1614} 1615 1616func (d *decoder) getRegisteredTagItem(vt reflect.Type) *tagItem { 1617 if d.dm.tags != nil { 1618 return d.dm.tags.getTagItemFromType(vt) 1619 } 1620 return nil 1621} 1622 1623// skip moves data offset to the next item. skip assumes data is well-formed, 1624// and does not perform bounds checking. 1625func (d *decoder) skip() { 1626 t, ai, val := d.getHead() 1627 1628 if ai == 31 { 1629 switch t { 1630 case cborTypeByteString, cborTypeTextString, cborTypeArray, cborTypeMap: 1631 for { 1632 if d.data[d.off] == 0xff { 1633 d.off++ 1634 return 1635 } 1636 d.skip() 1637 } 1638 } 1639 } 1640 1641 switch t { 1642 case cborTypeByteString, cborTypeTextString: 1643 d.off += int(val) 1644 case cborTypeArray: 1645 for i := 0; i < int(val); i++ { 1646 d.skip() 1647 } 1648 case cborTypeMap: 1649 for i := 0; i < int(val)*2; i++ { 1650 d.skip() 1651 } 1652 case cborTypeTag: 1653 d.skip() 1654 } 1655} 1656 1657// getHead assumes data is well-formed, and does not perform bounds checking. 1658func (d *decoder) getHead() (t cborType, ai byte, val uint64) { 1659 t = cborType(d.data[d.off] & 0xe0) 1660 ai = d.data[d.off] & 0x1f 1661 val = uint64(ai) 1662 d.off++ 1663 1664 if ai < 24 { 1665 return 1666 } 1667 if ai == 24 { 1668 val = uint64(d.data[d.off]) 1669 d.off++ 1670 return 1671 } 1672 if ai == 25 { 1673 val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+2])) 1674 d.off += 2 1675 return 1676 } 1677 if ai == 26 { 1678 val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+4])) 1679 d.off += 4 1680 return 1681 } 1682 if ai == 27 { 1683 val = binary.BigEndian.Uint64(d.data[d.off : d.off+8]) 1684 d.off += 8 1685 return 1686 } 1687 return 1688} 1689 1690func (d *decoder) numOfItemsUntilBreak() int { 1691 savedOff := d.off 1692 i := 0 1693 for !d.foundBreak() { 1694 d.skip() 1695 i++ 1696 } 1697 d.off = savedOff 1698 return i 1699} 1700 1701// foundBreak assumes data is well-formed, and does not perform bounds checking. 1702func (d *decoder) foundBreak() bool { 1703 if d.data[d.off] == 0xff { 1704 d.off++ 1705 return true 1706 } 1707 return false 1708} 1709 1710func (d *decoder) reset(data []byte) { 1711 d.data = data 1712 d.off = 0 1713} 1714 1715func (d *decoder) nextCBORType() cborType { 1716 return cborType(d.data[d.off] & 0xe0) 1717} 1718 1719func (d *decoder) nextCBORNil() bool { 1720 return d.data[d.off] == 0xf6 || d.data[d.off] == 0xf7 1721} 1722 1723var ( 1724 typeIntf = reflect.TypeOf([]interface{}(nil)).Elem() 1725 typeTime = reflect.TypeOf(time.Time{}) 1726 typeBigInt = reflect.TypeOf(big.Int{}) 1727 typeUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem() 1728 typeBinaryUnmarshaler = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem() 1729) 1730 1731func fillNil(t cborType, v reflect.Value) error { 1732 switch v.Kind() { 1733 case reflect.Slice, reflect.Map, reflect.Interface, reflect.Ptr: 1734 v.Set(reflect.Zero(v.Type())) 1735 return nil 1736 } 1737 return nil 1738} 1739 1740func fillPositiveInt(t cborType, val uint64, v reflect.Value) error { 1741 switch v.Kind() { 1742 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1743 if val > math.MaxInt64 { 1744 return &UnmarshalTypeError{ 1745 CBORType: t.String(), 1746 GoType: v.Type().String(), 1747 errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(), 1748 } 1749 } 1750 if v.OverflowInt(int64(val)) { 1751 return &UnmarshalTypeError{ 1752 CBORType: t.String(), 1753 GoType: v.Type().String(), 1754 errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(), 1755 } 1756 } 1757 v.SetInt(int64(val)) 1758 return nil 1759 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 1760 if v.OverflowUint(val) { 1761 return &UnmarshalTypeError{ 1762 CBORType: t.String(), 1763 GoType: v.Type().String(), 1764 errorMsg: strconv.FormatUint(val, 10) + " overflows " + v.Type().String(), 1765 } 1766 } 1767 v.SetUint(val) 1768 return nil 1769 case reflect.Float32, reflect.Float64: 1770 f := float64(val) 1771 v.SetFloat(f) 1772 return nil 1773 } 1774 if v.Type() == typeBigInt { 1775 i := new(big.Int).SetUint64(val) 1776 v.Set(reflect.ValueOf(*i)) 1777 return nil 1778 } 1779 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1780} 1781 1782func fillNegativeInt(t cborType, val int64, v reflect.Value) error { 1783 switch v.Kind() { 1784 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1785 if v.OverflowInt(val) { 1786 return &UnmarshalTypeError{ 1787 CBORType: t.String(), 1788 GoType: v.Type().String(), 1789 errorMsg: strconv.FormatInt(val, 10) + " overflows " + v.Type().String(), 1790 } 1791 } 1792 v.SetInt(val) 1793 return nil 1794 case reflect.Float32, reflect.Float64: 1795 f := float64(val) 1796 v.SetFloat(f) 1797 return nil 1798 } 1799 if v.Type() == typeBigInt { 1800 i := new(big.Int).SetInt64(val) 1801 v.Set(reflect.ValueOf(*i)) 1802 return nil 1803 } 1804 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1805} 1806 1807func fillBool(t cborType, val bool, v reflect.Value) error { 1808 if v.Kind() == reflect.Bool { 1809 v.SetBool(val) 1810 return nil 1811 } 1812 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1813} 1814 1815func fillFloat(t cborType, val float64, v reflect.Value) error { 1816 switch v.Kind() { 1817 case reflect.Float32, reflect.Float64: 1818 if v.OverflowFloat(val) { 1819 return &UnmarshalTypeError{ 1820 CBORType: t.String(), 1821 GoType: v.Type().String(), 1822 errorMsg: strconv.FormatFloat(val, 'E', -1, 64) + " overflows " + v.Type().String(), 1823 } 1824 } 1825 v.SetFloat(val) 1826 return nil 1827 } 1828 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1829} 1830 1831func fillByteString(t cborType, val []byte, v reflect.Value) error { 1832 if reflect.PtrTo(v.Type()).Implements(typeBinaryUnmarshaler) { 1833 if v.CanAddr() { 1834 v = v.Addr() 1835 if u, ok := v.Interface().(encoding.BinaryUnmarshaler); ok { 1836 return u.UnmarshalBinary(val) 1837 } 1838 } 1839 return errors.New("cbor: cannot set new value for " + v.Type().String()) 1840 } 1841 if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { 1842 v.SetBytes(val) 1843 return nil 1844 } 1845 if v.Kind() == reflect.Array && v.Type().Elem().Kind() == reflect.Uint8 { 1846 vLen := v.Len() 1847 i := 0 1848 for ; i < vLen && i < len(val); i++ { 1849 v.Index(i).SetUint(uint64(val[i])) 1850 } 1851 // Set remaining Go array elements to zero values. 1852 if i < vLen { 1853 zeroV := reflect.Zero(reflect.TypeOf(byte(0))) 1854 for ; i < vLen; i++ { 1855 v.Index(i).Set(zeroV) 1856 } 1857 } 1858 return nil 1859 } 1860 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1861} 1862 1863func fillTextString(t cborType, val []byte, v reflect.Value) error { 1864 if v.Kind() == reflect.String { 1865 v.SetString(string(val)) 1866 return nil 1867 } 1868 return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()} 1869} 1870 1871func isImmutableKind(k reflect.Kind) bool { 1872 switch k { 1873 case reflect.Bool, 1874 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 1875 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 1876 reflect.Float32, reflect.Float64, 1877 reflect.String: 1878 return true 1879 default: 1880 return false 1881 } 1882} 1883 1884func isHashableValue(rv reflect.Value) bool { 1885 switch rv.Kind() { 1886 case reflect.Slice, reflect.Map, reflect.Func: 1887 return false 1888 case reflect.Struct: 1889 switch rv.Type() { 1890 case typeTag: 1891 tag := rv.Interface().(Tag) 1892 return isHashableValue(reflect.ValueOf(tag.Content)) 1893 case typeBigInt: 1894 return false 1895 } 1896 } 1897 return true 1898} 1899 1900// validBuiltinTag checks that supported built-in tag numbers are followed by expected content types. 1901func validBuiltinTag(tagNum uint64, contentHead byte) error { 1902 t := cborType(contentHead & 0xe0) 1903 switch tagNum { 1904 case 0: 1905 // Tag content (date/time text string in RFC 3339 format) must be string type. 1906 if t != cborTypeTextString { 1907 return errors.New("cbor: tag number 0 must be followed by text string, got " + t.String()) 1908 } 1909 return nil 1910 case 1: 1911 // Tag content (epoch date/time) must be uint, int, or float type. 1912 if t != cborTypePositiveInt && t != cborTypeNegativeInt && (contentHead < 0xf9 || contentHead > 0xfb) { 1913 return errors.New("cbor: tag number 1 must be followed by integer or floating-point number, got " + t.String()) 1914 } 1915 return nil 1916 case 2, 3: 1917 // Tag content (bignum) must be byte type. 1918 if t != cborTypeByteString { 1919 return errors.New("cbor: tag number 2 or 3 must be followed by byte string, got " + t.String()) 1920 } 1921 return nil 1922 } 1923 return nil 1924} 1925