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 }