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 }