Skip to content

Commit f035b38

Browse files
committed
Improve fuzz testing
1 parent 7d3b4f2 commit f035b38

8 files changed

Lines changed: 565 additions & 27 deletions

File tree

.github/workflows/fuzz-testing.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
5757
- name: Run all fuzz tests
5858
run: |
59-
DURATION="${{ github.event.inputs.duration || '1h' }}"
59+
DURATION="${{ github.event.inputs.duration || '5h' }}"
6060
./gradlew fuzz -Pfuzz.maxDuration=$DURATION --stacktrace
6161
6262
- name: Save fuzz corpus cache
@@ -73,7 +73,7 @@ jobs:
7373
if: always()
7474
with:
7575
name: fuzz-test-reports
76-
path: '**/build/reports/jazzer/**'
76+
path: '**/build/reports/fuzz-coverage/**'
7777

7878
- name: Upload crash artifacts
7979
uses: actions/upload-artifact@v5

buildSrc/src/main/kotlin/smithy-java.fuzz-test.gradle.kts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dependencies {
1717
}
1818

1919
// Create the fuzz test task
20-
tasks.register<Test>("fuzz") {
20+
val fuzz = tasks.register<Test>("fuzz") {
2121
description = "Run fuzz tests using Jazzer"
2222
group = "verification"
2323

@@ -42,15 +42,34 @@ tasks.register<Test>("fuzz") {
4242

4343
// Jazzer configuration
4444
systemProperty("jazzer.valueprofile", "1")
45-
systemProperty("jazzer.coverage_report", "${project.layout.buildDirectory}/reports/jazzer")
4645

4746
systemProperty("jazzer.instrumentation_includes", "software.amazon.smithy.java.**")
4847

4948
val corpusDir = "${project.projectDir}/src/fuzz/resources/corpus"
49+
var argIndex = 0;
5050
if (file(corpusDir).exists()) {
51-
systemProperty("jazzer.internal.arg.0", corpusDir)
51+
systemProperty("jazzer.internal.arg.${argIndex++}", corpusDir)
5252
}
5353

5454
val maxDuration = project.findProperty("fuzz.maxDuration") ?: "1h"
5555
systemProperty("jazzer.max_duration", maxDuration)
56+
}
57+
58+
// Generate JaCoCo coverage report for fuzz tests
59+
val fuzzReport = tasks.register<JacocoReport>("jacocoFuzzReport") {
60+
description = "Generate JaCoCo coverage report for fuzz tests"
61+
group = "verification"
62+
63+
dependsOn(fuzz)
64+
executionData(layout.buildDirectory.files("jacoco/${fuzz.name}.exec"))
65+
sourceSets(project.the<SourceSetContainer>()["main"])
66+
67+
reports {
68+
xml.required.set(false)
69+
csv.required.set(false)
70+
}
71+
}
72+
73+
fuzz {
74+
finalizedBy(fuzzReport)
5675
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# ---- Integers (major type 0) ----
2+
# uint(0)
3+
"\x00"
4+
5+
# uint(1)
6+
"\x01"
7+
8+
# uint(10)
9+
"\x0a"
10+
11+
# uint(23) — boundary of “small” ints
12+
"\x17"
13+
14+
# uint(24) encoded using 1 follow byte
15+
"\x18\x18"
16+
17+
# uint(255)
18+
"\x18\xff"
19+
20+
# uint(256)
21+
"\x19\x01\x00"
22+
23+
# ---- Negative integers (major type 1) ----
24+
# -1
25+
"\x20"
26+
27+
# -10
28+
"\x29"
29+
30+
# -24 (boundary small negative int)
31+
"\x37"
32+
33+
# -25 (encoded with u8 following)
34+
"\x38\x18"
35+
36+
37+
# ---- Byte strings (major type 2) ----
38+
# byte string length 0
39+
"\x40"
40+
41+
# byte string length 1
42+
"\x41"
43+
44+
# byte string length 4
45+
"\x44"
46+
47+
# byte string length 8
48+
"\x48"
49+
50+
# byte string length 16 (u8)
51+
"\x58\x10"
52+
53+
# byte string length 256 (u16)
54+
"\x59\x01\x00"
55+
56+
# indefinite-length byte string
57+
"\x5f"
58+
59+
60+
# ---- Text strings (major type 3) ----
61+
# text string length 0
62+
"\x60"
63+
64+
# text string length 1
65+
"\x61"
66+
67+
# text string length 4
68+
"\x64"
69+
70+
# text string length 8
71+
"\x68"
72+
73+
# text string length 16 (u8)
74+
"\x78\x10"
75+
76+
# text string length 256 (u16)
77+
"\x79\x01\x00"
78+
79+
# indefinite-length text string
80+
"\x7f"
81+
82+
83+
# ---- Arrays (major type 4) ----
84+
# array(0)
85+
"\x80"
86+
87+
# array(1)
88+
"\x81"
89+
90+
# array(2)
91+
"\x82"
92+
93+
# array(3)
94+
"\x83"
95+
96+
# array(4)
97+
"\x84"
98+
99+
# array(8)
100+
"\x88"
101+
102+
# array(16) (u8)
103+
"\x98\x10"
104+
105+
# array(256) (u16)
106+
"\x99\x01\x00"
107+
108+
# indefinite-length array
109+
"\x9f"
110+
111+
112+
# ---- Maps (major type 5) ----
113+
# map(0)
114+
"\xa0"
115+
116+
# map(1)
117+
"\xa1"
118+
119+
# map(2)
120+
"\xa2"
121+
122+
# map(3)
123+
"\xa3"
124+
125+
# map(4)
126+
"\xa4"
127+
128+
# map(8)
129+
"\xa8"
130+
131+
# map(16) (u8)
132+
"\xb8\x10"
133+
134+
# map(256) (u16)
135+
"\xb9\x01\x00"
136+
137+
# indefinite-length map
138+
"\xbf"
139+
140+
141+
# ---- Tags (major type 6) ----
142+
# tag(0): datetime string
143+
"\xc0"
144+
145+
# tag(1): epoch datetime
146+
"\xc1"
147+
148+
# tag(2): positive bignum
149+
"\xc2"
150+
151+
# tag(3): negative bignum
152+
"\xc3"
153+
154+
# tag(32): URI
155+
"\xd8\x20"
156+
157+
# tag(55799) — common CBOR self-describe magic
158+
"\xd9\xd9\xf7"
159+
160+
161+
# ---- Simple values, floats, break (major type 7) ----
162+
# false
163+
"\xf4"
164+
165+
# true
166+
"\xf5"
167+
168+
# null
169+
"\xf6"
170+
171+
# undefined
172+
"\xf7"
173+
174+
# half float header
175+
"\xf9"
176+
177+
# float32 header
178+
"\xfa"
179+
180+
# float64 header
181+
"\xfb"
182+
183+
# BREAK code for indefinite lengths
184+
"\xff"
185+
186+
187+
# ---- Useful prefabricated patterns ----
188+
# { "a": false }
189+
"\xa1\x61\x61\xf4"
190+
191+
# [1,2,3]
192+
"\x83\x01\x02\x03"
193+
194+
# [false, true, null]
195+
"\x83\xf4\xf5\xf6"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"0"
2+
"7"
3+
","
4+
":"
5+
"2.1e24"
6+
7+
"true"
8+
"false"
9+
"null"
10+
11+
"\"\""
12+
"\"\":"
13+
14+
"{}"
15+
",{}"
16+
":{}"
17+
"{\"\":0}"
18+
"{{}}"
19+
20+
"[]"
21+
",[]"
22+
":[]"
23+
"[0]"
24+
"[[]]"
25+
26+
"''"
27+
"\\"
28+
"\\b"
29+
"\\f"
30+
"\\n"
31+
"\\r"
32+
"\\t"
33+
"\\u0000"
34+
"\\x00"
35+
"\\0"
36+
"\\uD800\\uDC00"
37+
"\\uDBFF\\uDFFF"
38+
39+
"\"\":0"
40+
"//"
41+
"/**/"
42+
43+
44+
# Things like geojson, json-ld, ...
45+
"$ref"
46+
"type"
47+
"coordinates"
48+
"@context"
49+
"@id"
50+
"@type"
51+
52+
# Strings with truncated special values
53+
"{\"foo\":fa"
54+
"{\"foo\":t"
55+
"{\"foo\":nul"
56+
57+
"{"
58+
"}"
59+
"\"qty\": 1, \"qty\": -1"
60+
"\"qty\": 1, \"qty\\ud800\": -1"
61+
"\"qty\": 1, \"qt\\y\": -1"
62+
"/*"
63+
"*/"
64+
"\""
65+
"1.7976931348623157e+308"
66+
"5e-324"
67+
"9007199254740991"
68+
"-9007199254740991"
69+
70+
"}="
71+
72+
",,"
73+
"{\"\":"

0 commit comments

Comments
 (0)