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  }