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