github.com/stellar/go-xdr@v0.0.0-20231122183749-b53fb00bcac2/xdr3/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 "encoding/base64" 22 "fmt" 23 "math" 24 "reflect" 25 "testing" 26 "time" 27 28 . "github.com/stellar/go-xdr/xdr3" 29 ) 30 31 // subTest is used to allow testing of the Unmarshal function into struct fields 32 // which are structs themselves. 33 type subTest struct { 34 A string 35 B uint8 36 } 37 38 // allTypesTest is used to allow testing of the Unmarshal function into struct 39 // fields of all supported types. 40 type allTypesTest struct { 41 A int8 42 B uint8 43 C int16 44 D uint16 45 E int32 46 F uint32 47 G int64 48 H uint64 49 I bool 50 J float32 51 K float64 52 L string 53 M []byte 54 N [3]byte 55 O []int16 56 P [2]subTest 57 Q subTest 58 R map[string]uint32 59 S time.Time 60 } 61 62 // opaqueStruct is used to test handling of uint8 slices and arrays. 63 type opaqueStruct struct { 64 Slice []uint8 `xdropaque:"false"` 65 Array [1]uint8 `xdropaque:"false"` 66 } 67 68 type AnEnum int32 69 70 func (e AnEnum) ValidEnum(v int32) bool { 71 return v < 3 72 } 73 74 type aUnion struct { 75 Type AnEnum 76 Data *int32 77 Text *string `xdrmaxsize:"28"` 78 } 79 80 func (u aUnion) SwitchFieldName() string { 81 return "Type" 82 } 83 84 func (u aUnion) ArmForSwitch(sw int32) (string, bool) { 85 switch sw { 86 case 0: 87 return "Data", true 88 case 1: 89 return "Text", true 90 case 2: // void 91 return "", true 92 } 93 94 return "-", false 95 } 96 97 type structWithPointer struct { 98 Data *string 99 } 100 101 // testExpectedURet is a convenience method to test an expected number of bytes 102 // read and error for an unmarshal. 103 func testExpectedURet(t *testing.T, name string, n, wantN int, err, wantErr error) bool { 104 // First ensure the number of bytes read is the expected value. The 105 // byes read should be accurate even when an error occurs. 106 if n != wantN { 107 t.Errorf("%s: unexpected num bytes read - got: %v want: %v\n", 108 name, n, wantN) 109 return false 110 } 111 112 // Next check for the expected error. 113 return assertError(t, name, err, wantErr) 114 } 115 116 func assertError(t *testing.T, name string, err, wantErr error) bool { 117 if reflect.TypeOf(err) != reflect.TypeOf(wantErr) { 118 t.Errorf("%s: failed to detect error - got: %v <%[2]T> want: %T", 119 name, err, wantErr) 120 return false 121 } 122 123 if rerr, ok := err.(*UnmarshalError); ok { 124 if werr, ok := wantErr.(*UnmarshalError); ok { 125 if rerr.ErrorCode != werr.ErrorCode { 126 t.Errorf("%s: failed to detect error code - "+ 127 "got: %v want: %v", name, 128 rerr.ErrorCode, werr.ErrorCode) 129 return false 130 } 131 } 132 } 133 134 return true 135 } 136 137 // TestUnmarshal ensures the Unmarshal function works properly with all types. 138 func TestUnmarshal(t *testing.T) { 139 // Variables for various unsupported Unmarshal types. 140 var nilInterface interface{} 141 var testChan chan int 142 var testFunc func() 143 var testComplex64 complex64 144 var testComplex128 complex128 145 146 // structTestIn is input data for the big struct test of all supported 147 // types. 148 structTestIn := []byte{ 149 0x00, 0x00, 0x00, 0x7F, // A 150 0x00, 0x00, 0x00, 0xFF, // B 151 0x00, 0x00, 0x7F, 0xFF, // C 152 0x00, 0x00, 0xFF, 0xFF, // D 153 0x7F, 0xFF, 0xFF, 0xFF, // E 154 0xFF, 0xFF, 0xFF, 0xFF, // F 155 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // G 156 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // H 157 0x00, 0x00, 0x00, 0x01, // I 158 0x40, 0x48, 0xF5, 0xC3, // J 159 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, // K 160 0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00, // L 161 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // M 162 0x01, 0x02, 0x03, 0x00, // N 163 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 164 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // O 165 0x00, 0x00, 0x00, 0x03, 0x6F, 0x6E, 0x65, 0x00, // P[0].A 166 0x00, 0x00, 0x00, 0x01, // P[0].B 167 0x00, 0x00, 0x00, 0x03, 0x74, 0x77, 0x6F, 0x00, // P[1].A 168 0x00, 0x00, 0x00, 0x02, // P[1].B 169 0x00, 0x00, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, // Q.A 170 0x00, 0x00, 0x00, 0x03, // Q.B 171 0x00, 0x00, 0x00, 0x02, // R length 172 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1 173 0x00, 0x00, 0x00, 0x01, // R value map1 174 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2 175 0x00, 0x00, 0x00, 0x02, // R value map2 176 0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34, 177 0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30, 178 0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, // S 179 } 180 181 // structTestWant is the expected output after unmarshalling 182 // structTestIn. 183 structTestWant := allTypesTest{ 184 127, // A 185 255, // B 186 32767, // C 187 65535, // D 188 2147483647, // E 189 4294967295, // F 190 9223372036854775807, // G 191 18446744073709551615, // H 192 true, // I 193 3.14, // J 194 3.141592653589793, // K 195 "xdr", // L 196 []byte{1, 2, 3, 4}, // M 197 [3]byte{1, 2, 3}, // N 198 []int16{512, 1024, 2048}, // O 199 [2]subTest{{"one", 1}, {"two", 2}}, // P 200 subTest{"bar", 3}, // Q 201 map[string]uint32{"map1": 1, "map2": 2}, // R 202 time.Unix(1396581888, 0).UTC(), // S 203 } 204 205 tests := []struct { 206 in []byte // input bytes 207 wantVal interface{} // expected value 208 wantN int // expected number of bytes read 209 err error // expected error 210 }{ 211 // int8 - XDR Integer 212 {[]byte{0x00, 0x00, 0x00, 0x00}, int8(0), 4, nil}, 213 {[]byte{0x00, 0x00, 0x00, 0x40}, int8(64), 4, nil}, 214 {[]byte{0x00, 0x00, 0x00, 0x7F}, int8(127), 4, nil}, 215 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int8(-1), 4, nil}, 216 {[]byte{0xFF, 0xFF, 0xFF, 0x80}, int8(-128), 4, nil}, 217 // Expected Failures -- 128, -129 overflow int8 and not enough 218 // bytes 219 {[]byte{0x00, 0x00, 0x00, 0x80}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 220 {[]byte{0xFF, 0xFF, 0xFF, 0x7F}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 221 {[]byte{0x00, 0x00, 0x00}, int8(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 222 223 // uint8 - XDR Unsigned Integer 224 {[]byte{0x00, 0x00, 0x00, 0x00}, uint8(0), 4, nil}, 225 {[]byte{0x00, 0x00, 0x00, 0x40}, uint8(64), 4, nil}, 226 {[]byte{0x00, 0x00, 0x00, 0xFF}, uint8(255), 4, nil}, 227 // Expected Failures -- 256, -1 overflow uint8 and not enough 228 // bytes 229 {[]byte{0x00, 0x00, 0x01, 0x00}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 230 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 231 {[]byte{0x00, 0x00, 0x00}, uint8(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 232 233 // int16 - XDR Integer 234 {[]byte{0x00, 0x00, 0x00, 0x00}, int16(0), 4, nil}, 235 {[]byte{0x00, 0x00, 0x04, 0x00}, int16(1024), 4, nil}, 236 {[]byte{0x00, 0x00, 0x7F, 0xFF}, int16(32767), 4, nil}, 237 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int16(-1), 4, nil}, 238 {[]byte{0xFF, 0xFF, 0x80, 0x00}, int16(-32768), 4, nil}, 239 // Expected Failures -- 32768, -32769 overflow int16 and not 240 // enough bytes 241 {[]byte{0x00, 0x00, 0x80, 0x00}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 242 {[]byte{0xFF, 0xFF, 0x7F, 0xFF}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 243 {[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 244 245 // uint16 - XDR Unsigned Integer 246 {[]byte{0x00, 0x00, 0x00, 0x00}, uint16(0), 4, nil}, 247 {[]byte{0x00, 0x00, 0x04, 0x00}, uint16(1024), 4, nil}, 248 {[]byte{0x00, 0x00, 0xFF, 0xFF}, uint16(65535), 4, nil}, 249 // Expected Failures -- 65536, -1 overflow uint16 and not enough 250 // bytes 251 {[]byte{0x00, 0x01, 0x00, 0x00}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 252 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 253 {[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 254 255 // int32 - XDR Integer 256 {[]byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil}, 257 {[]byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, nil}, 258 {[]byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, nil}, 259 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, nil}, 260 {[]byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, nil}, 261 // Expected Failure -- not enough bytes 262 {[]byte{0x00, 0x00, 0x00}, int32(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 263 264 // uint32 - XDR Unsigned Integer 265 {[]byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, nil}, 266 {[]byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, nil}, 267 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, nil}, 268 // Expected Failure -- not enough bytes 269 {[]byte{0x00, 0x00, 0x00}, uint32(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 270 271 // int64 - XDR Hyper Integer 272 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, nil}, 273 {[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, nil}, 274 {[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, nil}, 275 {[]byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, nil}, 276 {[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, nil}, 277 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, nil}, 278 // Expected Failures -- not enough bytes 279 {[]byte{0x7f, 0xff, 0xff}, int64(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 280 {[]byte{0x7f, 0x00, 0xff, 0x00}, int64(0), 4, &UnmarshalError{ErrorCode: ErrIO}}, 281 282 // uint64 - XDR Unsigned Hyper Integer 283 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, nil}, 284 {[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, nil}, 285 {[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, nil}, 286 {[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, nil}, 287 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, nil}, 288 // Expected Failures -- not enough bytes 289 {[]byte{0xff, 0xff, 0xff}, uint64(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 290 {[]byte{0xff, 0x00, 0xff, 0x00}, uint64(0), 4, &UnmarshalError{ErrorCode: ErrIO}}, 291 292 // bool - XDR Integer 293 {[]byte{0x00, 0x00, 0x00, 0x00}, false, 4, nil}, 294 {[]byte{0x00, 0x00, 0x00, 0x01}, true, 4, nil}, 295 // Expected Failures -- only 0 or 1 is a valid bool 296 {[]byte{0x01, 0x00, 0x00, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 297 {[]byte{0x00, 0x00, 0x40, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 298 299 // float32 - XDR Floating-Point 300 {[]byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, nil}, 301 {[]byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, nil}, 302 {[]byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, nil}, 303 {[]byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, nil}, 304 {[]byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, nil}, 305 // Expected Failures -- not enough bytes 306 {[]byte{0xff, 0xff}, float32(0), 2, &UnmarshalError{ErrorCode: ErrIO}}, 307 {[]byte{0xff, 0x00, 0xff}, float32(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 308 309 // float64 - XDR Double-precision Floating-Point 310 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, nil}, 311 {[]byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, nil}, 312 {[]byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, nil}, 313 {[]byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, nil}, 314 // Expected Failures -- not enough bytes 315 {[]byte{0xff, 0xff, 0xff}, float64(0), 3, &UnmarshalError{ErrorCode: ErrIO}}, 316 {[]byte{0xff, 0x00, 0xff, 0x00}, float64(0), 4, &UnmarshalError{ErrorCode: ErrIO}}, 317 318 // string - XDR String 319 {[]byte{0x00, 0x00, 0x00, 0x00}, "", 4, nil}, 320 {[]byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, nil}, 321 {[]byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, nil}, 322 // Expected Failures -- not enough bytes for length, length 323 // larger than allowed, and len larger than available bytes. 324 {[]byte{0x00, 0x00, 0xFF}, "", 3, &UnmarshalError{ErrorCode: ErrIO}}, 325 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 326 {[]byte{0x00, 0x00, 0x00, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrIO}}, 327 328 // []byte - XDR Variable Opaque 329 {[]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, nil}, 330 {[]byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, nil}, 331 // Expected Failures -- not enough bytes for length, length 332 // larger than allowed, and data larger than available bytes. 333 {[]byte{0x00, 0x00, 0xFF}, []byte{}, 3, &UnmarshalError{ErrorCode: ErrIO}}, 334 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 335 {[]byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrIO}}, 336 337 // [#]byte - XDR Fixed Opaque 338 {[]byte{0x01, 0x00, 0x00, 0x00}, [1]byte{0x01}, 4, nil}, 339 {[]byte{0x01, 0x02, 0x00, 0x00}, [2]byte{0x01, 0x02}, 4, nil}, 340 {[]byte{0x01, 0x02, 0x03, 0x00}, [3]byte{0x01, 0x02, 0x03}, 4, nil}, 341 {[]byte{0x01, 0x02, 0x03, 0x04}, [4]byte{0x01, 0x02, 0x03, 0x04}, 4, nil}, 342 {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, [5]byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, nil}, 343 // Expected Failure -- fixed opaque data not padded 344 {[]byte{0x01}, [1]byte{}, 1, &UnmarshalError{ErrorCode: ErrIO}}, 345 346 // []<type> - XDR Variable-Length Array 347 {[]byte{0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00}, 348 []int16{512, 1024, 2048}, 16, nil}, 349 {[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, []bool{true, false}, 12, nil}, 350 // Expected Failure -- 2 entries in array - not enough bytes 351 {[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, []bool{}, 8, &UnmarshalError{ErrorCode: ErrIO}}, 352 353 // [#]<type> - XDR Fixed-Length Array 354 {[]byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00}, [2]uint32{512, 1024}, 8, nil}, 355 // Expected Failure -- 2 entries in array - not enough bytes 356 {[]byte{0x00, 0x00, 0x00, 0x02}, [2]uint32{}, 4, &UnmarshalError{ErrorCode: ErrIO}}, 357 358 // map[string]uint32 359 {[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, 0x00, 0x00, 0x00, 0x01}, 360 map[string]uint32{"map1": 1}, 16, nil}, 361 // Expected Failures -- not enough bytes in length, 1 map 362 // element no extra bytes, 1 map element not enough bytes for 363 // key, 1 map element not enough bytes for value. 364 {[]byte{0x00, 0x00, 0x00}, map[string]uint32{}, 3, &UnmarshalError{ErrorCode: ErrIO}}, 365 {[]byte{0x00, 0x00, 0x00, 0x01}, map[string]uint32{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 366 {[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, map[string]uint32{}, 7, &UnmarshalError{ErrorCode: ErrIO}}, 367 {[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31}, 368 map[string]uint32{}, 12, &UnmarshalError{ErrorCode: ErrIO}}, 369 370 // time.Time - XDR String per RFC3339 371 {[]byte{ 372 0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34, 373 0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30, 374 0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, 375 }, time.Unix(1396581888, 0).UTC(), 24, nil}, 376 // Expected Failures -- not enough bytes, improperly formatted 377 // time 378 {[]byte{0x00, 0x00, 0x00}, time.Time{}, 3, &UnmarshalError{ErrorCode: ErrIO}}, 379 {[]byte{0x00, 0x00, 0x00, 0x00}, time.Time{}, 4, &UnmarshalError{ErrorCode: ErrParseTime}}, 380 381 // struct - XDR Structure -- test struct contains all supported types 382 {structTestIn, structTestWant, len(structTestIn), nil}, 383 {[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02}, 384 opaqueStruct{[]uint8{1}, [1]uint8{2}}, 12, nil}, 385 // Expected Failures -- normal struct not enough bytes, non 386 // opaque data not enough bytes for slice, non opaque data not 387 // enough bytes for slice. 388 {[]byte{0x00, 0x00}, allTypesTest{}, 2, &UnmarshalError{ErrorCode: ErrIO}}, 389 {[]byte{0x00, 0x00, 0x00}, opaqueStruct{}, 3, &UnmarshalError{ErrorCode: ErrIO}}, 390 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00}, opaqueStruct{}, 5, &UnmarshalError{ErrorCode: ErrIO}}, 391 392 // Expected errors 393 {nil, nilInterface, 0, &UnmarshalError{ErrorCode: ErrNilInterface}}, 394 {nil, &nilInterface, 0, &UnmarshalError{ErrorCode: ErrIO}}, 395 {nil, testChan, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}}, 396 {nil, &testChan, 0, &UnmarshalError{ErrorCode: ErrIO}}, 397 {nil, testFunc, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}}, 398 {nil, &testFunc, 0, &UnmarshalError{ErrorCode: ErrIO}}, 399 {nil, testComplex64, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}}, 400 {nil, &testComplex64, 0, &UnmarshalError{ErrorCode: ErrIO}}, 401 {nil, testComplex128, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}}, 402 {nil, &testComplex128, 0, &UnmarshalError{ErrorCode: ErrIO}}, 403 } 404 405 for i, test := range tests { 406 // Attempt to unmarshal to a non-pointer version of each 407 // positive test type to ensure the appropriate error is 408 // returned. 409 if test.err == nil && test.wantVal != nil { 410 testName := fmt.Sprintf("Unmarshal #%d (non-pointer)", i) 411 wantErr := &UnmarshalError{ErrorCode: ErrBadArguments} 412 413 wvt := reflect.TypeOf(test.wantVal) 414 want := reflect.New(wvt).Elem().Interface() 415 n, err := Unmarshal(bytes.NewReader(test.in), want) 416 if !testExpectedURet(t, testName, n, 0, err, wantErr) { 417 continue 418 } 419 } 420 421 testName := fmt.Sprintf("Unmarshal #%d", i) 422 // Create a new pointer to the appropriate type. 423 var want interface{} 424 if test.wantVal != nil { 425 wvt := reflect.TypeOf(test.wantVal) 426 want = reflect.New(wvt).Interface() 427 } 428 n, err := Unmarshal(bytes.NewReader(test.in), want) 429 430 // First ensure the number of bytes read is the expected value 431 // and the error is the expected one. 432 if !testExpectedURet(t, testName, n, test.wantN, err, test.err) { 433 continue 434 } 435 if test.err != nil { 436 continue 437 } 438 439 // Finally, ensure the read value is the expected one. 440 wantElem := reflect.Indirect(reflect.ValueOf(want)).Interface() 441 if !reflect.DeepEqual(wantElem, test.wantVal) { 442 t.Errorf("%s: unexpected result - got: %v want: %v\n", 443 testName, wantElem, test.wantVal) 444 continue 445 } 446 } 447 448 // successful enum decoding 449 var anEnum AnEnum 450 _, err := Unmarshal(bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x01}), &anEnum) 451 452 if err != nil { 453 t.Errorf("enum decode: expected no error, got: %v\n", err) 454 } 455 456 if anEnum != AnEnum(1) { 457 t.Errorf("enum decode: expected 1, got: %v\n", anEnum) 458 } 459 460 // failed enum decoding 461 _, err = Unmarshal(bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x03}), &anEnum) 462 463 if err == nil { 464 t.Errorf("enum decode: expected error, got none") 465 } 466 467 // union decoding 468 var u aUnion 469 // void arm 470 _, err = Unmarshal(bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x02}), &u) 471 if err != nil { 472 t.Errorf("union decode: expected no error, got: %v\n", err) 473 } 474 475 if u.Type != AnEnum(2) { 476 t.Errorf("union decode: expected type == 2, got: %v\n", u.Type) 477 } 478 479 if u.Data != nil { 480 t.Errorf("union decode: expected data to be nil, it was not.") 481 } 482 483 // non-void arm 484 _, err = Unmarshal(bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}), &u) 485 if err != nil { 486 t.Errorf("union decode: expected no error, got: %v\n", err) 487 } 488 489 if u.Type != AnEnum(0) { 490 t.Errorf("union decode: expected type == 0, got: %v\n", u.Type) 491 } 492 493 if u.Data == nil { 494 t.Errorf("union decode: expected data to be filled, it was not.") 495 } 496 497 if *u.Data != 5 { 498 t.Errorf("union decode: expected data to be 5, got: %v\n", *u.Data) 499 } 500 501 // non-void arm: xdrmaxsize 502 _, err = Unmarshal(bytes.NewReader([]byte{ 503 0x00, 0x00, 0x00, 0x01, // Text 504 0x00, 0x00, 0x00, 0x1D, // String length = 29 505 0x74, 0x65, 0x73, 0x74, // "test" 4 506 0x74, 0x65, 0x73, 0x74, // "test" 8 507 0x74, 0x65, 0x73, 0x74, // "test" 12 508 0x74, 0x65, 0x73, 0x74, // "test" 16 509 0x74, 0x65, 0x73, 0x74, // "test" 20 510 0x74, 0x65, 0x73, 0x74, // "test" 24 511 0x74, 0x65, 0x73, 0x74, // "test" 28 512 0x74, 0x00, 0x00, 0x00, // "test" 29 513 }), &u) 514 if err == nil { 515 t.Errorf("union decode: expected error") 516 } 517 518 if err.Error() != "xdr:DecodeString: data exceeds max slice limit - read: '29'" { 519 t.Errorf("union decode: expected 'data exceeds max slice limit' error") 520 } 521 522 // invalid enum for switch 523 _, err = Unmarshal(bytes.NewReader([]byte{0x00, 0x00, 0x00, 0x03}), &u) 524 if err == nil { 525 t.Errorf("union decode: expected error, got nil") 526 } 527 528 // invalid arm for switch 529 _, err = Unmarshal(bytes.NewReader([]byte{0xFF, 0xFF, 0xFF, 0xFF}), &u) 530 if err == nil { 531 t.Errorf("union decode: expected error, got nil") 532 } 533 } 534 535 // decodeFunc is used to identify which public function of the Decoder object 536 // a test applies to. 537 type decodeFunc int 538 539 const ( 540 fDecodeBool decodeFunc = iota 541 fDecodeDouble 542 fDecodeEnum 543 fDecodeFixedOpaque 544 fDecodeFloat 545 fDecodeHyper 546 fDecodeInt 547 fDecodeOpaque 548 fDecodeString 549 fDecodeUhyper 550 fDecodeUint 551 ) 552 553 // Map of decodeFunc values to names for pretty printing. 554 var decodeFuncStrings = map[decodeFunc]string{ 555 fDecodeBool: "DecodeBool", 556 fDecodeDouble: "DecodeDouble", 557 fDecodeEnum: "DecodeEnum", 558 fDecodeFixedOpaque: "DecodeFixedOpaque", 559 fDecodeFloat: "DecodeFloat", 560 fDecodeHyper: "DecodeHyper", 561 fDecodeInt: "DecodeInt", 562 fDecodeOpaque: "DecodeOpaque", 563 fDecodeString: "DecodeString", 564 fDecodeUhyper: "DecodeUhyper", 565 fDecodeUint: "DecodeUint", 566 } 567 568 // String implements the fmt.Stringer interface and returns the encode function 569 // as a human-readable string. 570 func (f decodeFunc) String() string { 571 if s := decodeFuncStrings[f]; s != "" { 572 return s 573 } 574 return fmt.Sprintf("Unknown decodeFunc (%d)", f) 575 } 576 577 // TestDecoder ensures a Decoder works as intended. 578 func TestDecoder(t *testing.T) { 579 tests := []struct { 580 f decodeFunc // function to use to decode 581 in []byte // input bytes 582 wantVal interface{} // expected value 583 wantN int // expected number of bytes read 584 err error // expected error 585 }{ 586 // Bool 587 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x00}, false, 4, nil}, 588 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x01}, true, 4, nil}, 589 // Expected Failures -- only 0 or 1 is a valid bool 590 {fDecodeBool, []byte{0x01, 0x00, 0x00, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 591 {fDecodeBool, []byte{0x00, 0x00, 0x40, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 592 593 // Double 594 {fDecodeDouble, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, nil}, 595 {fDecodeDouble, []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, nil}, 596 {fDecodeDouble, []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, nil}, 597 {fDecodeDouble, []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, nil}, 598 599 // Enum 600 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil}, 601 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x01}, int32(1), 4, nil}, 602 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x02}, nil, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 603 {fDecodeEnum, []byte{0x12, 0x34, 0x56, 0x78}, nil, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 604 {fDecodeEnum, []byte{0x00}, nil, 1, &UnmarshalError{ErrorCode: ErrIO}}, 605 606 // FixedOpaque 607 {fDecodeFixedOpaque, []byte{0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 4, nil}, 608 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x00, 0x00}, []byte{0x01, 0x02}, 4, nil}, 609 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 4, nil}, 610 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 4, nil}, 611 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, nil}, 612 // Expected Failure -- fixed opaque data not padded 613 {fDecodeFixedOpaque, []byte{0x01}, []byte{0x00}, 1, &UnmarshalError{ErrorCode: ErrIO}}, 614 615 // Float 616 {fDecodeFloat, []byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, nil}, 617 {fDecodeFloat, []byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, nil}, 618 {fDecodeFloat, []byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, nil}, 619 {fDecodeFloat, []byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, nil}, 620 {fDecodeFloat, []byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, nil}, 621 622 // Hyper 623 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, nil}, 624 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, nil}, 625 {fDecodeHyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, nil}, 626 {fDecodeHyper, []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, nil}, 627 {fDecodeHyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, nil}, 628 {fDecodeHyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, nil}, 629 630 // Int 631 {fDecodeInt, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil}, 632 {fDecodeInt, []byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, nil}, 633 {fDecodeInt, []byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, nil}, 634 {fDecodeInt, []byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, nil}, 635 {fDecodeInt, []byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, nil}, 636 637 // Opaque 638 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, nil}, 639 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, nil}, 640 // Expected Failures -- not enough bytes for length, length 641 // larger than allowed, and data larger than available bytes. 642 {fDecodeOpaque, []byte{0x00, 0x00, 0xFF}, []byte{}, 3, &UnmarshalError{ErrorCode: ErrIO}}, 643 {fDecodeOpaque, []byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 644 {fDecodeOpaque, []byte{0x7F, 0xFF, 0xFF, 0xFD}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 645 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrIO}}, 646 647 // String 648 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x00}, "", 4, nil}, 649 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, nil}, 650 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, nil}, 651 // Expected Failures -- not enough bytes for length, length 652 // larger than allowed, and len larger than available bytes. 653 {fDecodeString, []byte{0x00, 0x00, 0xFF}, "", 3, &UnmarshalError{ErrorCode: ErrIO}}, 654 {fDecodeString, []byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrOverflow}}, 655 {fDecodeString, []byte{0x00, 0x00, 0x00, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrIO}}, 656 657 // Uhyper 658 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, nil}, 659 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, nil}, 660 {fDecodeUhyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, nil}, 661 {fDecodeUhyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, nil}, 662 {fDecodeUhyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, nil}, 663 664 // Uint 665 {fDecodeUint, []byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, nil}, 666 {fDecodeUint, []byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, nil}, 667 {fDecodeUint, []byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, nil}, 668 } 669 670 validEnums := make(map[int32]bool) 671 validEnums[0] = true 672 validEnums[1] = true 673 674 var rv interface{} 675 var n int 676 var err error 677 678 for i, test := range tests { 679 err = nil 680 dec := NewDecoder(bytes.NewReader(test.in)) 681 switch test.f { 682 case fDecodeBool: 683 rv, n, err = dec.DecodeBool() 684 case fDecodeDouble: 685 rv, n, err = dec.DecodeDouble() 686 case fDecodeEnum: 687 rv, n, err = dec.DecodeEnum(validEnums) 688 case fDecodeFixedOpaque: 689 want := test.wantVal.([]byte) 690 rv, n, err = dec.DecodeFixedOpaque(int32(len(want))) 691 case fDecodeFloat: 692 rv, n, err = dec.DecodeFloat() 693 case fDecodeHyper: 694 rv, n, err = dec.DecodeHyper() 695 case fDecodeInt: 696 rv, n, err = dec.DecodeInt() 697 case fDecodeOpaque: 698 rv, n, err = dec.DecodeOpaque(0) 699 case fDecodeString: 700 rv, n, err = dec.DecodeString(0) 701 case fDecodeUhyper: 702 rv, n, err = dec.DecodeUhyper() 703 case fDecodeUint: 704 rv, n, err = dec.DecodeUint() 705 default: 706 t.Errorf("%v #%d unrecognized function", test.f, i) 707 continue 708 } 709 710 // First ensure the number of bytes read is the expected value 711 // and the error is the expected one. 712 testName := fmt.Sprintf("%v #%d", test.f, i) 713 if !testExpectedURet(t, testName, n, test.wantN, err, test.err) { 714 continue 715 } 716 if test.err != nil { 717 continue 718 } 719 720 // Finally, ensure the read value is the expected one. 721 if !reflect.DeepEqual(rv, test.wantVal) { 722 t.Errorf("%s: unexpected result - got: %v want: %v\n", 723 testName, rv, test.wantVal) 724 continue 725 } 726 } 727 } 728 729 // TestUnmarshalCorners ensures the Unmarshal function properly handles various 730 // cases not already covered by the other tests. 731 func TestUnmarshalCorners(t *testing.T) { 732 buf := []byte{ 733 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 734 0x00, 0x00, 0x00, 0x02, 735 } 736 737 // Ensure unmarshal to unsettable pointer returns the expected error. 738 testName := "Unmarshal to unsettable pointer" 739 var i32p *int32 740 expectedN := 0 741 expectedErr := error(&UnmarshalError{ErrorCode: ErrNotSettable}) 742 n, err := Unmarshal(bytes.NewReader(buf), i32p) 743 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 744 745 // Ensure decode of unsettable pointer returns the expected error. 746 testName = "Decode to unsettable pointer" 747 expectedN = 4 748 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 749 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(i32p), 0, DecodeDefaultMaxDepth) 750 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 751 752 // Ensure unmarshal to indirected unsettable pointer returns the 753 // expected error. 754 testName = "Unmarshal to indirected unsettable pointer" 755 ii32p := interface{}(i32p) 756 expectedN = 0 757 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 758 n, err = Unmarshal(bytes.NewReader(buf), &ii32p) 759 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 760 761 // Ensure unmarshal to embedded unsettable interface value returns the 762 // expected error. 763 testName = "Unmarshal to embedded unsettable interface value" 764 var i32 int32 765 ii32 := interface{}(i32) 766 expectedN = 0 767 expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable} 768 n, err = Unmarshal(bytes.NewReader(buf), &ii32) 769 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 770 771 // Ensure unmarshal to embedded interface value works properly. 772 testName = "Unmarshal to embedded interface value" 773 ii32vp := interface{}(&i32) 774 expectedN = 4 775 expectedErr = nil 776 ii32vpr := int32(1) 777 expectedVal := interface{}(&ii32vpr) 778 n, err = Unmarshal(bytes.NewReader(buf), &ii32vp) 779 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 780 if !reflect.DeepEqual(ii32vp, expectedVal) { 781 t.Errorf("%s: unexpected result - got: %v want: %v\n", 782 testName, ii32vp, expectedVal) 783 } 784 } 785 786 // Ensure decode of an invalid reflect value returns the expected 787 // error. 788 testName = "Decode invalid reflect value" 789 expectedN = 0 790 expectedErr = error(&UnmarshalError{ErrorCode: ErrUnsupportedType}) 791 n, err = TstDecode(bytes.NewReader(buf))(reflect.Value{}, 0, DecodeDefaultMaxDepth) 792 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 793 794 // Ensure unmarshal to a slice with a cap and 0 length adjusts the 795 // length properly. 796 testName = "Unmarshal to capped slice" 797 cappedSlice := make([]bool, 0, 1) 798 expectedN = 8 799 expectedErr = nil 800 expectedVal = []bool{true} 801 n, err = Unmarshal(bytes.NewReader(buf), &cappedSlice) 802 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 803 if !reflect.DeepEqual(cappedSlice, expectedVal) { 804 t.Errorf("%s: unexpected result - got: %v want: %v\n", 805 testName, cappedSlice, expectedVal) 806 } 807 } 808 809 // Ensure decode to a slice retuns expected number of elements 810 testName = "Unmarshal to oversized slice" 811 oversizedSlice := make([]bool, 2, 2) 812 expectedN = 8 813 expectedErr = nil 814 expectedVal = []bool{true} 815 n, err = Unmarshal(bytes.NewReader(buf), &oversizedSlice) 816 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 817 if !reflect.DeepEqual(oversizedSlice, expectedVal) { 818 t.Errorf("%s: unexpected result - got: %v want: %v\n", 819 testName, oversizedSlice, expectedVal) 820 } 821 } 822 823 // Ensure unmarshal to struct with both exported and unexported fields 824 // skips the unexported fields but still unmarshals to the exported 825 // fields. 826 type unexportedStruct struct { 827 unexported int 828 Exported int 829 } 830 testName = "Unmarshal to struct with exported and unexported fields" 831 var tstruct unexportedStruct 832 expectedN = 4 833 expectedErr = nil 834 expectedVal = unexportedStruct{0, 1} 835 n, err = Unmarshal(bytes.NewReader(buf), &tstruct) 836 if testExpectedURet(t, testName, n, expectedN, err, expectedErr) { 837 if !reflect.DeepEqual(tstruct, expectedVal) { 838 t.Errorf("%s: unexpected result - got: %v want: %v\n", 839 testName, tstruct, expectedVal) 840 } 841 } 842 843 // Ensure decode to struct with unsettable fields return expected error. 844 type unsettableStruct struct { 845 Exported int 846 } 847 testName = "Decode to struct with unsettable fields" 848 var ustruct unsettableStruct 849 expectedN = 0 850 expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable}) 851 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(ustruct), 0, DecodeDefaultMaxDepth) 852 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 853 854 // Ensure decode to struct with unsettable pointer fields return 855 // expected error. 856 type unsettablePointerStruct struct { 857 Exported *int 858 } 859 testName = "Decode to struct with unsettable pointer fields" 860 var upstruct unsettablePointerStruct 861 expectedN = 0 862 expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable}) 863 n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(upstruct), 0, DecodeDefaultMaxDepth) 864 testExpectedURet(t, testName, n, expectedN, err, expectedErr) 865 } 866 867 type String32 string 868 869 var _ Sized = String32("hello") 870 871 func (s String32) XDRMaxSize() int { 872 return 32 873 } 874 875 func TestSizedType(t *testing.T) { 876 cases := map[string]struct { 877 input []byte 878 out string 879 err error 880 }{ 881 // works for 0 length 882 "0 length": {[]byte{0x00, 0x00, 0x00, 0x00}, "", nil}, 883 // works for 1 length 884 "1 length": {[]byte{0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00}, "H", nil}, 885 // works for 32 length 886 "32 length": { 887 []byte{ 888 0x00, 0x00, 0x00, 0x20, 889 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 890 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 891 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 892 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 893 }, 894 "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", 895 nil, 896 }, 897 // fails for 33 length 898 "33 length": { 899 []byte{ 900 0x00, 0x00, 0x00, 0x21, 901 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 902 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 903 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 904 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 905 0x48, 0x00, 0x00, 0x00, 906 }, 907 "", 908 &UnmarshalError{ErrorCode: ErrOverflow}, 909 }, 910 } 911 912 for name, kase := range cases { 913 var out String32 914 r := bytes.NewReader(kase.input) 915 _, err := Unmarshal(r, &out) 916 917 if !assertError(t, name, err, kase.err) { 918 continue 919 } 920 921 if string(out) != kase.out { 922 t.Errorf("%s: expected output to be %#v, but got %#v", name, kase.out, out) 923 continue 924 } 925 } 926 } 927 928 type sizedField struct { 929 Val string `xdrmaxsize:"32"` 930 } 931 932 func TestSizedField(t *testing.T) { 933 cases := map[string]struct { 934 input []byte 935 out string 936 err error 937 }{ 938 // works for 0 length 939 "0 length": {[]byte{0x00, 0x00, 0x00, 0x00}, "", nil}, 940 // works for 1 length 941 "1 length": {[]byte{0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00}, "H", nil}, 942 // works for 32 length 943 "32 length": { 944 []byte{ 945 0x00, 0x00, 0x00, 0x20, 946 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 947 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 948 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 949 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 950 }, 951 "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", 952 nil, 953 }, 954 // fails for 33 length 955 "33 length": { 956 []byte{ 957 0x00, 0x00, 0x00, 0x21, 958 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 959 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 960 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 961 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 962 0x48, 0x00, 0x00, 0x00, 963 }, 964 "", 965 &UnmarshalError{ErrorCode: ErrOverflow}, 966 }, 967 } 968 969 for name, kase := range cases { 970 var out sizedField 971 r := bytes.NewReader(kase.input) 972 _, err := Unmarshal(r, &out) 973 974 if !assertError(t, name, err, kase.err) { 975 continue 976 } 977 978 if out.Val != kase.out { 979 t.Errorf("%s: expected output to be %#v, but got %#v", name, kase.out, out.Val) 980 continue 981 } 982 } 983 } 984 985 type defEnum int32 986 987 func (e defEnum) ValidEnum(v int32) bool { 988 return v < 1 989 } 990 991 type defUnion struct { 992 Type defEnum 993 Data *int32 994 } 995 996 func (u defUnion) SwitchFieldName() string { 997 return "Type" 998 } 999 1000 func (u defUnion) ArmForSwitch(sw int32) (string, bool) { 1001 switch sw { 1002 case 0: 1003 return "Data", true 1004 } 1005 1006 return "-", false 1007 } 1008 1009 func TestUnion_EnumValidation(t *testing.T) { 1010 1011 var u defUnion 1012 var buf bytes.Buffer 1013 1014 // encode a union with invalid value fails 1015 u.Type = defEnum(3) 1016 _, err := Marshal(&buf, u) 1017 1018 if err == nil { 1019 t.Errorf("expected error when marshaling invalid enum, got none. result: %#v", buf.Bytes()) 1020 } 1021 1022 // decoding an invalid enum value into a union results in an error 1023 u = defUnion{} 1024 invalid := []byte{0x0, 0x0, 0x0, 0x3} 1025 _, err = Unmarshal(bytes.NewReader(invalid), &u) 1026 if err == nil { 1027 t.Errorf("expected error when unmarshaling invalid enum into union, got none. result: %#v", u) 1028 } 1029 } 1030 1031 func TestPaddedReads(t *testing.T) { 1032 // regression test for non-zeroed padding 1033 1034 // opaque 1035 dec := NewDecoder(bytes.NewReader([]byte{0x0, 0x0, 0x1, 0x1})) 1036 _, _, err := dec.DecodeFixedOpaque(3) 1037 if err == nil { 1038 t.Error("expected error when unmarshaling opaque with non-zero padding byte, got none") 1039 } 1040 1041 // string 1042 dec = NewDecoder(bytes.NewReader([]byte{ 1043 0x0, 0x0, 0x0, 0x1, 1044 0x1, 0x1, 0x0, 0x0, 1045 })) 1046 _, _, err = dec.DecodeString(3) 1047 if err == nil { 1048 t.Error("expected error when unmarshaling string with non-zero padding byte, got none") 1049 } 1050 1051 // read varopaque 1052 dec = NewDecoder(bytes.NewReader([]byte{ 1053 0x0, 0x0, 0x0, 0x1, 1054 0x1, 0x0, 0x0, 0x1, 1055 })) 1056 _, _, err = dec.DecodeOpaque(3) 1057 if err == nil { 1058 t.Error("expected error when unmarshaling varopaque with non-zero padding byte, got none") 1059 } 1060 } 1061 1062 func TestDecodeNilPointerIntoExistingObjectWithNotNilPointer(t *testing.T) { 1063 var buf bytes.Buffer 1064 data := "data" 1065 _, err := Marshal(&buf, structWithPointer{Data: &data}) 1066 if err != nil { 1067 t.Error("unexpected error") 1068 } 1069 1070 var s structWithPointer 1071 _, err = Unmarshal(&buf, &s) 1072 if err != nil { 1073 t.Error("unexpected error") 1074 } 1075 1076 // Note: 1077 // 1. structWithPointer.Data is nil. 1078 // 2. We unmarshal into previously used object. 1079 _, err = Marshal(&buf, structWithPointer{}) 1080 if err != nil { 1081 t.Error("unexpected error") 1082 } 1083 1084 _, err = Unmarshal(&buf, &s) 1085 if err != nil { 1086 t.Error("unexpected error") 1087 } 1088 1089 if s.Data != nil { 1090 t.Error("Data should be nil") 1091 } 1092 } 1093 1094 func TestDecodeUnionIntoExistingObject(t *testing.T) { 1095 var buf bytes.Buffer 1096 var idata int32 = 1 1097 sdata := "data" 1098 _, err := Marshal(&buf, aUnion{ 1099 Type: 0, 1100 Data: &idata, 1101 }) 1102 if err != nil { 1103 t.Error("unexpected error") 1104 } 1105 1106 var s aUnion 1107 _, err = Unmarshal(&buf, &s) 1108 if err != nil { 1109 t.Error("unexpected error") 1110 } 1111 1112 _, err = Marshal(&buf, aUnion{ 1113 Type: 1, 1114 Text: &sdata, 1115 }) 1116 if err != nil { 1117 t.Error("unexpected error") 1118 } 1119 1120 _, err = Unmarshal(&buf, &s) 1121 if err != nil { 1122 t.Error("unexpected error") 1123 } 1124 1125 if s.Data != nil { 1126 t.Error("Data should be nil") 1127 } 1128 1129 if s.Type != 1 { 1130 t.Error("Type does not match") 1131 } 1132 1133 if *s.Text != sdata { 1134 t.Error("Text does not match") 1135 } 1136 } 1137 1138 func TestDecodeMaxDepth(t *testing.T) { 1139 var buf bytes.Buffer 1140 data := "data" 1141 _, err := Marshal(&buf, structWithPointer{Data: &data}) 1142 if err != nil { 1143 t.Error("unexpected error") 1144 } 1145 1146 bufCopy := buf 1147 decoder := NewDecoderWithOptions(&bufCopy, DecodeOptions{MaxDepth: 3}) 1148 var s structWithPointer 1149 _, err = decoder.Decode(&s) 1150 if err != nil { 1151 t.Error("unexpected error") 1152 } 1153 1154 bufCopy = buf 1155 decoder = NewDecoderWithOptions(&bufCopy, DecodeOptions{MaxDepth: 2}) 1156 _, err = decoder.Decode(&s) 1157 assertError(t, "", err, &UnmarshalError{ErrorCode: ErrMaxDecodingDepth}) 1158 } 1159 1160 func TestDecodeMaxAllocationCheck_ImplicitLenReader(t *testing.T) { 1161 var buf bytes.Buffer 1162 _, err := Marshal(&buf, "thisstringis23charslong") 1163 if err != nil { 1164 t.Error("unexpected error") 1165 } 1166 1167 // Reduce the buffer size so that the length of the buffer 1168 // is shorter than the encoded XDR length 1169 buf.Truncate(buf.Len() - 4) 1170 1171 decoder := NewDecoder(&buf) 1172 var s string 1173 _, err = decoder.Decode(&s) 1174 assertError(t, "", err, &UnmarshalError{ErrorCode: ErrOverflow}) 1175 } 1176 1177 func TestDecodeMaxAllocationCheck_ExplicitLenReader(t *testing.T) { 1178 var buf bytes.Buffer 1179 encoder := base64.NewEncoder(base64.StdEncoding, &buf) 1180 _, err := Marshal(encoder, "thisstringis23charslong") 1181 if err != nil { 1182 t.Error("unexpected error") 1183 } 1184 1185 xdrLen := base64.StdEncoding.DecodedLen(buf.Len()) 1186 // Reduce the buffer size so that the length of the buffer 1187 // is shorter than the encoded XDR length 1188 reducedLen := xdrLen - 4 1189 1190 decoder := NewDecoderWithOptions(&buf, DecodeOptions{MaxInputLen: reducedLen}) 1191 var s string 1192 _, err = decoder.Decode(&s) 1193 assertError(t, "", err, &UnmarshalError{ErrorCode: ErrOverflow}) 1194 }