wa-lang.org/wazero@v1.0.2/imports/wasi_snapshot_preview1/args_test.go (about)

     1  package wasi_snapshot_preview1
     2  
     3  import (
     4  	"testing"
     5  
     6  	"wa-lang.org/wazero"
     7  	"wa-lang.org/wazero/internal/testing/require"
     8  )
     9  
    10  func Test_argsGet(t *testing.T) {
    11  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
    12  	defer r.Close(testCtx)
    13  
    14  	argv := uint32(7)    // arbitrary offset
    15  	argvBuf := uint32(1) // arbitrary offset
    16  	expectedMemory := []byte{
    17  		'?',                 // argvBuf is after this
    18  		'a', 0, 'b', 'c', 0, // null terminated "a", "bc"
    19  		'?',        // argv is after this
    20  		1, 0, 0, 0, // little endian-encoded offset of "a"
    21  		3, 0, 0, 0, // little endian-encoded offset of "bc"
    22  		'?', // stopped after encoding
    23  	}
    24  
    25  	maskMemory(t, testCtx, mod, len(expectedMemory))
    26  
    27  	// Invoke argsGet and check the memory side effects.
    28  	requireErrno(t, ErrnoSuccess, mod, functionArgsGet, uint64(argv), uint64(argvBuf))
    29  	require.Equal(t, `
    30  --> proxy.args_get(argv=7,argv_buf=1)
    31  	==> wasi_snapshot_preview1.args_get(argv=7,argv_buf=1)
    32  	<== ESUCCESS
    33  <-- (0)
    34  `, "\n"+log.String())
    35  
    36  	actual, ok := mod.Memory().Read(testCtx, 0, uint32(len(expectedMemory)))
    37  	require.True(t, ok)
    38  	require.Equal(t, expectedMemory, actual)
    39  }
    40  
    41  func Test_argsGet_Errors(t *testing.T) {
    42  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
    43  	defer r.Close(testCtx)
    44  
    45  	memorySize := mod.Memory().Size(testCtx)
    46  	validAddress := uint32(0) // arbitrary valid address as arguments to args_get. We chose 0 here.
    47  
    48  	tests := []struct {
    49  		name          string
    50  		argv, argvBuf uint32
    51  		expectedLog   string
    52  	}{
    53  		{
    54  			name:    "out-of-memory argv",
    55  			argv:    memorySize,
    56  			argvBuf: validAddress,
    57  			expectedLog: `
    58  --> proxy.args_get(argv=65536,argv_buf=0)
    59  	==> wasi_snapshot_preview1.args_get(argv=65536,argv_buf=0)
    60  	<== EFAULT
    61  <-- (21)
    62  `,
    63  		},
    64  		{
    65  			name:    "out-of-memory argvBuf",
    66  			argv:    validAddress,
    67  			argvBuf: memorySize,
    68  			expectedLog: `
    69  --> proxy.args_get(argv=0,argv_buf=65536)
    70  	==> wasi_snapshot_preview1.args_get(argv=0,argv_buf=65536)
    71  	<== EFAULT
    72  <-- (21)
    73  `,
    74  		},
    75  		{
    76  			name: "argv exceeds the maximum valid address by 1",
    77  			// 4*argCount is the size of the result of the pointers to args, 4 is the size of uint32
    78  			argv:    memorySize - 4*2 + 1,
    79  			argvBuf: validAddress,
    80  			expectedLog: `
    81  --> proxy.args_get(argv=65529,argv_buf=0)
    82  	==> wasi_snapshot_preview1.args_get(argv=65529,argv_buf=0)
    83  	<== EFAULT
    84  <-- (21)
    85  `,
    86  		},
    87  		{
    88  			name: "argvBuf exceeds the maximum valid address by 1",
    89  			argv: validAddress,
    90  			// "a", "bc" size = size of "a0bc0" = 5
    91  			argvBuf: memorySize - 5 + 1,
    92  			expectedLog: `
    93  --> proxy.args_get(argv=0,argv_buf=65532)
    94  	==> wasi_snapshot_preview1.args_get(argv=0,argv_buf=65532)
    95  	<== EFAULT
    96  <-- (21)
    97  `,
    98  		},
    99  	}
   100  
   101  	for _, tt := range tests {
   102  		tc := tt
   103  
   104  		t.Run(tc.name, func(t *testing.T) {
   105  			defer log.Reset()
   106  
   107  			requireErrno(t, ErrnoFault, mod, functionArgsGet, uint64(tc.argv), uint64(tc.argvBuf))
   108  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   109  		})
   110  	}
   111  }
   112  
   113  func Test_argsSizesGet(t *testing.T) {
   114  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
   115  	defer r.Close(testCtx)
   116  
   117  	resultArgc := uint32(1)    // arbitrary offset
   118  	resultArgvLen := uint32(6) // arbitrary offset
   119  	expectedMemory := []byte{
   120  		'?',                // resultArgc is after this
   121  		0x2, 0x0, 0x0, 0x0, // little endian-encoded arg count
   122  		'?',                // resultArgvLen is after this
   123  		0x5, 0x0, 0x0, 0x0, // little endian-encoded size of null terminated strings
   124  		'?', // stopped after encoding
   125  	}
   126  
   127  	maskMemory(t, testCtx, mod, len(expectedMemory))
   128  
   129  	// Invoke argsSizesGet and check the memory side effects.
   130  	requireErrno(t, ErrnoSuccess, mod, functionArgsSizesGet, uint64(resultArgc), uint64(resultArgvLen))
   131  	require.Equal(t, `
   132  --> proxy.args_sizes_get(result.argc=1,result.argv_len=6)
   133  	==> wasi_snapshot_preview1.args_sizes_get(result.argc=1,result.argv_len=6)
   134  	<== ESUCCESS
   135  <-- (0)
   136  `, "\n"+log.String())
   137  
   138  	actual, ok := mod.Memory().Read(testCtx, 0, uint32(len(expectedMemory)))
   139  	require.True(t, ok)
   140  	require.Equal(t, expectedMemory, actual)
   141  }
   142  
   143  func Test_argsSizesGet_Errors(t *testing.T) {
   144  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
   145  	defer r.Close(testCtx)
   146  
   147  	memorySize := mod.Memory().Size(testCtx)
   148  	validAddress := uint32(0) // arbitrary valid address as arguments to args_sizes_get. We chose 0 here.
   149  
   150  	tests := []struct {
   151  		name          string
   152  		argc, argvLen uint32
   153  		expectedLog   string
   154  	}{
   155  		{
   156  			name:    "out-of-memory argc",
   157  			argc:    memorySize,
   158  			argvLen: validAddress,
   159  			expectedLog: `
   160  --> proxy.args_sizes_get(result.argc=65536,result.argv_len=0)
   161  	==> wasi_snapshot_preview1.args_sizes_get(result.argc=65536,result.argv_len=0)
   162  	<== EFAULT
   163  <-- (21)
   164  `,
   165  		},
   166  		{
   167  			name:    "out-of-memory argvLen",
   168  			argc:    validAddress,
   169  			argvLen: memorySize,
   170  			expectedLog: `
   171  --> proxy.args_sizes_get(result.argc=0,result.argv_len=65536)
   172  	==> wasi_snapshot_preview1.args_sizes_get(result.argc=0,result.argv_len=65536)
   173  	<== EFAULT
   174  <-- (21)
   175  `,
   176  		},
   177  		{
   178  			name:    "argc exceeds the maximum valid address by 1",
   179  			argc:    memorySize - 4 + 1, // 4 is the size of uint32, the type of the count of args
   180  			argvLen: validAddress,
   181  			expectedLog: `
   182  --> proxy.args_sizes_get(result.argc=65533,result.argv_len=0)
   183  	==> wasi_snapshot_preview1.args_sizes_get(result.argc=65533,result.argv_len=0)
   184  	<== EFAULT
   185  <-- (21)
   186  `,
   187  		},
   188  		{
   189  			name:    "argvLen exceeds the maximum valid size by 1",
   190  			argc:    validAddress,
   191  			argvLen: memorySize - 4 + 1, // 4 is count of bytes to encode uint32le
   192  			expectedLog: `
   193  --> proxy.args_sizes_get(result.argc=0,result.argv_len=65533)
   194  	==> wasi_snapshot_preview1.args_sizes_get(result.argc=0,result.argv_len=65533)
   195  	<== EFAULT
   196  <-- (21)
   197  `,
   198  		},
   199  	}
   200  
   201  	for _, tt := range tests {
   202  		tc := tt
   203  
   204  		t.Run(tc.name, func(t *testing.T) {
   205  			defer log.Reset()
   206  
   207  			requireErrno(t, ErrnoFault, mod, functionArgsSizesGet, uint64(tc.argc), uint64(tc.argvLen))
   208  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   209  		})
   210  	}
   211  }