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