Skip to content

Commit f12735e

Browse files
committed
Document WAST test contributing
1 parent d576e44 commit f12735e

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

cmake/spectests_contributing.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
2+
3+
## Run fuzzer
4+
5+
Run Fizzy vs WABT verification fuzzer, currently in `fuzzing` branch.
6+
Start with small inputs.
7+
8+
```shell script
9+
bin/fizzy-fuzz-parser corpus -max_len=13
10+
```
11+
12+
In case it finds a failure you will see output like
13+
```text
14+
INFO: Seed: 770491456
15+
INFO: Loaded 1 modules (64068 inline 8-bit counters): 64068 [0xb8dc90, 0xb9d6d4),
16+
INFO: Loaded 1 PC tables (64068 PCs): 64068 [0xb9d6d8,0xc97b18),
17+
INFO: 10986 files found in corpus
18+
INFO: seed corpus: files: 10986 min: 1b max: 27419b total: 740862b rss: 40Mb
19+
#11160 INITED cov: 7782 ft: 9644 corp: 227/2677b exec/s: 0 rss: 186Mb
20+
#65536 pulse cov: 7782 ft: 9644 corp: 227/2677b lim: 13 exec/s: 32768 rss: 215Mb
21+
#131072 pulse cov: 7782 ft: 9644 corp: 227/2677b lim: 13 exec/s: 32768 rss: 248Mb
22+
#262144 pulse cov: 7782 ft: 9644 corp: 227/2677b lim: 13 exec/s: 32768 rss: 314Mb
23+
MALFORMED: invalid limits 4
24+
/home/chfast/Projects/wasmx/fizzy/test/fuzzer/parser_fuzzer.cpp:47:9: runtime error: execution reached an unreachable program point
25+
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/chfast/Projects/wasmx/fizzy/test/fuzzer/parser_fuzzer.cpp:47:9 in
26+
MS: 1 ChangeBit-; base unit: 846f4928f92649789961543e93544b4c2ed6fc44
27+
0x0,0x61,0x73,0x6d,0x1,0x0,0x0,0x0,0x5,0x3,0x1,0x4,0x2b,
28+
\x00asm\x01\x00\x00\x00\x05\x03\x01\x04+
29+
artifact_prefix='./'; Test unit written to ./crash-016934f781c41276bfacda9a90385cef85a88d5f
30+
Base64: AGFzbQEAAAAFAwEEKw==
31+
```
32+
33+
In this example Fizzy reported the error `MALFORMED: invalid limits 4`
34+
while WABT considers the Wasm binary valid.
35+
The test unit (Wasm binary) is also printed in various forms and saved as
36+
`crash-016934f781c41276bfacda9a90385cef85a88d5f`.
37+
38+
39+
## Check WebAssembly spec interpreter
40+
41+
In case of false negative validation result in WABT it is likely that
42+
such case is missing in the WAST spec test.
43+
44+
Build the `wasm reference interpreter` following official instructions.
45+
46+
Rename `crash-016934f781c41276bfacda9a90385cef85a88d5f` to `crash.wasm`
47+
as the interpreter need proper files extension to recognize file type.
48+
49+
```shell script
50+
./wasm crash.wasm
51+
```
52+
53+
Output:
54+
```text
55+
crash.wasm:0xb: decoding error: integer too large
56+
```
57+
58+
Good news. This is effectively the same error reported as in Fizzy. In Wasm 1.0 `limits` kind
59+
can be 0 or 1. The the value 4 in the `crash.wasm` is larger than the max 1.
60+
61+
62+
## Inspect with WABT tools
63+
64+
You can use `wasm2wat` or `wasm-validate` tools to confirm the bug in WABT.
65+
Make sure you use the same version as used for fuzzing.
66+
Disable all extensions except "mutable globals".
67+
68+
In our example, `wasm2wat crash.wasm`:
69+
```webassembly
70+
(module
71+
(memory (;0;) 43 i64))
72+
```
73+
This indicates that the issue is in the memory section.
74+
75+
Unfortunately, we get different error as the data section also has invalid length.
76+
Let's fix that.
77+
78+
79+
## Prepare WAST test
80+
81+
Dump the test unit (`xxd -p -c1000 crash.wasm`):
82+
83+
```hexdump
84+
0061736d01000000050301042b
85+
```
86+
87+
Here are created WAST tests, placed in `new.wast` file. In the original `crash.wasm` the invalid 4
88+
is followed by `2b` byte. We added 2 more variants of the test with byte `00` and without any
89+
following byte (remember to change the section length if you actually modify the length).
90+
91+
```wast
92+
(assert_malformed
93+
(module binary
94+
"\00asm" "\01\00\00\00"
95+
"\05\03\01" ;; memory section
96+
"\04\2b" ;; malformed memory limit 4
97+
)
98+
"integer too large"
99+
)
100+
101+
(assert_malformed
102+
(module binary
103+
"\00asm" "\01\00\00\00"
104+
"\05\03\01" ;; memory section
105+
"\04\00" ;; malformed memory limit 4
106+
)
107+
"integer too large"
108+
)
109+
110+
(assert_malformed
111+
(module binary
112+
"\00asm" "\01\00\00\00"
113+
"\05\02\01" ;; memory section
114+
"\04" ;; malformed memory limit 4
115+
)
116+
"integer too large"
117+
)
118+
```
119+
120+
These tests can be rechecked with WABT.
121+
122+
```shell script
123+
wast2json new.wast
124+
wasm-validate new.0.wasm
125+
wasm-validate new.1.wasm
126+
wasm-validate new.2.wasm
127+
```
128+
129+
The last test case is actually failing in WABT for some other reason, but it can stay as a valid
130+
spectests addition.
131+
132+
```text
133+
000000c: error: unable to read u32 leb128: memory initial page count
134+
```
135+
136+
137+
## Debug & fix WABT
138+
139+
Debug `wasm-validate new.0.wasm` to find out why it passes validation.
140+
Binary loading code is in `binary-reader.cc`.
141+
142+
The example bug is fixed by https://github.com/WebAssembly/wabt/pull/1547.
143+
144+
145+
## Send WAST tests upstream

0 commit comments

Comments
 (0)