Skip to content

Commit 97dbadd

Browse files
committed
"--timeout=..." is now a native Jazzer.js flag
1 parent 5841165 commit 97dbadd

15 files changed

Lines changed: 60 additions & 26 deletions

File tree

docs/fuzz-settings.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,16 @@ npx jazzer fuzzTarget -- -use_value_profile=1
5555
## Timeout
5656

5757
Invocations of fuzz targets, which take longer than the configured timeout, will
58-
cause fuzzing to stop and a timeout finding to be reported. This feature is
59-
directly provided by the underlying fuzzing engine, libFuzzer.
60-
61-
A [default timeout](https://www.llvm.org/docs/LibFuzzer.html#output) of 1200
62-
seconds is preconfigured, but can be changed using the `-timeout` fuzzer flag.
58+
cause fuzzing to stop and a timeout finding to be reported. A default timeout of
59+
5000 milliseconds is preconfigured, but can be changed using the `--timeout`
60+
fuzzer flag.
6361

6462
Timeouts work in the sync- and asynchronous fuzzing mode.
6563

6664
**Example invocation:**
6765

6866
```shell
69-
npx jazzer fuzzTarget -- -timeout=10
67+
npx jazzer fuzzTarget --timeout=10000
7068
```
7169

7270
**Example output:**

docs/jest-integration.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,3 @@ reimplemented.
327327
328328
- Mock functions
329329
- Isolated workers
330-
- Test-based timeouts (third parameter to `test` functions)

examples/jest_integration/integration.fuzz.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ describe("My describe", () => {
2424
target.fuzzMe(data);
2525
});
2626

27+
it.fuzz(
28+
"My fuzz test with an explicit timeout (async)",
29+
async (data) => {
30+
target.fuzzMe(data);
31+
},
32+
1000
33+
);
34+
35+
it.fuzz(
36+
"My fuzz test with an explicit timeout (sync)",
37+
(data) => {
38+
target.fuzzMe(data);
39+
},
40+
1000
41+
);
42+
2743
it.fuzz("My callback fuzz test", (data, done) => {
2844
target.callbackFuzzMe(data, done);
2945
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test

fuzztests/.jazzerjsrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"fuzzerOptions": ["-use_value_profile=1", "-max_total_time=30"],
3-
"includes": ["jazzer.js"]
3+
"includes": ["jazzer.js"],
4+
"timeout": 1000
45
}

fuzztests/FuzzedDataProvider.fuzz.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describe("FuzzedDataProvider", () => {
4242
}
4343
jazzer.exploreState(hash(usedMethods), 31);
4444
},
45-
40000
45+
5000
4646
);
4747
});
4848

fuzztests/runFuzzTests.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const fs = require("fs/promises");
99
const { spawn } = require("child_process");
1010

1111
const fuzzTestFileExtension = "fuzz.js";
12-
const fuzzTestNameRegex = /it.fuzz\(\s*"(.*)"/g;
12+
const fuzzTestNameRegex = /it.fuzz\s*\(\s*"(.*)"/g;
1313

1414
async function findFuzzTestNamesInFile(file) {
1515
const fuzzTestNames = [];
@@ -47,8 +47,11 @@ async function executeFuzzTest(file, name) {
4747
});
4848
test.on("close", (code) => {
4949
console.log(`--- Finished fuzz test ${file} > ${name} with code ${code}`);
50-
if (code !== 0 && code !== null) reject(code);
51-
else resolve();
50+
if (code !== 0 && code !== null) {
51+
reject(code);
52+
} else {
53+
resolve();
54+
}
5255
});
5356
});
5457
}

packages/core/cli.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ yargs(process.argv.slice(2))
181181
type: "string",
182182
group: "Fuzzer:",
183183
default: ["json", "text", "lcov", "clover"],
184+
})
185+
.option("timeout", {
186+
describe: "Timeout in milliseconds for each fuzz test execution.",
187+
type: "number",
188+
group: "Fuzzer:",
189+
default: 5000,
184190
});
185191
},
186192
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -196,6 +202,7 @@ yargs(process.argv.slice(2))
196202
excludes: args.instrumentation_excludes,
197203
dryRun: args.dry_run,
198204
sync: args.sync,
205+
timeout: args.timeout,
199206
fuzzerOptions: args.corpus.concat(args._),
200207
customHooks: args.custom_hooks,
201208
expectedErrors: args.expected_errors,

packages/core/core.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export interface Options {
5252
fuzzerOptions: string[];
5353
customHooks: string[];
5454
expectedErrors: string[];
55-
timeout?: number;
55+
timeout: number;
5656
idSyncFile?: string;
5757
coverage: boolean; // Enables source code coverage report generation.
5858
coverageDirectory: string;
@@ -290,10 +290,12 @@ function buildFuzzerOptions(options: Options): string[] {
290290
// the last provided option takes precedence
291291
opts = opts.concat("-runs=0");
292292
}
293-
if (options.timeout != undefined) {
294-
const inSeconds = options.timeout / 1000;
295-
opts = opts.concat(`-timeout=${inSeconds}`);
293+
294+
if (options.timeout <= 0) {
295+
throw new Error("timeout must be > 0");
296296
}
297+
const inSeconds = Math.ceil(options.timeout / 1000);
298+
opts = opts.concat(`-timeout=${inSeconds}`);
297299

298300
return [prepareLibFuzzerArg0(opts), ...opts];
299301
}

0 commit comments

Comments
 (0)