github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/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/davecgh/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 type test 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 maxSize uint // read limiter value 460 err error // expected error 461 } 462 tests := []test{ 463 // Bool 464 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x00}, false, 4, 0, nil}, 465 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x01}, true, 4, 0, nil}, 466 // Expected Failures -- only 0 or 1 is a valid bool 467 {fDecodeBool, []byte{0x01, 0x00, 0x00, 0x00}, true, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 468 {fDecodeBool, []byte{0x00, 0x00, 0x40, 0x00}, true, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 469 470 // Double 471 {fDecodeDouble, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, 0, nil}, 472 {fDecodeDouble, []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, 0, nil}, 473 {fDecodeDouble, []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, 0, nil}, 474 {fDecodeDouble, []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, 0, nil}, 475 476 // Enum 477 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, 0, nil}, 478 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x01}, int32(1), 4, 0, nil}, 479 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x02}, nil, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 480 {fDecodeEnum, []byte{0x12, 0x34, 0x56, 0x78}, nil, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 481 {fDecodeEnum, []byte{0x00}, nil, 1, 0, &UnmarshalError{ErrorCode: ErrIO}}, 482 483 // FixedOpaque 484 {fDecodeFixedOpaque, []byte{0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 4, 0, nil}, 485 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x00, 0x00}, []byte{0x01, 0x02}, 4, 0, nil}, 486 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 4, 0, nil}, 487 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 4, 0, nil}, 488 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, 0, nil}, 489 // Expected Failure -- fixed opaque data not padded 490 {fDecodeFixedOpaque, []byte{0x01}, []byte{0x00}, 1, 0, &UnmarshalError{ErrorCode: ErrIO}}, 491 492 // Float 493 {fDecodeFloat, []byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, 0, nil}, 494 {fDecodeFloat, []byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, 0, nil}, 495 {fDecodeFloat, []byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, 0, nil}, 496 {fDecodeFloat, []byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, 0, nil}, 497 {fDecodeFloat, []byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, 0, nil}, 498 499 // Hyper 500 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, 0, nil}, 501 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, 0, nil}, 502 {fDecodeHyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, 0, nil}, 503 {fDecodeHyper, []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, 0, nil}, 504 {fDecodeHyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, 0, nil}, 505 {fDecodeHyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, 0, nil}, 506 507 // Int 508 {fDecodeInt, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, 0, nil}, 509 {fDecodeInt, []byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, 0, nil}, 510 {fDecodeInt, []byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, 0, nil}, 511 {fDecodeInt, []byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, 0, nil}, 512 {fDecodeInt, []byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, 0, nil}, 513 514 // Opaque 515 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, 0, nil}, 516 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, 0, nil}, 517 // Expected Failures -- not enough bytes for length, length 518 // larger than allowed, and data larger than available bytes. 519 {fDecodeOpaque, []byte{0x00, 0x00, 0xFF}, []byte{}, 3, 0, &UnmarshalError{ErrorCode: ErrIO}}, 520 {fDecodeOpaque, []byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}}, 521 {fDecodeOpaque, []byte{0x7F, 0xFF, 0xFF, 0xFD}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}}, 522 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrIO}}, 523 // Hit maxReadSize in opaque 524 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, 4, nil}, 525 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00}, []byte{}, 4, 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 526 527 // String 528 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x00}, "", 4, 0, nil}, 529 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, 0, nil}, 530 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, 0, nil}, 531 // Expected Failures -- not enough bytes for length, length 532 // larger than allowed, and len larger than available bytes. 533 {fDecodeString, []byte{0x00, 0x00, 0xFF}, "", 3, 0, &UnmarshalError{ErrorCode: ErrIO}}, 534 {fDecodeString, []byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}}, 535 {fDecodeString, []byte{0x00, 0x00, 0x00, 0xFF}, "", 4, 0, &UnmarshalError{ErrorCode: ErrIO}}, 536 // Hit maxReadSize in string 537 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, 4, nil}, 538 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 4, 2, &UnmarshalError{ErrorCode: ErrOverflow}}, 539 540 // Uhyper 541 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, 0, nil}, 542 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, 0, nil}, 543 {fDecodeUhyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, 0, nil}, 544 {fDecodeUhyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, 0, nil}, 545 {fDecodeUhyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, 0, nil}, 546 547 // Uint 548 {fDecodeUint, []byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, 0, nil}, 549 {fDecodeUint, []byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, 0, nil}, 550 {fDecodeUint, []byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, 0, nil}, 551 } 552 553 validEnums := make(map[int32]bool) 554 validEnums[0] = true 555 validEnums[1] = true 556 557 var rv interface{} 558 var n int 559 var err error 560 561 decoders := []func(test) *Decoder{ 562 func(t test) *Decoder { 563 // return DecoderLimited for test cases that can't succeed. 564 if t.maxSize == 0 { 565 return NewDecoder(bytes.NewReader(t.in)) 566 } 567 return NewDecoderLimited(bytes.NewReader(t.in), t.maxSize) 568 }, 569 func(t test) *Decoder { 570 return NewDecoderLimited(bytes.NewReader(t.in), t.maxSize) 571 }, 572 } 573 for _, decoder := range decoders { 574 for i, test := range tests { 575 err = nil 576 var dec *Decoder 577 dec = decoder(test) 578 switch test.f { 579 case fDecodeBool: 580 rv, n, err = dec.DecodeBool() 581 case fDecodeDouble: 582 rv, n, err = dec.DecodeDouble() 583 case fDecodeEnum: 584 rv, n, err = dec.DecodeEnum(validEnums) 585 case fDecodeFixedOpaque: 586 want := test.wantVal.([]byte) 587 rv, n, err = dec.DecodeFixedOpaque(int32(len(want))) 588 case fDecodeFloat: 589 rv, n, err = dec.DecodeFloat() 590 case fDecodeHyper: 591 rv, n, err = dec.DecodeHyper() 592 case fDecodeInt: 593 rv, n, err = dec.DecodeInt() 594 case fDecodeOpaque: 595 rv, n, err = dec.DecodeOpaque() 596 case fDecodeString: 597 rv, n, err = dec.DecodeString() 598 case fDecodeUhyper: 599 rv, n, err = dec.DecodeUhyper() 600 case fDecodeUint: 601 rv, n, err = dec.DecodeUint() 602 default: 603 t.Errorf("%v #%d unrecognized function", test.f, i) 604 continue 605 } 606 607 // First ensure the number of bytes read is the expected value 608 // and the error is the expected one. 609 testName := fmt.Sprintf("%v #%d", test.f, i) 610 if !testExpectedURet(t, testName, n, test.wantN, err, test.err) { 611 continue 612 } 613 if test.err != nil { 614 continue 615 } 616 617 // Finally, ensure the read value is the expected one. 618 if !reflect.DeepEqual(rv, test.wantVal) { 619 t.Errorf("%s: unexpected result - got: %v want: %v\n", 620 testName, rv, test.wantVal) 621 continue 622 } 623 } 624 } 625 } 626 627 // TestUnmarshalLimited ensures the UnmarshalLimited function properly handles 628 // various cases not already covered by the other tests. 629 func TestUnmarshalLimited(t *testing.T) { 630 buf := []byte{ 631 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 632 0x00, 0x00, 0x00, 0x02, 633 } 634 635 testName := "UnmarshalLimited to capped slice" 636 cappedSlice := make([]bool, 0, 1) 637 expectedN := 8 638 expectedErr := error(nil) 639 expectedVal := []bool{true} 640 n, err := UnmarshalLimited(bytes.NewReader(buf), &cappedSlice, 8) 641 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 642 if !reflect.DeepEqual(cappedSlice, expectedVal) { 643 t.Errorf("%s: unexpected result - got: %v want: %v\n", 644 testName, cappedSlice, expectedVal) 645 } 646 } 647 648 // Positive map test. 649 buf = []byte{ 650 0x00, 0x00, 0x00, 0x02, // R length 651 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1 652 0x00, 0x00, 0x00, 0x01, // R value map1 653 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2 654 0x00, 0x00, 0x00, 0x02, // R value map2 655 } 656 type myMap struct { 657 R map[string]uint32 658 } 659 expectedMapVal := &myMap{ 660 R: map[string]uint32{"map1": 1, "map2": 2}, // R 661 } 662 var m myMap 663 n, err = UnmarshalLimited(bytes.NewReader(buf), &m, 28) 664 expectedN = 28 665 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 666 if !reflect.DeepEqual(&m, expectedMapVal) { 667 t.Errorf("%s: unexpected result - got: %v want: %v\n", 668 testName, m, expectedMapVal) 669 } 670 } 671 } 672 673 // TestUnmarshalCorners ensures the Unmarshal function properly handles various 674 // cases not already covered by the other tests. 675 func TestUnmarshalCorners(t *testing.T) { 676 buf := []byte{ 677 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 678 0x00, 0x00, 0x00, 0x02, 679 } 680 681 // Ensure unmarshal to unsettable pointer returns the expected error. 682 testName := "Unmarshal to unsettable pointer" 683 var i32p *int32 684 expectedN := 0 685 expectedErr := error(&UnmarshalError{ErrorCode: ErrNotSettable}) 686 n, err := Unmarshal(bytes.NewReader(buf), i32p) 687 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 688 689 // Ensure decode of unsettable pointer returns the expected error. 690 testName = "Decode to unsettable pointer" 691 expectedN = 0 692 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 693 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(i32p)) 694 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 695 696 // Ensure unmarshal to indirected unsettable pointer returns the 697 // expected error. 698 testName = "Unmarshal to indirected unsettable pointer" 699 ii32p := interface{}(i32p) 700 expectedN = 0 701 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 702 n, err = Unmarshal(bytes.NewReader(buf), &ii32p) 703 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 704 705 // Ensure unmarshal to embedded unsettable interface value returns the 706 // expected error. 707 testName = "Unmarshal to embedded unsettable interface value" 708 var i32 int32 709 ii32 := interface{}(i32) 710 expectedN = 0 711 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 712 n, err = Unmarshal(bytes.NewReader(buf), &ii32) 713 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 714 715 // Ensure unmarshal to embedded interface value works properly. 716 testName = "Unmarshal to embedded interface value" 717 ii32vp := interface{}(&i32) 718 expectedN = 4 719 expectedErr = nil 720 ii32vpr := int32(1) 721 expectedVal := interface{}(&ii32vpr) 722 n, err = Unmarshal(bytes.NewReader(buf), &ii32vp) 723 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 724 if !reflect.DeepEqual(ii32vp, expectedVal) { 725 t.Errorf("%s: unexpected result - got: %v want: %v\n", 726 testName, ii32vp, expectedVal) 727 } 728 } 729 730 // Ensure decode of an invalid reflect value returns the expected 731 // error. 732 testName = "Decode invalid reflect value" 733 expectedN = 0 734 expectedErr = error(&UnmarshalError{ErrorCode: ErrUnsupportedType}) 735 n, err = TstDecode(bytes.NewReader(buf))(reflect.Value{}) 736 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 737 738 // Ensure unmarshal to a slice with a cap and 0 length adjusts the 739 // length properly. 740 testName = "Unmarshal to capped slice" 741 cappedSlice := make([]bool, 0, 1) 742 expectedN = 8 743 expectedErr = nil 744 expectedVal = []bool{true} 745 n, err = Unmarshal(bytes.NewReader(buf), &cappedSlice) 746 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 747 if !reflect.DeepEqual(cappedSlice, expectedVal) { 748 t.Errorf("%s: unexpected result - got: %v want: %v\n", 749 testName, cappedSlice, expectedVal) 750 } 751 } 752 753 // Ensure unmarshal to struct with both exported and unexported fields 754 // skips the unexported fields but still unmarshals to the exported 755 // fields. 756 type unexportedStruct struct { 757 unexported int 758 Exported int 759 } 760 testName = "Unmarshal to struct with exported and unexported fields" 761 var tstruct unexportedStruct 762 expectedN = 4 763 expectedErr = nil 764 expectedVal = unexportedStruct{0, 1} 765 n, err = Unmarshal(bytes.NewReader(buf), &tstruct) 766 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 767 if !reflect.DeepEqual(tstruct, expectedVal) { 768 t.Errorf("%s: unexpected result - got: %v want: %v\n", 769 testName, tstruct, expectedVal) 770 } 771 } 772 773 // Ensure decode to struct with unsettable fields return expected error. 774 type unsettableStruct struct { 775 Exported int 776 } 777 testName = "Decode to struct with unsettable fields" 778 var ustruct unsettableStruct 779 expectedN = 0 780 expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable}) 781 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(ustruct)) 782 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 783 784 // Ensure decode to struct with unsettable pointer fields return 785 // expected error. 786 type unsettablePointerStruct struct { 787 Exported *int 788 } 789 testName = "Decode to struct with unsettable pointer fields" 790 var upstruct unsettablePointerStruct 791 expectedN = 0 792 expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable}) 793 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(upstruct)) 794 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 795 }