github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/utils/cser/binary_test.go (about) 1 package cser 2 3 import ( 4 "errors" 5 "math" 6 "math/big" 7 "math/rand" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/unicornultrafoundation/go-u2u/utils/fast" 13 ) 14 15 func TestEmpty(t *testing.T) { 16 var ( 17 buf []byte 18 err error 19 ) 20 21 t.Run("Write", func(t *testing.T) { 22 buf, err = MarshalBinaryAdapter(func(w *Writer) error { 23 return nil 24 }) 25 require.NoError(t, err) 26 }) 27 28 t.Run("Read", func(t *testing.T) { 29 err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { 30 return nil 31 }) 32 require.NoError(t, err) 33 }) 34 } 35 36 func TestErr(t *testing.T) { 37 var ( 38 buf []byte 39 ) 40 41 bufCopy := func() []byte { 42 bb := make([]byte, len(buf)) 43 copy(bb, buf) 44 return bb 45 } 46 47 t.Run("Write", func(t *testing.T) { 48 require := require.New(t) 49 50 bb, err := MarshalBinaryAdapter(func(w *Writer) error { 51 w.U64(math.MaxUint64) 52 return nil 53 }) 54 require.NoError(err) 55 buf = append(buf, bb...) 56 57 errExp := errors.New("custom") 58 bb, err = MarshalBinaryAdapter(func(w *Writer) error { 59 w.Bool(false) 60 return errExp 61 }) 62 require.Equal(errExp, err) 63 buf = append(buf, bb...) 64 }) 65 66 t.Run("Read nil", func(t *testing.T) { 67 require := require.New(t) 68 // nothing unmarshal 69 err := UnmarshalBinaryAdapter(nil, func(r *Reader) error { 70 return nil 71 }) 72 require.Equal(ErrMalformedEncoding, err) 73 }) 74 75 t.Run("Read err", func(t *testing.T) { 76 require := require.New(t) 77 78 errExp := errors.New("custom") 79 // unmarshal 80 err := UnmarshalBinaryAdapter(buf, func(r *Reader) error { 81 require.Equal(uint64(math.MaxUint64), r.U64()) 82 return errExp 83 }) 84 require.Equal(errExp, err) 85 }) 86 87 t.Run("Read 0", func(t *testing.T) { 88 require := require.New(t) 89 // unpack 90 _, bbytes, err := binaryToCSER(bufCopy()) 91 require.NoError(err) 92 // pack with wrong bits size 93 corrupted := fast.NewWriter(bbytes) 94 sizeWriter := fast.NewWriter(make([]byte, 0, 4)) 95 writeUint64Compact(sizeWriter, uint64(len(bbytes)+1)) 96 corrupted.Write(reversed(sizeWriter.Bytes())) 97 // corrupted unpack 98 _, _, err = binaryToCSER(corrupted.Bytes()) 99 require.Equal(ErrMalformedEncoding, err) 100 // corrupted unmarshal 101 err = UnmarshalBinaryAdapter(corrupted.Bytes(), func(r *Reader) error { 102 require.Equal(uint64(math.MaxUint64), r.U64()) 103 return nil 104 }) 105 require.Equal(ErrMalformedEncoding, err) 106 }) 107 108 repackWithDefect := func( 109 defect func(bbits, bbytes *[]byte) (expected error), 110 ) func(t *testing.T) { 111 return func(t *testing.T) { 112 require := require.New(t) 113 // unpack 114 bbits, bbytes, err := binaryToCSER(bufCopy()) 115 require.NoError(err) 116 // pack with defect 117 errExp := defect(&bbits.Bytes, &bbytes) 118 corrupted, err := binaryFromCSER(bbits, bbytes) 119 require.NoError(err) 120 // corrupted unmarshal 121 err = UnmarshalBinaryAdapter(corrupted, func(r *Reader) error { 122 _ = r.U64() 123 return nil 124 }) 125 require.Equal(errExp, err) 126 } 127 } 128 129 t.Run("Read 1", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { 130 // no defect 131 return nil 132 })) 133 134 t.Run("Read 2", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { 135 *bbytes = append(*bbytes, 0xFF) 136 return ErrNonCanonicalEncoding 137 })) 138 139 t.Run("Read 3", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { 140 *bbits = append(*bbits, 0x0F) 141 return ErrNonCanonicalEncoding 142 })) 143 144 t.Run("Read 4", repackWithDefect(func(bbits, bbytes *[]byte) (expected error) { 145 *bbytes = (*bbytes)[:len(*bbytes)-1] 146 return ErrNonCanonicalEncoding 147 })) 148 } 149 150 func TestVals(t *testing.T) { 151 var ( 152 buf []byte 153 err error 154 ) 155 var ( 156 expBigInt = []*big.Int{big.NewInt(0), big.NewInt(0xFFFFF)} 157 expBool = []bool{true, false} 158 expFixedBytes = [][]byte{[]byte{}, randBytes(0xFF)} 159 expSliceBytes = [][]byte{[]byte{}, randBytes(0xFF)} 160 expU8 = []uint8{0, 1, 0xFF} 161 expU16 = []uint16{0, 1, 0xFFFF} 162 expU32 = []uint32{0, 1, 0xFFFFFFFF} 163 expU64 = []uint64{0, 1, 0xFFFFFFFFFFFFFFFF} 164 expVarUint = []uint64{0, 1, 0xFFFFFFFFFFFFFFFF} 165 expI64 = []int64{0, 1, math.MinInt64, math.MaxInt64} 166 expU56 = []uint64{0, 1, 1<<(8*7) - 1} 167 ) 168 169 t.Run("Write", func(t *testing.T) { 170 require := require.New(t) 171 172 buf, err = MarshalBinaryAdapter(func(w *Writer) error { 173 for _, v := range expBigInt { 174 w.BigInt(v) 175 } 176 for _, v := range expBool { 177 w.Bool(v) 178 } 179 for _, v := range expFixedBytes { 180 w.FixedBytes(v) 181 } 182 for _, v := range expSliceBytes { 183 w.SliceBytes(v) 184 } 185 for _, v := range expU8 { 186 w.U8(v) 187 } 188 for _, v := range expU16 { 189 w.U16(v) 190 } 191 for _, v := range expU32 { 192 w.U32(v) 193 } 194 for _, v := range expU64 { 195 w.U64(v) 196 } 197 for _, v := range expVarUint { 198 w.VarUint(v) 199 } 200 for _, v := range expI64 { 201 w.I64(v) 202 } 203 for _, v := range expU56 { 204 w.U56(v) 205 } 206 return nil 207 }) 208 require.NoError(err) 209 }) 210 211 t.Run("Read", func(t *testing.T) { 212 require := require.New(t) 213 214 err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { 215 for i, exp := range expBigInt { 216 got := r.BigInt() 217 require.Equal(exp, got, i) 218 } 219 for i, exp := range expBool { 220 got := r.Bool() 221 require.Equal(exp, got, i) 222 } 223 for i, exp := range expFixedBytes { 224 got := make([]byte, len(exp)) 225 r.FixedBytes(got) 226 require.Equal(exp, got, i) 227 } 228 for i, exp := range expSliceBytes { 229 got := r.SliceBytes(255) 230 require.Equal(exp, got, i) 231 } 232 for i, exp := range expU8 { 233 got := r.U8() 234 require.Equal(exp, got, i) 235 } 236 for i, exp := range expU16 { 237 got := r.U16() 238 require.Equal(exp, got, i) 239 } 240 for i, exp := range expU32 { 241 got := r.U32() 242 require.Equal(exp, got, i) 243 } 244 for i, exp := range expU64 { 245 got := r.U64() 246 require.Equal(exp, got, i) 247 } 248 for i, exp := range expVarUint { 249 got := r.VarUint() 250 require.Equal(exp, got, i) 251 } 252 for i, exp := range expI64 { 253 got := r.I64() 254 require.Equal(exp, got, i) 255 } 256 for i, exp := range expU56 { 257 got := r.U56() 258 require.Equal(exp, got, i) 259 } 260 return nil 261 }) 262 require.NoError(err) 263 }) 264 } 265 266 func TestBadVals(t *testing.T) { 267 var ( 268 buf []byte 269 err error 270 ) 271 var ( 272 expBigInt = []*big.Int{nil} 273 expFixedBytes = [][]byte{nil} 274 expSliceBytes = [][]byte{nil} 275 expU56 = []uint64{1 << (8 * 7), math.MaxUint64} 276 ) 277 278 t.Run("Write", func(t *testing.T) { 279 require := require.New(t) 280 281 buf, err = MarshalBinaryAdapter(func(w *Writer) error { 282 for _, v := range expBigInt { 283 require.Panics(func() { 284 w.BigInt(v) 285 }) 286 } 287 for _, v := range expFixedBytes { 288 w.FixedBytes(v) 289 } 290 for _, v := range expSliceBytes { 291 w.SliceBytes(v) 292 } 293 for _, v := range expU56 { 294 require.Panics(func() { 295 w.U56(v) 296 }) 297 } 298 return nil 299 }) 300 require.NoError(err) 301 }) 302 303 t.Run("Read", func(t *testing.T) { 304 require := require.New(t) 305 306 err = UnmarshalBinaryAdapter(buf, func(r *Reader) error { 307 for _, _ = range expBigInt { 308 // skip 309 } 310 for i, exp := range expFixedBytes { 311 got := make([]byte, len(exp)) 312 r.FixedBytes(got) 313 require.NotEqual(exp, got, i) 314 require.Equal(len(exp), len(got), i) 315 } 316 for i, exp := range expSliceBytes { 317 got := r.SliceBytes(1) 318 require.NotEqual(exp, got, i) 319 require.Equal(len(exp), len(got), i) 320 } 321 for _, _ = range expU56 { 322 // skip 323 } 324 return nil 325 }) 326 require.NoError(err) 327 }) 328 } 329 330 func randBytes(n int) []byte { 331 bb := make([]byte, n) 332 _, err := rand.Read(bb) 333 if err != nil { 334 panic(err) 335 } 336 return bb 337 }