Skip to content

Commit b380792

Browse files
committed
fix(core): surface callback afterEach findings
Run afterEach callbacks before clearing callback findings so deferred detector reports are delivered through done(error).
1 parent 63c1cd0 commit b380792

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

packages/core/core.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2026 Code Intelligence GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { registerAfterEachCallback } from "./callback";
18+
import { asFindingAwareFuzzFn } from "./core";
19+
import { clearFirstFinding, Finding, reportFinding } from "./finding";
20+
21+
describe("asFindingAwareFuzzFn", () => {
22+
let stderrWrite: jest.SpiedFunction<typeof process.stderr.write>;
23+
24+
beforeEach(() => {
25+
globalThis.JazzerJS = new Map();
26+
stderrWrite = jest
27+
.spyOn(process.stderr, "write")
28+
.mockImplementation(() => true);
29+
});
30+
31+
afterEach(() => {
32+
stderrWrite.mockRestore();
33+
clearFirstFinding();
34+
});
35+
36+
it("surfaces afterEach findings from async done callbacks", async () => {
37+
registerAfterEachCallback(() => reportFinding("afterEach finding", false));
38+
const wrappedFn = asFindingAwareFuzzFn(
39+
(_data, done: (err?: Error) => void) => {
40+
setTimeout(() => done(), 0);
41+
},
42+
false,
43+
);
44+
45+
await new Promise<void>((resolve, reject) => {
46+
wrappedFn(Buffer.from(""), (error?: Error) => {
47+
try {
48+
expect(error).toBeInstanceOf(Finding);
49+
expect(error?.message).toBe("afterEach finding");
50+
resolve();
51+
} catch (e) {
52+
reject(e);
53+
}
54+
});
55+
});
56+
});
57+
});

packages/core/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,11 +453,11 @@ export function asFindingAwareFuzzFn(
453453
callbacks.runBeforeEachCallbacks();
454454
// Return result of fuzz target to enable sanity checks in C++ part.
455455
const result = originalFuzzFn(data, (err?) => {
456+
callbacks.runAfterEachCallbacks();
456457
const error = clearFirstFinding() ?? err;
457458
if (error) {
458459
printAndDump(error);
459460
}
460-
callbacks.runAfterEachCallbacks();
461461
done(error);
462462
});
463463
// Check if any finding was reported by the invocation before the

0 commit comments

Comments
 (0)