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