github.com/stellar/go-xdr@v0.0.0-20231122183749-b53fb00bcac2/xdr3/decode.go (about) 1 /* 2 * Copyright (c) 2012-2014 Dave Collins <dave@davec.name> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 package xdr 18 19 import ( 20 "fmt" 21 "io" 22 "math" 23 "reflect" 24 "strconv" 25 "time" 26 ) 27 28 const maxInt32 = math.MaxInt32 29 30 var errMaxSlice = "data exceeds max slice limit" 31 var errIODecode = "%s while decoding %d bytes" 32 33 // DecodeDefaultMaxDepth is the default maximum decoding depth 34 const DecodeDefaultMaxDepth = 200 35 36 // DecodeOptions configures how Decoding is done. 37 type DecodeOptions struct { 38 // MaxDepth is the maximum decoding depth (i.e. maximum nesting of data structures). 39 // It prevents infinite recursions in cyclic datastructures and determines the maximum callstack growth. 40 // If set to 0, DecodeDefaultMaxDepth will be used. 41 MaxDepth uint 42 43 // MaxInputLen sets the maximum input size. It is used by the decoder to sanity-check 44 // allocation sizes and avoid heap explosions from doctored inputs. 45 // 46 // If set to 0, the decoder will try to figure out the input size by checking whether 47 // the provided io.Reader implements Len() (e.g. strings.Reader, bytes.Reader and bytes.Buffer do). 48 // Otherwise, no sanity checks will be done. 49 MaxInputLen int 50 } 51 52 // DefaultDecodeOptions are the default decoding options. 53 var DefaultDecodeOptions = DecodeOptions{ 54 MaxDepth: DecodeDefaultMaxDepth, 55 MaxInputLen: 0, 56 } 57 58 /* 59 Unmarshal parses XDR-encoded data into the value pointed to by v reading from 60 reader r and returning the total number of bytes read. An addressable pointer 61 must be provided since Unmarshal needs to both store the result of the decode as 62 well as obtain target type information. Unmarhsal traverses v recursively and 63 automatically indirects pointers through arbitrary depth, allocating them as 64 necessary, to decode the data into the underlying value pointed to. 65 66 Unmarshal uses reflection to determine the type of the concrete value contained 67 by v and performs a mapping of underlying XDR types to Go types as follows: 68 69 Go Type <- XDR Type 70 -------------------- 71 int8, int16, int32, int <- XDR Integer 72 uint8, uint16, uint32, uint <- XDR Unsigned Integer 73 int64 <- XDR Hyper Integer 74 uint64 <- XDR Unsigned Hyper Integer 75 bool <- XDR Boolean 76 float32 <- XDR Floating-Point 77 float64 <- XDR Double-Precision Floating-Point 78 string <- XDR String 79 byte <- XDR Integer 80 []byte <- XDR Variable-Length Opaque Data 81 [#]byte <- XDR Fixed-Length Opaque Data 82 []<type> <- XDR Variable-Length Array 83 [#]<type> <- XDR Fixed-Length Array 84 struct <- XDR Structure 85 map <- XDR Variable-Length Array of two-element XDR Structures 86 time.Time <- XDR String encoded with RFC3339 nanosecond precision 87 88 Notes and Limitations: 89 90 - Automatic unmarshalling of variable and fixed-length arrays of uint8s 91 requires a special struct tag xdropaque:"false" since byte slices 92 and byte arrays are assumed to be opaque data and byte is a Go alias 93 for uint8 thus indistinguishable under reflection 94 - Cyclic data structures are not supported and will result in ErrMaxDecodingDepth errors 95 96 If any issues are encountered during the unmarshalling process, an 97 UnmarshalError is returned with a human readable description as well as 98 an ErrorCode value for further inspection from sophisticated callers. Some 99 potential issues are unsupported Go types, attempting to decode a value which is 100 too large to fit into a specified Go type, and exceeding max slice limitations. 101 */ 102 func Unmarshal(r io.Reader, v interface{}) (int, error) { 103 d := NewDecoder(r) 104 return d.Decode(v) 105 } 106 107 // UnmarshalWithOptions works like Unmarshal but accepts decoding options. 108 func UnmarshalWithOptions(r io.Reader, v interface{}, options DecodeOptions) (int, error) { 109 d := NewDecoderWithOptions(r, options) 110 return d.Decode(v) 111 } 112 113 type lenLeft interface { 114 Len() int 115 } 116 117 // A Decoder wraps an io.Reader that is expected to provide an XDR-encoded byte 118 // stream and provides several exposed methods to manually decode various XDR 119 // primitives without relying on reflection. The NewDecoder function can be 120 // used to get a new Decoder directly. 121 // 122 // Typically, Unmarshal should be used instead of manual decoding. A Decoder 123 // is exposed, so it is possible to perform manual decoding should it be 124 // necessary in complex scenarios where automatic reflection-based decoding 125 // won't work. 126 type Decoder struct { 127 // used to minimize heap allocations during decoding 128 scratchBuf [8]byte 129 r io.Reader 130 l lenLeft 131 maxDepth uint 132 } 133 134 // readerLenWrapper wraps a reader an initial length and provides a Len() method indicating 135 // how much input is left 136 type readerLenWrapper struct { 137 inner io.Reader 138 readCount int 139 initialLen int 140 } 141 142 func (l *readerLenWrapper) Len() int { 143 return l.initialLen - l.readCount 144 } 145 146 func (l *readerLenWrapper) Read(p []byte) (int, error) { 147 n, err := l.inner.Read(p) 148 if n > 0 { 149 l.readCount += n 150 } 151 return n, err 152 } 153 154 // NewDecoder returns a Decoder that can be used to manually decode XDR data 155 // from a provided reader. Typically, Unmarshal should be used instead of 156 // manually creating a Decoder. 157 func NewDecoder(r io.Reader) *Decoder { 158 return NewDecoderWithOptions(r, DefaultDecodeOptions) 159 } 160 161 // NewDecoderWithOptions works like NewDecoder but allows supplying decoding options. 162 func NewDecoderWithOptions(r io.Reader, options DecodeOptions) *Decoder { 163 maxDepth := options.MaxDepth 164 if maxDepth < 1 { 165 maxDepth = DecodeDefaultMaxDepth 166 } 167 if l, ok := r.(lenLeft); ok { 168 return &Decoder{r: r, l: l, maxDepth: maxDepth} 169 } 170 if options.MaxInputLen > 0 { 171 rlw := &readerLenWrapper{ 172 inner: r, 173 initialLen: options.MaxInputLen, 174 } 175 return &Decoder{r: rlw, l: rlw, maxDepth: maxDepth} 176 } 177 return &Decoder{r: r, l: nil, maxDepth: options.MaxDepth} 178 } 179 180 // DecodeInt treats the next 4 bytes as an XDR encoded integer and returns the 181 // result as an int32 along with the number of bytes actually read. 182 // 183 // An UnmarshalError is returned if there are insufficient bytes remaining. 184 // 185 // Reference: 186 // 187 // RFC Section 4.1 - Integer 188 // 32-bit big-endian signed integer in range [-2147483648, 2147483647] 189 func (d *Decoder) DecodeInt() (int32, int, error) { 190 n, err := io.ReadFull(d.r, d.scratchBuf[:4]) 191 if err != nil { 192 msg := fmt.Sprintf(errIODecode, err.Error(), 4) 193 err := unmarshalError("DecodeInt", ErrIO, msg, d.scratchBuf[:n], err) 194 return 0, n, err 195 } 196 197 rv := int32(d.scratchBuf[3]) | int32(d.scratchBuf[2])<<8 | 198 int32(d.scratchBuf[1])<<16 | int32(d.scratchBuf[0])<<24 199 return rv, n, nil 200 } 201 202 // DecodeUint treats the next 4 bytes as an XDR encoded unsigned integer and 203 // returns the result as a uint32 along with the number of bytes actually read. 204 // 205 // An UnmarshalError is returned if there are insufficient bytes remaining. 206 // 207 // Reference: 208 // 209 // RFC Section 4.2 - Unsigned Integer 210 // 32-bit big-endian unsigned integer in range [0, 4294967295] 211 func (d *Decoder) DecodeUint() (uint32, int, error) { 212 n, err := io.ReadFull(d.r, d.scratchBuf[:4]) 213 if err != nil { 214 msg := fmt.Sprintf(errIODecode, err.Error(), 4) 215 err := unmarshalError("DecodeUint", ErrIO, msg, d.scratchBuf[:n], err) 216 return 0, n, err 217 } 218 219 rv := uint32(d.scratchBuf[3]) | uint32(d.scratchBuf[2])<<8 | 220 uint32(d.scratchBuf[1])<<16 | uint32(d.scratchBuf[0])<<24 221 return rv, n, nil 222 } 223 224 // DecodeEnum treats the next 4 bytes as an XDR encoded enumeration value and 225 // returns the result as an int32 after verifying that the value is in the 226 // provided map of valid values. It also returns the number of bytes actually 227 // read. 228 // 229 // An UnmarshalError is returned if there are insufficient bytes remaining or 230 // the parsed enumeration value is not one of the provided valid values. 231 // 232 // Reference: 233 // 234 // RFC Section 4.3 - Enumeration 235 // Represented as an XDR encoded signed integer 236 func (d *Decoder) DecodeEnum(validEnums map[int32]bool) (int32, int, error) { 237 val, n, err := d.DecodeInt() 238 if err != nil { 239 return 0, n, err 240 } 241 242 if !validEnums[val] { 243 err := unmarshalError("DecodeEnum", ErrBadEnumValue, 244 "invalid enum", val, nil) 245 return 0, n, err 246 } 247 return val, n, nil 248 } 249 250 // DecodeBool treats the next 4 bytes as an XDR encoded boolean value and 251 // returns the result as a bool along with the number of bytes actually read. 252 // 253 // An UnmarshalError is returned if there are insufficient bytes remaining or 254 // the parsed value is not a 0 or 1. 255 // 256 // Reference: 257 // 258 // RFC Section 4.4 - Boolean 259 // Represented as an XDR encoded enumeration where 0 is false and 1 is true 260 func (d *Decoder) DecodeBool() (bool, int, error) { 261 val, n, err := d.DecodeInt() 262 if err != nil { 263 return false, n, err 264 } 265 switch val { 266 case 0: 267 return false, n, nil 268 case 1: 269 return true, n, nil 270 } 271 272 err = unmarshalError("DecodeBool", ErrBadEnumValue, "bool not 0 or 1", 273 val, nil) 274 return false, n, err 275 } 276 277 // DecodeHyper treats the next 8 bytes as an XDR encoded hyper value and 278 // returns the result as an int64 along with the number of bytes actually read. 279 // 280 // An UnmarshalError is returned if there are insufficient bytes remaining. 281 // 282 // Reference: 283 // 284 // RFC Section 4.5 - Hyper Integer 285 // 64-bit big-endian signed integer in range [-9223372036854775808, 9223372036854775807] 286 func (d *Decoder) DecodeHyper() (int64, int, error) { 287 n, err := io.ReadFull(d.r, d.scratchBuf[:8]) 288 if err != nil { 289 msg := fmt.Sprintf(errIODecode, err.Error(), 8) 290 err := unmarshalError("DecodeHyper", ErrIO, msg, d.scratchBuf[:n], err) 291 return 0, n, err 292 } 293 294 rv := int64(d.scratchBuf[7]) | int64(d.scratchBuf[6])<<8 | 295 int64(d.scratchBuf[5])<<16 | int64(d.scratchBuf[4])<<24 | 296 int64(d.scratchBuf[3])<<32 | int64(d.scratchBuf[2])<<40 | 297 int64(d.scratchBuf[1])<<48 | int64(d.scratchBuf[0])<<56 298 return rv, n, err 299 } 300 301 // DecodeUhyper treats the next 8 bytes as an XDR encoded unsigned hyper value 302 // and returns the result as a uint64 along with the number of bytes actually 303 // read. 304 // 305 // An UnmarshalError is returned if there are insufficient bytes remaining. 306 // 307 // Reference: 308 // 309 // RFC Section 4.5 - Unsigned Hyper Integer 310 // 64-bit big-endian unsigned integer in range [0, 18446744073709551615] 311 func (d *Decoder) DecodeUhyper() (uint64, int, error) { 312 n, err := io.ReadFull(d.r, d.scratchBuf[:8]) 313 if err != nil { 314 msg := fmt.Sprintf(errIODecode, err.Error(), 8) 315 err := unmarshalError("DecodeUhyper", ErrIO, msg, d.scratchBuf[:n], err) 316 return 0, n, err 317 } 318 319 rv := uint64(d.scratchBuf[7]) | uint64(d.scratchBuf[6])<<8 | 320 uint64(d.scratchBuf[5])<<16 | uint64(d.scratchBuf[4])<<24 | 321 uint64(d.scratchBuf[3])<<32 | uint64(d.scratchBuf[2])<<40 | 322 uint64(d.scratchBuf[1])<<48 | uint64(d.scratchBuf[0])<<56 323 return rv, n, nil 324 } 325 326 // DecodeFloat treats the next 4 bytes as an XDR encoded floating point and 327 // returns the result as a float32 along with the number of bytes actually read. 328 // 329 // An UnmarshalError is returned if there are insufficient bytes remaining. 330 // 331 // Reference: 332 // 333 // RFC Section 4.6 - Floating Point 334 // 32-bit single-precision IEEE 754 floating point 335 func (d *Decoder) DecodeFloat() (float32, int, error) { 336 n, err := io.ReadFull(d.r, d.scratchBuf[:4]) 337 if err != nil { 338 msg := fmt.Sprintf(errIODecode, err.Error(), 4) 339 err := unmarshalError("DecodeFloat", ErrIO, msg, d.scratchBuf[:n], err) 340 return 0, n, err 341 } 342 343 val := uint32(d.scratchBuf[3]) | uint32(d.scratchBuf[2])<<8 | 344 uint32(d.scratchBuf[1])<<16 | uint32(d.scratchBuf[0])<<24 345 return math.Float32frombits(val), n, nil 346 } 347 348 // DecodeDouble treats the next 8 bytes as an XDR encoded double-precision 349 // floating point and returns the result as a float64 along with the number of 350 // bytes actually read. 351 // 352 // An UnmarshalError is returned if there are insufficient bytes remaining. 353 // 354 // Reference: 355 // 356 // RFC Section 4.7 - Double-Precision Floating Point 357 // 64-bit double-precision IEEE 754 floating point 358 func (d *Decoder) DecodeDouble() (float64, int, error) { 359 n, err := io.ReadFull(d.r, d.scratchBuf[:8]) 360 if err != nil { 361 msg := fmt.Sprintf(errIODecode, err.Error(), 8) 362 err := unmarshalError("DecodeDouble", ErrIO, msg, d.scratchBuf[:n], err) 363 return 0, n, err 364 } 365 366 val := uint64(d.scratchBuf[7]) | uint64(d.scratchBuf[6])<<8 | 367 uint64(d.scratchBuf[5])<<16 | uint64(d.scratchBuf[4])<<24 | 368 uint64(d.scratchBuf[3])<<32 | uint64(d.scratchBuf[2])<<40 | 369 uint64(d.scratchBuf[1])<<48 | uint64(d.scratchBuf[0])<<56 370 return math.Float64frombits(val), n, nil 371 } 372 373 // RFC Section 4.8 - Quadruple-Precision Floating Point 374 // 128-bit quadruple-precision floating point 375 // Not Implemented 376 377 // DecodeFixedOpaque treats the next 'size' bytes as XDR encoded opaque data and 378 // returns the result as a byte slice along with the number of bytes actually 379 // read. 380 // 381 // An UnmarshalError is returned if there are insufficient bytes remaining to 382 // satisfy the passed size, including the necessary padding to make it a 383 // multiple of 4. 384 // 385 // Reference: 386 // 387 // RFC Section 4.9 - Fixed-Length Opaque Data 388 // Fixed-length uninterpreted data zero-padded to a multiple of four 389 func (d *Decoder) DecodeFixedOpaque(size int32) ([]byte, int, error) { 390 out := make([]byte, size) 391 n, err := d.DecodeFixedOpaqueInplace(out) 392 if err != nil { 393 return nil, n, err 394 } 395 return out, n, nil 396 } 397 398 // DecodeFixedOpaqueInplace is an in-place version of DecodeFixedOpaque. 399 // It improves performance when the destination is pre-allocated (which avoids 400 // internally allocating an extra slice and does not require further copying) 401 func (d *Decoder) DecodeFixedOpaqueInplace(out []byte) (int, error) { 402 size := len(out) 403 // Nothing to do if size is 0. 404 if size == 0 { 405 return 0, nil 406 } 407 408 pad := (4 - (size % 4)) % 4 409 paddedSize := size + pad 410 if uint(paddedSize) > uint(maxInt32) { 411 err := unmarshalError("DecodeFixedOpaqueInplace", ErrOverflow, 412 errMaxSlice, paddedSize, nil) 413 return 0, err 414 } 415 416 n, err := io.ReadFull(d.r, out) 417 if err != nil { 418 msg := fmt.Sprintf(errIODecode, err.Error(), size) 419 err := unmarshalError("DecodeFixedOpaqueInplace", ErrIO, msg, out[:n], 420 err) 421 return n, err 422 } 423 424 if pad > 0 { 425 // the maximum value of pad is 3, so the scratch buffer should be enough 426 _ = d.scratchBuf[2] 427 padding := d.scratchBuf[:pad] 428 n2, err := io.ReadFull(d.r, padding) 429 if err != nil { 430 msg := fmt.Sprintf(errIODecode, err.Error(), pad) 431 err := unmarshalError("DecodeFixedOpaqueInplace", ErrIO, msg, out[:n], 432 err) 433 return n, err 434 } 435 n += n2 436 // check all the padding bytes to be zero 437 for _, p := range padding { 438 if p != 0x00 { 439 msg := "non-zero padding" 440 err := unmarshalError("DecodeFixedOpaqueInplace", ErrIO, msg, padding[:n2], nil) 441 return n, err 442 } 443 } 444 } 445 446 return n, nil 447 } 448 449 // DecodeOpaque treats the next bytes as variable length XDR encoded opaque 450 // data and returns the result as a byte slice along with the number of bytes 451 // actually read. 452 // 453 // An UnmarshalError is returned if there are insufficient bytes remaining or 454 // the opaque data is larger than the max length of a Go slice. 455 // 456 // Reference: 457 // 458 // RFC Section 4.10 - Variable-Length Opaque Data 459 // Unsigned integer length followed by fixed opaque data of that length 460 func (d *Decoder) DecodeOpaque(maxSize int) ([]byte, int, error) { 461 dataLen, n, err := d.DecodeUint() 462 if err != nil { 463 return nil, n, err 464 } 465 466 maxSize = d.mergeInputLenAndMaxSize(maxSize) 467 if maxSize == 0 { 468 maxSize = maxInt32 469 } 470 471 if uint(dataLen) > uint(maxSize) { 472 err := unmarshalError("DecodeOpaque", ErrOverflow, errMaxSlice, 473 dataLen, nil) 474 return nil, n, err 475 } 476 477 rv, n2, err := d.DecodeFixedOpaque(int32(dataLen)) 478 n += n2 479 if err != nil { 480 return nil, n, err 481 } 482 return rv, n, nil 483 } 484 485 // DecodeString treats the next bytes as a variable length XDR encoded string 486 // and returns the result as a string along with the number of bytes actually 487 // read. Character encoding is assumed to be UTF-8 and therefore ASCII 488 // compatible. If the underlying character encoding is not compatibile with 489 // this assumption, the data can instead be read as variable-length opaque data 490 // (DecodeOpaque) and manually converted as needed. 491 // 492 // An UnmarshalError is returned if there are insufficient bytes remaining or 493 // the string data is larger than the max length of a Go slice. 494 // 495 // Reference: 496 // 497 // RFC Section 4.11 - String 498 // Unsigned integer length followed by bytes zero-padded to a multiple of 499 // four 500 func (d *Decoder) DecodeString(maxSize int) (string, int, error) { 501 dataLen, n, err := d.DecodeUint() 502 if err != nil { 503 return "", n, err 504 } 505 506 maxSize = d.mergeInputLenAndMaxSize(maxSize) 507 if maxSize == 0 { 508 maxSize = maxInt32 509 } 510 511 if uint(dataLen) > uint(maxSize) { 512 err = unmarshalError("DecodeString", ErrOverflow, errMaxSlice, 513 dataLen, nil) 514 return "", n, err 515 } 516 517 opaque, n2, err := d.DecodeFixedOpaque(int32(dataLen)) 518 n += n2 519 if err != nil { 520 return "", n, err 521 } 522 return string(opaque), n, nil 523 } 524 525 // decodeFixedArray treats the next bytes as a series of XDR encoded elements 526 // of the same type as the array represented by the reflection value and decodes 527 // each element into the passed array. The ignoreOpaque flag controls whether 528 // or not uint8 (byte) elements should be decoded individually or as a fixed 529 // sequence of opaque data. It returns the the number of bytes actually read. 530 // 531 // An UnmarshalError is returned if any issues are encountered while decoding 532 // the array elements. 533 // 534 // Reference: 535 // 536 // RFC Section 4.12 - Fixed-Length Array 537 // Individually XDR encoded array elements 538 func (d *Decoder) decodeFixedArray(v reflect.Value, ignoreOpaque bool, maxDepth uint) (int, error) { 539 // Treat [#]byte (byte is alias for uint8) as opaque data unless 540 // ignored. 541 if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 { 542 dest := v.Slice(0, v.Len()).Bytes() 543 return d.DecodeFixedOpaqueInplace(dest) 544 } 545 546 // Decode each array element. 547 var n int 548 for i := 0; i < v.Len(); i++ { 549 n2, err := d.decode(v.Index(i), 0, maxDepth) 550 n += n2 551 if err != nil { 552 return n, err 553 } 554 } 555 return n, nil 556 } 557 558 // decodeArray treats the next bytes as a variable length series of XDR encoded 559 // elements of the same type as the array represented by the reflection value. 560 // The number of elements is obtained by first decoding the unsigned integer 561 // element count. Then each element is decoded into the passed array. The 562 // ignoreOpaque flag controls whether uint8 (byte) elements should be 563 // decoded individually or as a variable sequence of opaque data. It returns 564 // the number of bytes actually read. 565 // 566 // An UnmarshalError is returned if any issues are encountered while decoding 567 // the array elements. 568 // 569 // Reference: 570 // 571 // RFC Section 4.13 - Variable-Length Array 572 // Unsigned integer length followed by individually XDR encoded array 573 // elements 574 func (d *Decoder) decodeArray(v reflect.Value, ignoreOpaque bool, maxSize int, maxDepth uint) (int, error) { 575 dataLen, n, err := d.DecodeUint() 576 if err != nil { 577 return n, err 578 } 579 580 maxSize = d.mergeInputLenAndMaxSize(maxSize) 581 if maxSize == 0 { 582 maxSize = maxInt32 583 } 584 585 if uint(dataLen) > uint(maxSize) { 586 err := unmarshalError("decodeArray", ErrOverflow, errMaxSlice, 587 dataLen, nil) 588 return n, err 589 } 590 591 // Allocate storage for the slice elements (the underlying array) if 592 // existing slice does not have enough capacity. 593 sliceLen := int(dataLen) 594 if v.Cap() < sliceLen { 595 v.Set(reflect.MakeSlice(v.Type(), sliceLen, sliceLen)) 596 } 597 v.SetLen(sliceLen) 598 599 // Treat []byte (byte is alias for uint8) as opaque data unless ignored. 600 if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 { 601 data, n2, err := d.DecodeFixedOpaque(int32(sliceLen)) 602 n += n2 603 if err != nil { 604 return n, err 605 } 606 v.SetBytes(data) 607 return n, nil 608 } 609 610 // Decode each slice element. 611 for i := 0; i < sliceLen; i++ { 612 n2, err := d.decode(v.Index(i), 0, maxDepth) 613 n += n2 614 if err != nil { 615 return n, err 616 } 617 } 618 return n, nil 619 } 620 621 func setUnionArmsToNil(v reflect.Value) { 622 for i := 0; i < v.NumField(); i++ { 623 f := v.Field(i) 624 if f.Kind() != reflect.Ptr { 625 continue 626 } 627 v.Set(reflect.Zero(v.Type())) 628 } 629 } 630 631 // decodeUnion 632 func (d *Decoder) decodeUnion(v reflect.Value, maxDepth uint) (int, error) { 633 // we should have already checked that v is a union 634 // prior to this call, so we panic if v is not a union 635 u := v.Interface().(Union) 636 637 setUnionArmsToNil(v) 638 639 i, n, err := d.DecodeInt() 640 if err != nil { 641 return n, err 642 } 643 644 vs := v.FieldByName(u.SwitchFieldName()) 645 646 // ensure the switch field is a valid enum value for the union, if possible 647 enum, ok := vs.Interface().(Enum) 648 649 if ok && !enum.ValidEnum(i) { 650 msg := fmt.Sprintf("switch '%d' is not valid enum value for union", i) 651 err := unmarshalError("decode", ErrBadUnionSwitch, msg, nil, nil) 652 return n, err 653 } 654 655 kind := vs.Kind() 656 if kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || 657 kind == reflect.Uint32 || kind == reflect.Uint64 { 658 vs.SetUint(uint64(i)) 659 } else { 660 vs.SetInt(int64(i)) 661 } 662 663 arm, ok := u.ArmForSwitch(i) 664 665 if !ok { 666 msg := fmt.Sprintf("switch '%d' is not valid for union", i) 667 err := unmarshalError("decode", ErrBadUnionSwitch, msg, nil, nil) 668 return n, err 669 } 670 671 if arm == "" { 672 return n, nil 673 } 674 675 vv := v.FieldByName(arm) 676 677 vvet := vv.Type().Elem() 678 vv.Set(reflect.New(vvet)) 679 680 field, ok := v.Type().FieldByName(arm) 681 if !ok { 682 msg := fmt.Sprintf("switch '%s' is not valid for union", arm) 683 err := unmarshalError("decode", ErrBadUnionSwitch, msg, nil, nil) 684 return n, err 685 } 686 687 maxSize := 0 688 sizeTag := field.Tag.Get("xdrmaxsize") 689 if sizeTag != "" { 690 sz, err := strconv.ParseInt(sizeTag, 10, 32) 691 if err != nil { 692 return n, err 693 } 694 maxSize = int(sz) 695 } 696 697 n2, err := d.decode(vv.Elem(), maxSize, maxDepth) 698 n += n2 699 700 if err != nil { 701 return n, err 702 } 703 return n, nil 704 } 705 706 // decodeStruct treats the next bytes as a series of XDR encoded elements 707 // of the same type as the exported fields of the struct represented by the 708 // passed reflection value. Pointers are automatically indirected and 709 // allocated as necessary. It returns the number of bytes actually read. 710 // 711 // An UnmarshalError is returned if any issues are encountered while decoding 712 // the elements. 713 // 714 // Reference: 715 // 716 // RFC Section 4.14 - Structure 717 // XDR encoded elements in the order of their declaration in the struct 718 func (d *Decoder) decodeStruct(v reflect.Value, maxDepth uint) (int, error) { 719 var n int 720 vt := v.Type() 721 for i := 0; i < v.NumField(); i++ { 722 // Skip unexported fields. 723 vtf := vt.Field(i) 724 if vtf.PkgPath != "" { 725 continue 726 } 727 728 // Indirect through pointers allocating them as needed and 729 // ensure the field is settable. 730 vf := v.Field(i) 731 732 if !vf.CanSet() { 733 msg := fmt.Sprintf("can't decode to unsettable '%v'", 734 vf.Type().String()) 735 err := unmarshalError("decodeStruct", ErrNotSettable, 736 msg, nil, nil) 737 return n, err 738 } 739 740 // Handle non-opaque data to []uint8 and [#]uint8 based on 741 // struct tag. 742 tag := vtf.Tag.Get("xdropaque") 743 if tag == "false" { 744 switch vf.Kind() { 745 case reflect.Slice: 746 maxSize := 0 747 if dest, ok := vf.Interface().(Sized); ok { 748 maxSize = dest.XDRMaxSize() 749 } 750 751 n2, err := d.decodeArray(vf, true, maxSize, maxDepth) 752 n += n2 753 if err != nil { 754 return n, err 755 } 756 continue 757 758 case reflect.Array: 759 n2, err := d.decodeFixedArray(vf, true, maxDepth) 760 n += n2 761 if err != nil { 762 return n, err 763 } 764 continue 765 } 766 } 767 768 maxSize := 0 769 sizeTag := vtf.Tag.Get("xdrmaxsize") 770 if sizeTag != "" { 771 sz, err := strconv.ParseInt(sizeTag, 10, 32) 772 if err != nil { 773 return n, err 774 } 775 maxSize = int(sz) 776 } 777 778 // Decode each struct field. 779 n2, err := d.decode(vf, maxSize, maxDepth) 780 n += n2 781 if err != nil { 782 return n, err 783 } 784 } 785 786 return n, nil 787 } 788 789 // RFC Section 4.15 - Discriminated Union 790 // RFC Section 4.16 - Void 791 // RFC Section 4.17 - Constant 792 // RFC Section 4.18 - Typedef 793 // RFC Section 4.19 - Optional data 794 // RFC Sections 4.15 though 4.19 only apply to the data specification language 795 // which is not implemented by this package. In the case of discriminated 796 // unions, struct tags are used to perform a similar function. 797 798 // decodeMap treats the next bytes as an XDR encoded variable array of 2-element 799 // structures whose fields are of the same type as the map keys and elements 800 // represented by the passed reflection value. Pointers are automatically 801 // indirected and allocated as necessary. It returns the the number of bytes 802 // actually read. 803 // 804 // An UnmarshalError is returned if any issues are encountered while decoding 805 // the elements. 806 func (d *Decoder) decodeMap(v reflect.Value, maxDepth uint) (int, error) { 807 dataLen, n, err := d.DecodeUint() 808 if err != nil { 809 return n, err 810 } 811 if left, ok := d.InputLen(); ok { 812 if uint(left) < uint(dataLen) { 813 return n, unmarshalError("decodeMap", ErrOverflow, errMaxSlice, dataLen, nil) 814 } 815 } 816 817 // Allocate storage for the underlying map if needed. 818 vt := v.Type() 819 if v.IsNil() { 820 v.Set(reflect.MakeMap(vt)) 821 } 822 823 // Decode each key and value according to their type. 824 keyType := vt.Key() 825 elemType := vt.Elem() 826 for i := uint32(0); i < dataLen; i++ { 827 key := reflect.New(keyType).Elem() 828 n2, err := d.decode(key, 0, maxDepth) 829 n += n2 830 if err != nil { 831 return n, err 832 } 833 834 val := reflect.New(elemType).Elem() 835 n2, err = d.decode(val, 0, maxDepth) 836 n += n2 837 if err != nil { 838 return n, err 839 } 840 v.SetMapIndex(key, val) 841 } 842 return n, nil 843 } 844 845 // decodeInterface examines the interface represented by the passed reflection 846 // value to detect whether it is an interface that can be decoded into and 847 // if it is, extracts the underlying value to pass back into the decode function 848 // for decoding according to its type. It returns the number of bytes 849 // actually read. 850 // 851 // An UnmarshalError is returned if any issues are encountered while decoding 852 // the interface. 853 func (d *Decoder) decodeInterface(v reflect.Value, maxDepth uint) (int, error) { 854 if v.IsNil() || !v.CanInterface() { 855 msg := fmt.Sprintf("can't decode to nil interface") 856 err := unmarshalError("decodeInterface", ErrNilInterface, msg, 857 nil, nil) 858 return 0, err 859 } 860 861 // Extract underlying value from the interface and indirect through 862 // any pointer, allocating as needed. 863 ve := reflect.ValueOf(v.Interface()) 864 ve, err := d.indirectIfPtr(ve) 865 if err != nil { 866 return 0, err 867 } 868 if !ve.CanSet() { 869 msg := fmt.Sprintf("can't decode to unsettable '%v'", 870 ve.Type().String()) 871 err := unmarshalError("decodeInterface", ErrNotSettable, msg, 872 nil, nil) 873 return 0, err 874 } 875 return d.decode(ve, 0, maxDepth) 876 } 877 878 func (d *Decoder) mergeInputLenAndMaxSize(maxSize int) int { 879 if left, ok := d.InputLen(); ok { 880 if maxSize == 0 || left < maxSize { 881 return left 882 } 883 } 884 return maxSize 885 } 886 887 // decode is the main workhorse for unmarshalling via reflection. It uses 888 // the passed reflection value to choose the XDR primitives to decode from 889 // the encapsulated reader. It is a recursive function, 890 // so cyclic data structures are not supported and will result in an ErrMaxDecodingDepth 891 // error. It returns the number of bytes actually read. 892 func (d *Decoder) decode(ve reflect.Value, maxSize int, maxDepth uint) (int, error) { 893 if maxDepth == 0 { 894 return 0, unmarshalError("decode", ErrMaxDecodingDepth, "maximum decoding depth reached", nil, nil) 895 } 896 maxDepth-- 897 898 if !ve.IsValid() { 899 msg := fmt.Sprintf("type '%s' is not valid", ve.Kind().String()) 900 err := unmarshalError("decode", ErrUnsupportedType, msg, nil, nil) 901 return 0, err 902 } 903 904 // Handle time.Time values by decoding them as an RFC3339 formatted 905 // string with nanosecond precision. Check the type string rather 906 // than doing a full-blown conversion to interface and type assertion 907 // since checking a string is much quicker. 908 if ve.Type().String() == "time.Time" { 909 // Read the value as a string and parse it. 910 timeString, n, err := d.DecodeString(maxSize) 911 if err != nil { 912 return n, err 913 } 914 ttv, err := time.Parse(time.RFC3339, timeString) 915 if err != nil { 916 err := unmarshalError("decode", ErrParseTime, 917 err.Error(), timeString, err) 918 return n, err 919 } 920 ve.Set(reflect.ValueOf(ttv)) 921 return n, nil 922 } 923 924 // Handle native Go types. 925 switch ve.Kind() { 926 927 case reflect.Ptr: 928 return d.decodePtr(ve, maxDepth) 929 930 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int: 931 i, n, err := d.DecodeInt() 932 if err != nil { 933 return n, err 934 } 935 if ve.OverflowInt(int64(i)) { 936 msg := fmt.Sprintf("signed integer too large to fit '%s'", 937 ve.Kind().String()) 938 err = unmarshalError("decode", ErrOverflow, msg, i, nil) 939 return n, err 940 } 941 ve.SetInt(int64(i)) 942 enum, ok := ve.Interface().(Enum) 943 944 if ok { 945 if !enum.ValidEnum(i) { 946 err := unmarshalError("decode", ErrBadEnumValue, "invalid enum", i, nil) 947 return n, err 948 } 949 } 950 951 return n, nil 952 953 case reflect.Int64: 954 i, n, err := d.DecodeHyper() 955 if err != nil { 956 return n, err 957 } 958 ve.SetInt(i) 959 return n, nil 960 961 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint: 962 ui, n, err := d.DecodeUint() 963 if err != nil { 964 return n, err 965 } 966 if ve.OverflowUint(uint64(ui)) { 967 msg := fmt.Sprintf("unsigned integer too large to fit '%s'", 968 ve.Kind().String()) 969 err = unmarshalError("decode", ErrOverflow, msg, ui, nil) 970 return n, err 971 } 972 ve.SetUint(uint64(ui)) 973 return n, nil 974 975 case reflect.Uint64: 976 ui, n, err := d.DecodeUhyper() 977 if err != nil { 978 return n, err 979 } 980 ve.SetUint(ui) 981 return n, nil 982 983 case reflect.Bool: 984 b, n, err := d.DecodeBool() 985 if err != nil { 986 return n, err 987 } 988 ve.SetBool(b) 989 return n, nil 990 991 case reflect.Float32: 992 f, n, err := d.DecodeFloat() 993 if err != nil { 994 return n, err 995 } 996 ve.SetFloat(float64(f)) 997 return n, nil 998 999 case reflect.Float64: 1000 f, n, err := d.DecodeDouble() 1001 if err != nil { 1002 return n, err 1003 } 1004 ve.SetFloat(f) 1005 return n, nil 1006 1007 case reflect.String: 1008 if dest, ok := ve.Interface().(Sized); ok { 1009 maxSize = dest.XDRMaxSize() 1010 } 1011 1012 s, n, err := d.DecodeString(maxSize) 1013 if err != nil { 1014 return n, err 1015 } 1016 ve.SetString(s) 1017 return n, nil 1018 1019 case reflect.Array: 1020 n, err := d.decodeFixedArray(ve, false, maxDepth) 1021 if err != nil { 1022 return n, err 1023 } 1024 return n, nil 1025 1026 case reflect.Slice: 1027 if dest, ok := ve.Interface().(Sized); ok { 1028 maxSize = dest.XDRMaxSize() 1029 } 1030 1031 n, err := d.decodeArray(ve, false, maxSize, maxDepth) 1032 if err != nil { 1033 return n, err 1034 } 1035 return n, nil 1036 1037 case reflect.Struct: 1038 // If the struct's pointer implements union 1039 // we need to init the union's value interface 1040 1041 if _, ok := ve.Interface().(Union); ok { 1042 return d.decodeUnion(ve, maxDepth) 1043 } 1044 1045 n, err := d.decodeStruct(ve, maxDepth) 1046 if err != nil { 1047 return n, err 1048 } 1049 return n, nil 1050 1051 case reflect.Map: 1052 n, err := d.decodeMap(ve, maxDepth) 1053 if err != nil { 1054 return n, err 1055 } 1056 return n, nil 1057 1058 case reflect.Interface: 1059 n, err := d.decodeInterface(ve, maxDepth) 1060 if err != nil { 1061 return n, err 1062 } 1063 return n, nil 1064 } 1065 1066 // The only unhandled types left are unsupported. At the time of this 1067 // writing the only remaining unsupported types that exist are 1068 // reflect.Uintptr and reflect.UnsafePointer. 1069 msg := fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String()) 1070 err := unmarshalError("decode", ErrUnsupportedType, msg, nil, nil) 1071 return 0, err 1072 } 1073 1074 func setPtrToNil(v *reflect.Value) error { 1075 if v.Kind() != reflect.Ptr { 1076 msg := fmt.Sprintf("value is not a pointer: '%v'", 1077 v.Type().String()) 1078 err := unmarshalError("decodePtr", ErrBadArguments, msg, 1079 nil, nil) 1080 return err 1081 } 1082 if !v.CanSet() { 1083 msg := fmt.Sprintf("pointer value cannot be changed for '%v'", 1084 v.Type().String()) 1085 err := unmarshalError("decodePtr", ErrNotSettable, msg, 1086 nil, nil) 1087 return err 1088 } 1089 1090 v.Set(reflect.Zero(v.Type())) 1091 return nil 1092 } 1093 1094 func (d *Decoder) allocPtrIfNil(v *reflect.Value) error { 1095 if v.Kind() != reflect.Ptr { 1096 msg := fmt.Sprintf("value is not a pointer: '%v'", 1097 v.Type().String()) 1098 err := unmarshalError("decodePtr", ErrBadArguments, msg, 1099 nil, nil) 1100 return err 1101 } 1102 isNil := v.IsNil() 1103 if isNil && !v.CanSet() { 1104 msg := fmt.Sprintf("unable to allocate pointer for '%v'", 1105 v.Type().String()) 1106 err := unmarshalError("decodePtr", ErrNotSettable, msg, 1107 nil, nil) 1108 return err 1109 } 1110 if isNil { 1111 vet := v.Type().Elem() 1112 v.Set(reflect.New(vet)) 1113 } 1114 return nil 1115 } 1116 1117 // decodePtr decodes a single tagged XDR pointer type: one 4-byte 1118 // boolean followed by an encoded referent, which is allocated if needed. 1119 func (d *Decoder) decodePtr(v reflect.Value, maxDepth uint) (int, error) { 1120 1121 present, n, err := d.DecodeBool() 1122 1123 if err != nil { 1124 return n, err 1125 } 1126 1127 if !present { 1128 err = setPtrToNil(&v) 1129 return n, err 1130 } 1131 1132 if err = d.allocPtrIfNil(&v); err != nil { 1133 return n, err 1134 } 1135 1136 n2, err := d.decode(v.Elem(), 0, maxDepth) 1137 return n + n2, err 1138 } 1139 1140 // IndirectIfPtr allocates a pointee and dereferences it, if passed a Ptr type, 1141 // otherwise returns the passed value. 1142 func (d *Decoder) indirectIfPtr(v reflect.Value) (reflect.Value, error) { 1143 if v.Kind() == reflect.Ptr { 1144 err := d.allocPtrIfNil(&v) 1145 return v.Elem(), err 1146 } 1147 return v, nil 1148 } 1149 1150 // Decode operates identically to the Unmarshal function with the exception of 1151 // using the reader associated with the Decoder as the source of XDR-encoded 1152 // data instead of a user-supplied reader. See the Unmarhsal documentation for 1153 // specifics. Decode(v) is equivalent to DecodeWithMaxDepth(v, DecodeDefaultMaxDepth) 1154 func (d *Decoder) Decode(v interface{}) (int, error) { 1155 if v == nil { 1156 msg := "can't unmarshal to nil interface" 1157 return 0, unmarshalError("Unmarshal", ErrNilInterface, msg, nil, 1158 nil) 1159 } 1160 1161 vv := reflect.ValueOf(v) 1162 if vv.Kind() != reflect.Ptr { 1163 msg := fmt.Sprintf("can't unmarshal to non-pointer '%v' - use "+ 1164 "& operator", vv.Type().String()) 1165 err := unmarshalError("Unmarshal", ErrBadArguments, msg, nil, nil) 1166 return 0, err 1167 } 1168 if vv.IsNil() && !vv.CanSet() { 1169 msg := fmt.Sprintf("can't unmarshal to unsettable '%v' - use "+ 1170 "& operator", vv.Type().String()) 1171 err := unmarshalError("Unmarshal", ErrNotSettable, msg, nil, nil) 1172 return 0, err 1173 } 1174 1175 return d.decode(vv.Elem(), 0, d.maxDepth) 1176 } 1177 1178 // InputLen returns the size left to read from the decoder's input if available 1179 func (d *Decoder) InputLen() (int, bool) { 1180 if d.l == nil { 1181 return 0, false 1182 } 1183 return d.l.Len(), true 1184 }