github.com/stellar/go-xdr@v0.0.0-20231122183749-b53fb00bcac2/xdr2/decode_test.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_test
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"math"
    23  	"reflect"
    24  	"testing"
    25  	"time"
    26  
    27  	. "github.com/stellar/go-xdr/xdr2"
    28  )
    29  
    30  // subTest is used to allow testing of the Unmarshal function into struct fields
    31  // which are structs themselves.
    32  type subTest struct {
    33  	A string
    34  	B uint8
    35  }
    36  
    37  // allTypesTest is used to allow testing of the Unmarshal function into struct
    38  // fields of all supported types.
    39  type allTypesTest struct {
    40  	A int8
    41  	B uint8
    42  	C int16
    43  	D uint16
    44  	E int32
    45  	F uint32
    46  	G int64
    47  	H uint64
    48  	I bool
    49  	J float32
    50  	K float64
    51  	L string
    52  	M []byte
    53  	N [3]byte
    54  	O []int16
    55  	P [2]subTest
    56  	Q *subTest
    57  	R map[string]uint32
    58  	S time.Time
    59  }
    60  
    61  // opaqueStruct is used to test handling of uint8 slices and arrays.
    62  type opaqueStruct struct {
    63  	Slice []uint8  `xdropaque:"false"`
    64  	Array [1]uint8 `xdropaque:"false"`
    65  }
    66  
    67  // testExpectedURet is a convenience method to test an expected number of bytes
    68  // read and error for an unmarshal.
    69  func testExpectedURet(t *testing.T, name string, n, wantN int, err, wantErr error) bool {
    70  	// First ensure the number of bytes read is the expected value.  The
    71  	// byes read should be accurate even when an error occurs.
    72  	if n != wantN {
    73  		t.Errorf("%s: unexpected num bytes read - got: %v want: %v\n",
    74  			name, n, wantN)
    75  		return false
    76  	}
    77  
    78  	// Next check for the expected error.
    79  	if reflect.TypeOf(err) != reflect.TypeOf(wantErr) {
    80  		t.Errorf("%s: failed to detect error - got: %v <%[2]T> want: %T",
    81  			name, err, wantErr)
    82  		return false
    83  	}
    84  	if rerr, ok := err.(*UnmarshalError); ok {
    85  		if werr, ok := wantErr.(*UnmarshalError); ok {
    86  			if rerr.ErrorCode != werr.ErrorCode {
    87  				t.Errorf("%s: failed to detect error code - "+
    88  					"got: %v want: %v", name,
    89  					rerr.ErrorCode, werr.ErrorCode)
    90  				return false
    91  			}
    92  		}
    93  	}
    94  
    95  	return true
    96  }
    97  
    98  // TestUnmarshal ensures the Unmarshal function works properly with all types.
    99  func TestUnmarshal(t *testing.T) {
   100  	// Variables for various unsupported Unmarshal types.
   101  	var nilInterface interface{}
   102  	var testChan chan int
   103  	var testFunc func()
   104  	var testComplex64 complex64
   105  	var testComplex128 complex128
   106  
   107  	// structTestIn is input data for the big struct test of all supported
   108  	// types.
   109  	structTestIn := []byte{
   110  		0x00, 0x00, 0x00, 0x7F, // A
   111  		0x00, 0x00, 0x00, 0xFF, // B
   112  		0x00, 0x00, 0x7F, 0xFF, // C
   113  		0x00, 0x00, 0xFF, 0xFF, // D
   114  		0x7F, 0xFF, 0xFF, 0xFF, // E
   115  		0xFF, 0xFF, 0xFF, 0xFF, // F
   116  		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // G
   117  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // H
   118  		0x00, 0x00, 0x00, 0x01, // I
   119  		0x40, 0x48, 0xF5, 0xC3, // J
   120  		0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, // K
   121  		0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00, // L
   122  		0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // M
   123  		0x01, 0x02, 0x03, 0x00, // N
   124  		0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00,
   125  		0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // O
   126  		0x00, 0x00, 0x00, 0x03, 0x6F, 0x6E, 0x65, 0x00, // P[0].A
   127  		0x00, 0x00, 0x00, 0x01, // P[0].B
   128  		0x00, 0x00, 0x00, 0x03, 0x74, 0x77, 0x6F, 0x00, // P[1].A
   129  		0x00, 0x00, 0x00, 0x02, // P[1].B
   130  		0x00, 0x00, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, // Q.A
   131  		0x00, 0x00, 0x00, 0x03, // Q.B
   132  		0x00, 0x00, 0x00, 0x02, // R length
   133  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1
   134  		0x00, 0x00, 0x00, 0x01, // R value map1
   135  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2
   136  		0x00, 0x00, 0x00, 0x02, // R value map2
   137  		0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
   138  		0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
   139  		0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, // S
   140  	}
   141  
   142  	// structTestWant is the expected output after unmarshalling
   143  	// structTestIn.
   144  	structTestWant := allTypesTest{
   145  		127,                                     // A
   146  		255,                                     // B
   147  		32767,                                   // C
   148  		65535,                                   // D
   149  		2147483647,                              // E
   150  		4294967295,                              // F
   151  		9223372036854775807,                     // G
   152  		18446744073709551615,                    // H
   153  		true,                                    // I
   154  		3.14,                                    // J
   155  		3.141592653589793,                       // K
   156  		"xdr",                                   // L
   157  		[]byte{1, 2, 3, 4},                      // M
   158  		[3]byte{1, 2, 3},                        // N
   159  		[]int16{512, 1024, 2048},                // O
   160  		[2]subTest{{"one", 1}, {"two", 2}},      // P
   161  		&subTest{"bar", 3},                      // Q
   162  		map[string]uint32{"map1": 1, "map2": 2}, // R
   163  		time.Unix(1396581888, 0).UTC(),          // S
   164  	}
   165  
   166  	tests := []struct {
   167  		in      []byte      // input bytes
   168  		wantVal interface{} // expected value
   169  		wantN   int         // expected number of bytes read
   170  		err     error       // expected error
   171  	}{
   172  		// int8 - XDR Integer
   173  		{[]byte{0x00, 0x00, 0x00, 0x00}, int8(0), 4, nil},
   174  		{[]byte{0x00, 0x00, 0x00, 0x40}, int8(64), 4, nil},
   175  		{[]byte{0x00, 0x00, 0x00, 0x7F}, int8(127), 4, nil},
   176  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int8(-1), 4, nil},
   177  		{[]byte{0xFF, 0xFF, 0xFF, 0x80}, int8(-128), 4, nil},
   178  		// Expected Failures -- 128, -129 overflow int8 and not enough
   179  		// bytes
   180  		{[]byte{0x00, 0x00, 0x00, 0x80}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   181  		{[]byte{0xFF, 0xFF, 0xFF, 0x7F}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   182  		{[]byte{0x00, 0x00, 0x00}, int8(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   183  
   184  		// uint8 - XDR Unsigned Integer
   185  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint8(0), 4, nil},
   186  		{[]byte{0x00, 0x00, 0x00, 0x40}, uint8(64), 4, nil},
   187  		{[]byte{0x00, 0x00, 0x00, 0xFF}, uint8(255), 4, nil},
   188  		// Expected Failures -- 256, -1 overflow uint8 and not enough
   189  		// bytes
   190  		{[]byte{0x00, 0x00, 0x01, 0x00}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   191  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   192  		{[]byte{0x00, 0x00, 0x00}, uint8(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   193  
   194  		// int16 - XDR Integer
   195  		{[]byte{0x00, 0x00, 0x00, 0x00}, int16(0), 4, nil},
   196  		{[]byte{0x00, 0x00, 0x04, 0x00}, int16(1024), 4, nil},
   197  		{[]byte{0x00, 0x00, 0x7F, 0xFF}, int16(32767), 4, nil},
   198  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int16(-1), 4, nil},
   199  		{[]byte{0xFF, 0xFF, 0x80, 0x00}, int16(-32768), 4, nil},
   200  		// Expected Failures -- 32768, -32769 overflow int16 and not
   201  		// enough bytes
   202  		{[]byte{0x00, 0x00, 0x80, 0x00}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   203  		{[]byte{0xFF, 0xFF, 0x7F, 0xFF}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   204  		{[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   205  
   206  		// uint16 - XDR Unsigned Integer
   207  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint16(0), 4, nil},
   208  		{[]byte{0x00, 0x00, 0x04, 0x00}, uint16(1024), 4, nil},
   209  		{[]byte{0x00, 0x00, 0xFF, 0xFF}, uint16(65535), 4, nil},
   210  		// Expected Failures -- 65536, -1 overflow uint16 and not enough
   211  		// bytes
   212  		{[]byte{0x00, 0x01, 0x00, 0x00}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   213  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   214  		{[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   215  
   216  		// int32 - XDR Integer
   217  		{[]byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil},
   218  		{[]byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, nil},
   219  		{[]byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, nil},
   220  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, nil},
   221  		{[]byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, nil},
   222  		// Expected Failure -- not enough bytes
   223  		{[]byte{0x00, 0x00, 0x00}, int32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   224  
   225  		// uint32 - XDR Unsigned Integer
   226  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, nil},
   227  		{[]byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, nil},
   228  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, nil},
   229  		// Expected Failure -- not enough bytes
   230  		{[]byte{0x00, 0x00, 0x00}, uint32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   231  
   232  		// int64 - XDR Hyper Integer
   233  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, nil},
   234  		{[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, nil},
   235  		{[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, nil},
   236  		{[]byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, nil},
   237  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, nil},
   238  		{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, nil},
   239  		// Expected Failures -- not enough bytes
   240  		{[]byte{0x7f, 0xff, 0xff}, int64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   241  		{[]byte{0x7f, 0x00, 0xff, 0x00}, int64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   242  
   243  		// uint64 - XDR Unsigned Hyper Integer
   244  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, nil},
   245  		{[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, nil},
   246  		{[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, nil},
   247  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, nil},
   248  		{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, nil},
   249  		// Expected Failures -- not enough bytes
   250  		{[]byte{0xff, 0xff, 0xff}, uint64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   251  		{[]byte{0xff, 0x00, 0xff, 0x00}, uint64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   252  
   253  		// bool - XDR Integer
   254  		{[]byte{0x00, 0x00, 0x00, 0x00}, false, 4, nil},
   255  		{[]byte{0x00, 0x00, 0x00, 0x01}, true, 4, nil},
   256  		// Expected Failures -- only 0 or 1 is a valid bool
   257  		{[]byte{0x01, 0x00, 0x00, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   258  		{[]byte{0x00, 0x00, 0x40, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   259  
   260  		// float32 - XDR Floating-Point
   261  		{[]byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, nil},
   262  		{[]byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, nil},
   263  		{[]byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, nil},
   264  		{[]byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, nil},
   265  		{[]byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, nil},
   266  		// Expected Failures -- not enough bytes
   267  		{[]byte{0xff, 0xff}, float32(0), 2, &UnmarshalError{ErrorCode: ErrIO}},
   268  		{[]byte{0xff, 0x00, 0xff}, float32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   269  
   270  		// float64 - XDR Double-precision Floating-Point
   271  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, nil},
   272  		{[]byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, nil},
   273  		{[]byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, nil},
   274  		{[]byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, nil},
   275  		// Expected Failures -- not enough bytes
   276  		{[]byte{0xff, 0xff, 0xff}, float64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   277  		{[]byte{0xff, 0x00, 0xff, 0x00}, float64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   278  
   279  		// string - XDR String
   280  		{[]byte{0x00, 0x00, 0x00, 0x00}, "", 4, nil},
   281  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, nil},
   282  		{[]byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, nil},
   283  		// Expected Failures -- not enough bytes for length, length
   284  		// larger than allowed, and len larger than available bytes.
   285  		{[]byte{0x00, 0x00, 0xFF}, "", 3, &UnmarshalError{ErrorCode: ErrIO}},
   286  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   287  		{[]byte{0x00, 0x00, 0x00, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrIO}},
   288  
   289  		// []byte - XDR Variable Opaque
   290  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, nil},
   291  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, nil},
   292  		// Expected Failures -- not enough bytes for length, length
   293  		// larger than allowed, and data larger than available bytes.
   294  		{[]byte{0x00, 0x00, 0xFF}, []byte{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   295  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   296  		{[]byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   297  
   298  		// [#]byte - XDR Fixed Opaque
   299  		{[]byte{0x01, 0x00, 0x00, 0x00}, [1]byte{0x01}, 4, nil},
   300  		{[]byte{0x01, 0x02, 0x00, 0x00}, [2]byte{0x01, 0x02}, 4, nil},
   301  		{[]byte{0x01, 0x02, 0x03, 0x00}, [3]byte{0x01, 0x02, 0x03}, 4, nil},
   302  		{[]byte{0x01, 0x02, 0x03, 0x04}, [4]byte{0x01, 0x02, 0x03, 0x04}, 4, nil},
   303  		{[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, [5]byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, nil},
   304  		// Expected Failure -- fixed opaque data not padded
   305  		{[]byte{0x01}, [1]byte{}, 1, &UnmarshalError{ErrorCode: ErrIO}},
   306  
   307  		// []<type> - XDR Variable-Length Array
   308  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00},
   309  			[]int16{512, 1024, 2048}, 16, nil},
   310  		{[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, []bool{true, false}, 12, nil},
   311  		// Expected Failure -- 2 entries in array - not enough bytes
   312  		{[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, []bool{}, 8, &UnmarshalError{ErrorCode: ErrIO}},
   313  
   314  		// [#]<type> - XDR Fixed-Length Array
   315  		{[]byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00}, [2]uint32{512, 1024}, 8, nil},
   316  		// Expected Failure -- 2 entries in array - not enough bytes
   317  		{[]byte{0x00, 0x00, 0x00, 0x02}, [2]uint32{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   318  
   319  		// map[string]uint32
   320  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, 0x00, 0x00, 0x00, 0x01},
   321  			map[string]uint32{"map1": 1}, 16, nil},
   322  		// Expected Failures -- not enough bytes in length, 1 map
   323  		// element no extra bytes, 1 map element not enough bytes for
   324  		// key, 1 map element not enough bytes for value.
   325  		{[]byte{0x00, 0x00, 0x00}, map[string]uint32{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   326  		{[]byte{0x00, 0x00, 0x00, 0x01}, map[string]uint32{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   327  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, map[string]uint32{}, 7, &UnmarshalError{ErrorCode: ErrIO}},
   328  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31},
   329  			map[string]uint32{}, 12, &UnmarshalError{ErrorCode: ErrIO}},
   330  
   331  		// time.Time - XDR String per RFC3339
   332  		{[]byte{
   333  			0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
   334  			0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
   335  			0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a,
   336  		}, time.Unix(1396581888, 0).UTC(), 24, nil},
   337  		// Expected Failures -- not enough bytes, improperly formatted
   338  		// time
   339  		{[]byte{0x00, 0x00, 0x00}, time.Time{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   340  		{[]byte{0x00, 0x00, 0x00, 0x00}, time.Time{}, 4, &UnmarshalError{ErrorCode: ErrParseTime}},
   341  
   342  		// struct - XDR Structure -- test struct contains all supported types
   343  		{structTestIn, structTestWant, len(structTestIn), nil},
   344  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02},
   345  			opaqueStruct{[]uint8{1}, [1]uint8{2}}, 12, nil},
   346  		// Expected Failures -- normal struct not enough bytes, non
   347  		// opaque data not enough bytes for slice, non opaque data not
   348  		// enough bytes for slice.
   349  		{[]byte{0x00, 0x00}, allTypesTest{}, 2, &UnmarshalError{ErrorCode: ErrIO}},
   350  		{[]byte{0x00, 0x00, 0x00}, opaqueStruct{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   351  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00}, opaqueStruct{}, 5, &UnmarshalError{ErrorCode: ErrIO}},
   352  
   353  		// Expected errors
   354  		{nil, nilInterface, 0, &UnmarshalError{ErrorCode: ErrNilInterface}},
   355  		{nil, &nilInterface, 0, &UnmarshalError{ErrorCode: ErrNilInterface}},
   356  		{nil, testChan, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   357  		{nil, &testChan, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   358  		{nil, testFunc, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   359  		{nil, &testFunc, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   360  		{nil, testComplex64, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   361  		{nil, &testComplex64, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   362  		{nil, testComplex128, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   363  		{nil, &testComplex128, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   364  	}
   365  
   366  	for i, test := range tests {
   367  		// Attempt to unmarshal to a non-pointer version of each
   368  		// positive test type to ensure the appropriate error is
   369  		// returned.
   370  		if test.err == nil && test.wantVal != nil {
   371  			testName := fmt.Sprintf("Unmarshal #%d (non-pointer)", i)
   372  			wantErr := &UnmarshalError{ErrorCode: ErrBadArguments}
   373  
   374  			wvt := reflect.TypeOf(test.wantVal)
   375  			want := reflect.New(wvt).Elem().Interface()
   376  			n, err := Unmarshal(bytes.NewReader(test.in), want)
   377  			if !testExpectedURet(t, testName, n, 0, err, wantErr) {
   378  				continue
   379  			}
   380  		}
   381  
   382  		testName := fmt.Sprintf("Unmarshal #%d", i)
   383  		// Create a new pointer to the appropriate type.
   384  		var want interface{}
   385  		if test.wantVal != nil {
   386  			wvt := reflect.TypeOf(test.wantVal)
   387  			want = reflect.New(wvt).Interface()
   388  		}
   389  		n, err := Unmarshal(bytes.NewReader(test.in), want)
   390  
   391  		// First ensure the number of bytes read is the expected value
   392  		// and the error is the expected one.
   393  		if !testExpectedURet(t, testName, n, test.wantN, err, test.err) {
   394  			continue
   395  		}
   396  		if test.err != nil {
   397  			continue
   398  		}
   399  
   400  		// Finally, ensure the read value is the expected one.
   401  		wantElem := reflect.Indirect(reflect.ValueOf(want)).Interface()
   402  		if !reflect.DeepEqual(wantElem, test.wantVal) {
   403  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   404  				testName, wantElem, test.wantVal)
   405  			continue
   406  		}
   407  	}
   408  }
   409  
   410  // decodeFunc is used to identify which public function of the Decoder object
   411  // a test applies to.
   412  type decodeFunc int
   413  
   414  const (
   415  	fDecodeBool decodeFunc = iota
   416  	fDecodeDouble
   417  	fDecodeEnum
   418  	fDecodeFixedOpaque
   419  	fDecodeFloat
   420  	fDecodeHyper
   421  	fDecodeInt
   422  	fDecodeOpaque
   423  	fDecodeString
   424  	fDecodeUhyper
   425  	fDecodeUint
   426  )
   427  
   428  // Map of decodeFunc values to names for pretty printing.
   429  var decodeFuncStrings = map[decodeFunc]string{
   430  	fDecodeBool:        "DecodeBool",
   431  	fDecodeDouble:      "DecodeDouble",
   432  	fDecodeEnum:        "DecodeEnum",
   433  	fDecodeFixedOpaque: "DecodeFixedOpaque",
   434  	fDecodeFloat:       "DecodeFloat",
   435  	fDecodeHyper:       "DecodeHyper",
   436  	fDecodeInt:         "DecodeInt",
   437  	fDecodeOpaque:      "DecodeOpaque",
   438  	fDecodeString:      "DecodeString",
   439  	fDecodeUhyper:      "DecodeUhyper",
   440  	fDecodeUint:        "DecodeUint",
   441  }
   442  
   443  // String implements the fmt.Stringer interface and returns the encode function
   444  // as a human-readable string.
   445  func (f decodeFunc) String() string {
   446  	if s := decodeFuncStrings[f]; s != "" {
   447  		return s
   448  	}
   449  	return fmt.Sprintf("Unknown decodeFunc (%d)", f)
   450  }
   451  
   452  // TestDecoder ensures a Decoder works as intended.
   453  func TestDecoder(t *testing.T) {
   454  	tests := []struct {
   455  		f       decodeFunc  // function to use to decode
   456  		in      []byte      // input bytes
   457  		wantVal interface{} // expected value
   458  		wantN   int         // expected number of bytes read
   459  		err     error       // expected error
   460  	}{
   461  		// Bool
   462  		{fDecodeBool, []byte{0x00, 0x00, 0x00, 0x00}, false, 4, nil},
   463  		{fDecodeBool, []byte{0x00, 0x00, 0x00, 0x01}, true, 4, nil},
   464  		// Expected Failures -- only 0 or 1 is a valid bool
   465  		{fDecodeBool, []byte{0x01, 0x00, 0x00, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   466  		{fDecodeBool, []byte{0x00, 0x00, 0x40, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   467  
   468  		// Double
   469  		{fDecodeDouble, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, nil},
   470  		{fDecodeDouble, []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, nil},
   471  		{fDecodeDouble, []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, nil},
   472  		{fDecodeDouble, []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, nil},
   473  
   474  		// Enum
   475  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil},
   476  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x01}, int32(1), 4, nil},
   477  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x02}, nil, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   478  		{fDecodeEnum, []byte{0x12, 0x34, 0x56, 0x78}, nil, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   479  		{fDecodeEnum, []byte{0x00}, nil, 1, &UnmarshalError{ErrorCode: ErrIO}},
   480  
   481  		// FixedOpaque
   482  		{fDecodeFixedOpaque, []byte{0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 4, nil},
   483  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x00, 0x00}, []byte{0x01, 0x02}, 4, nil},
   484  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 4, nil},
   485  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 4, nil},
   486  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, nil},
   487  		// Expected Failure -- fixed opaque data not padded
   488  		{fDecodeFixedOpaque, []byte{0x01}, []byte{0x00}, 1, &UnmarshalError{ErrorCode: ErrIO}},
   489  
   490  		// Float
   491  		{fDecodeFloat, []byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, nil},
   492  		{fDecodeFloat, []byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, nil},
   493  		{fDecodeFloat, []byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, nil},
   494  		{fDecodeFloat, []byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, nil},
   495  		{fDecodeFloat, []byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, nil},
   496  
   497  		// Hyper
   498  		{fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, nil},
   499  		{fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, nil},
   500  		{fDecodeHyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, nil},
   501  		{fDecodeHyper, []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, nil},
   502  		{fDecodeHyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, nil},
   503  		{fDecodeHyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, nil},
   504  
   505  		// Int
   506  		{fDecodeInt, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil},
   507  		{fDecodeInt, []byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, nil},
   508  		{fDecodeInt, []byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, nil},
   509  		{fDecodeInt, []byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, nil},
   510  		{fDecodeInt, []byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, nil},
   511  
   512  		// Opaque
   513  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, nil},
   514  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, nil},
   515  		// Expected Failures -- not enough bytes for length, length
   516  		// larger than allowed, and data larger than available bytes.
   517  		{fDecodeOpaque, []byte{0x00, 0x00, 0xFF}, []byte{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   518  		{fDecodeOpaque, []byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   519  		{fDecodeOpaque, []byte{0x7F, 0xFF, 0xFF, 0xFD}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   520  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   521  
   522  		// String
   523  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x00}, "", 4, nil},
   524  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, nil},
   525  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, nil},
   526  		// Expected Failures -- not enough bytes for length, length
   527  		// larger than allowed, and len larger than available bytes.
   528  		{fDecodeString, []byte{0x00, 0x00, 0xFF}, "", 3, &UnmarshalError{ErrorCode: ErrIO}},
   529  		{fDecodeString, []byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   530  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrIO}},
   531  
   532  		// Uhyper
   533  		{fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, nil},
   534  		{fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, nil},
   535  		{fDecodeUhyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, nil},
   536  		{fDecodeUhyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, nil},
   537  		{fDecodeUhyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, nil},
   538  
   539  		// Uint
   540  		{fDecodeUint, []byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, nil},
   541  		{fDecodeUint, []byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, nil},
   542  		{fDecodeUint, []byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, nil},
   543  	}
   544  
   545  	validEnums := make(map[int32]bool)
   546  	validEnums[0] = true
   547  	validEnums[1] = true
   548  
   549  	var rv interface{}
   550  	var n int
   551  	var err error
   552  
   553  	for i, test := range tests {
   554  		err = nil
   555  		dec := NewDecoder(bytes.NewReader(test.in))
   556  		switch test.f {
   557  		case fDecodeBool:
   558  			rv, n, err = dec.DecodeBool()
   559  		case fDecodeDouble:
   560  			rv, n, err = dec.DecodeDouble()
   561  		case fDecodeEnum:
   562  			rv, n, err = dec.DecodeEnum(validEnums)
   563  		case fDecodeFixedOpaque:
   564  			want := test.wantVal.([]byte)
   565  			rv, n, err = dec.DecodeFixedOpaque(int32(len(want)))
   566  		case fDecodeFloat:
   567  			rv, n, err = dec.DecodeFloat()
   568  		case fDecodeHyper:
   569  			rv, n, err = dec.DecodeHyper()
   570  		case fDecodeInt:
   571  			rv, n, err = dec.DecodeInt()
   572  		case fDecodeOpaque:
   573  			rv, n, err = dec.DecodeOpaque()
   574  		case fDecodeString:
   575  			rv, n, err = dec.DecodeString()
   576  		case fDecodeUhyper:
   577  			rv, n, err = dec.DecodeUhyper()
   578  		case fDecodeUint:
   579  			rv, n, err = dec.DecodeUint()
   580  		default:
   581  			t.Errorf("%v #%d unrecognized function", test.f, i)
   582  			continue
   583  		}
   584  
   585  		// First ensure the number of bytes read is the expected value
   586  		// and the error is the expected one.
   587  		testName := fmt.Sprintf("%v #%d", test.f, i)
   588  		if !testExpectedURet(t, testName, n, test.wantN, err, test.err) {
   589  			continue
   590  		}
   591  		if test.err != nil {
   592  			continue
   593  		}
   594  
   595  		// Finally, ensure the read value is the expected one.
   596  		if !reflect.DeepEqual(rv, test.wantVal) {
   597  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   598  				testName, rv, test.wantVal)
   599  			continue
   600  		}
   601  	}
   602  }
   603  
   604  // TestUnmarshalCorners ensures the Unmarshal function properly handles various
   605  // cases not already covered by the other tests.
   606  func TestUnmarshalCorners(t *testing.T) {
   607  	buf := []byte{
   608  		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
   609  		0x00, 0x00, 0x00, 0x02,
   610  	}
   611  
   612  	// Ensure unmarshal to unsettable pointer returns the expected error.
   613  	testName := "Unmarshal to unsettable pointer"
   614  	var i32p *int32
   615  	expectedN := 0
   616  	expectedErr := error(&UnmarshalError{ErrorCode: ErrNotSettable})
   617  	n, err := Unmarshal(bytes.NewReader(buf), i32p)
   618  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   619  
   620  	// Ensure decode of unsettable pointer returns the expected error.
   621  	testName = "Decode to unsettable pointer"
   622  	expectedN = 0
   623  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   624  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(i32p))
   625  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   626  
   627  	// Ensure unmarshal to indirected unsettable pointer returns the
   628  	// expected error.
   629  	testName = "Unmarshal to indirected unsettable pointer"
   630  	ii32p := interface{}(i32p)
   631  	expectedN = 0
   632  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   633  	n, err = Unmarshal(bytes.NewReader(buf), &ii32p)
   634  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   635  
   636  	// Ensure unmarshal to embedded unsettable interface value returns the
   637  	// expected error.
   638  	testName = "Unmarshal to embedded unsettable interface value"
   639  	var i32 int32
   640  	ii32 := interface{}(i32)
   641  	expectedN = 0
   642  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   643  	n, err = Unmarshal(bytes.NewReader(buf), &ii32)
   644  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   645  
   646  	// Ensure unmarshal to embedded interface value works properly.
   647  	testName = "Unmarshal to embedded interface value"
   648  	ii32vp := interface{}(&i32)
   649  	expectedN = 4
   650  	expectedErr = nil
   651  	ii32vpr := int32(1)
   652  	expectedVal := interface{}(&ii32vpr)
   653  	n, err = Unmarshal(bytes.NewReader(buf), &ii32vp)
   654  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   655  		if !reflect.DeepEqual(ii32vp, expectedVal) {
   656  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   657  				testName, ii32vp, expectedVal)
   658  		}
   659  	}
   660  
   661  	// Ensure decode of an invalid reflect value returns the expected
   662  	// error.
   663  	testName = "Decode invalid reflect value"
   664  	expectedN = 0
   665  	expectedErr = error(&UnmarshalError{ErrorCode: ErrUnsupportedType})
   666  	n, err = TstDecode(bytes.NewReader(buf))(reflect.Value{})
   667  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   668  
   669  	// Ensure unmarshal to a slice with a cap and 0 length adjusts the
   670  	// length properly.
   671  	testName = "Unmarshal to capped slice"
   672  	cappedSlice := make([]bool, 0, 1)
   673  	expectedN = 8
   674  	expectedErr = nil
   675  	expectedVal = []bool{true}
   676  	n, err = Unmarshal(bytes.NewReader(buf), &cappedSlice)
   677  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   678  		if !reflect.DeepEqual(cappedSlice, expectedVal) {
   679  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   680  				testName, cappedSlice, expectedVal)
   681  		}
   682  	}
   683  
   684  	// Ensure unmarshal to struct with both exported and unexported fields
   685  	// skips the unexported fields but still unmarshals to the exported
   686  	// fields.
   687  	type unexportedStruct struct {
   688  		unexported int
   689  		Exported   int
   690  	}
   691  	testName = "Unmarshal to struct with exported and unexported fields"
   692  	var tstruct unexportedStruct
   693  	expectedN = 4
   694  	expectedErr = nil
   695  	expectedVal = unexportedStruct{0, 1}
   696  	n, err = Unmarshal(bytes.NewReader(buf), &tstruct)
   697  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   698  		if !reflect.DeepEqual(tstruct, expectedVal) {
   699  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   700  				testName, tstruct, expectedVal)
   701  		}
   702  	}
   703  
   704  	// Ensure decode to struct with unsettable fields return expected error.
   705  	type unsettableStruct struct {
   706  		Exported int
   707  	}
   708  	testName = "Decode to struct with unsettable fields"
   709  	var ustruct unsettableStruct
   710  	expectedN = 0
   711  	expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable})
   712  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(ustruct))
   713  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   714  
   715  	// Ensure decode to struct with unsettable pointer fields return
   716  	// expected error.
   717  	type unsettablePointerStruct struct {
   718  		Exported *int
   719  	}
   720  	testName = "Decode to struct with unsettable pointer fields"
   721  	var upstruct unsettablePointerStruct
   722  	expectedN = 0
   723  	expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable})
   724  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(upstruct))
   725  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   726  }