@@ -4,6 +4,7 @@ const builtin = @import("builtin");
4
4
const std = @import ("std" );
5
5
const testing = std .testing ;
6
6
const assert = std .debug .assert ;
7
+ const fuzz_abi = std .Build .abi .fuzz ;
7
8
8
9
pub const std_options : std.Options = .{
9
10
.logFn = log ,
@@ -57,7 +58,7 @@ pub fn main() void {
57
58
fba .reset ();
58
59
if (builtin .fuzz ) {
59
60
const cache_dir = opt_cache_dir orelse @panic ("missing --cache-dir=[path] argument" );
60
- fuzzer_init (FuzzerSlice .fromSlice (cache_dir ));
61
+ fuzz_abi . fuzzer_init (.fromSlice (cache_dir ));
61
62
}
62
63
63
64
if (listen ) {
@@ -78,7 +79,7 @@ fn mainServer() !void {
78
79
});
79
80
80
81
if (builtin .fuzz ) {
81
- const coverage_id = fuzzer_coverage_id ();
82
+ const coverage_id = fuzz_abi . fuzzer_coverage_id ();
82
83
try server .serveU64Message (.coverage_id , coverage_id );
83
84
}
84
85
@@ -152,14 +153,19 @@ fn mainServer() !void {
152
153
});
153
154
},
154
155
.start_fuzzing = > {
156
+ // This ensures that this code won't be analyzed and hence reference fuzzer symbols
157
+ // since they are not present.
155
158
if (! builtin .fuzz ) unreachable ;
159
+
156
160
const index = try server .receiveBody_u32 ();
157
161
const test_fn = builtin .test_functions [index ];
158
162
const entry_addr = @intFromPtr (test_fn .func );
163
+
159
164
try server .serveU64Message (.fuzz_start_addr , entry_addr );
160
165
defer if (testing .allocator_instance .deinit () == .leak ) std .process .exit (1 );
161
166
is_fuzz_test = false ;
162
- fuzzer_set_name (test_fn .name .ptr , test_fn .name .len );
167
+ fuzz_test_index = index ;
168
+
163
169
test_fn .func () catch | err | switch (err ) {
164
170
error .SkipZigTest = > return ,
165
171
else = > {
@@ -184,6 +190,8 @@ fn mainServer() !void {
184
190
185
191
fn mainTerminal () void {
186
192
@disableInstrumentation ();
193
+ if (builtin .fuzz ) @panic ("fuzz test requires server" );
194
+
187
195
const test_fn_list = builtin .test_functions ;
188
196
var ok_count : usize = 0 ;
189
197
var skip_count : usize = 0 ;
@@ -333,28 +341,8 @@ pub fn mainSimple() anyerror!void {
333
341
if (failed != 0 ) std .process .exit (1 );
334
342
}
335
343
336
- const FuzzerSlice = extern struct {
337
- ptr : [* ]const u8 ,
338
- len : usize ,
339
-
340
- /// Inline to avoid fuzzer instrumentation.
341
- inline fn toSlice (s : FuzzerSlice ) []const u8 {
342
- return s .ptr [0.. s .len ];
343
- }
344
-
345
- /// Inline to avoid fuzzer instrumentation.
346
- inline fn fromSlice (s : []const u8 ) FuzzerSlice {
347
- return .{ .ptr = s .ptr , .len = s .len };
348
- }
349
- };
350
-
351
344
var is_fuzz_test : bool = undefined ;
352
-
353
- extern fn fuzzer_set_name (name_ptr : [* ]const u8 , name_len : usize ) void ;
354
- extern fn fuzzer_init (cache_dir : FuzzerSlice ) void ;
355
- extern fn fuzzer_init_corpus_elem (input_ptr : [* ]const u8 , input_len : usize ) void ;
356
- extern fn fuzzer_start (testOne : * const fn ([* ]const u8 , usize ) callconv (.c ) void ) void ;
357
- extern fn fuzzer_coverage_id () u64 ;
345
+ var fuzz_test_index : u32 = undefined ;
358
346
359
347
pub fn fuzz (
360
348
context : anytype ,
@@ -385,12 +373,12 @@ pub fn fuzz(
385
373
const global = struct {
386
374
var ctx : @TypeOf (context ) = undefined ;
387
375
388
- fn fuzzer_one ( input_ptr : [ * ] const u8 , input_len : usize ) callconv (.c ) void {
376
+ fn test_one ( input : fuzz_abi.Slice ) callconv (.c ) void {
389
377
@disableInstrumentation ();
390
378
testing .allocator_instance = .{};
391
379
defer if (testing .allocator_instance .deinit () == .leak ) std .process .exit (1 );
392
380
log_err_count = 0 ;
393
- testOne (ctx , input_ptr [0 .. input_len ] ) catch | err | switch (err ) {
381
+ testOne (ctx , input . toSlice () ) catch | err | switch (err ) {
394
382
error .SkipZigTest = > return ,
395
383
else = > {
396
384
std .debug .lockStdErr ();
@@ -411,10 +399,11 @@ pub fn fuzz(
411
399
testing .allocator_instance = .{};
412
400
defer testing .allocator_instance = prev_allocator_state ;
413
401
414
- for (options .corpus ) | elem | fuzzer_init_corpus_elem (elem .ptr , elem .len );
415
-
416
402
global .ctx = context ;
417
- fuzzer_start (& global .fuzzer_one );
403
+ fuzz_abi .fuzzer_init_test (& global .test_one , .fromSlice (builtin .test_functions [fuzz_test_index ].name ));
404
+ for (options .corpus ) | elem |
405
+ fuzz_abi .fuzzer_new_input (.fromSlice (elem ));
406
+ fuzz_abi .fuzzer_main ();
418
407
return ;
419
408
}
420
409
0 commit comments