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  }