Skip to content

Commit

Permalink
Resolve naming conflict for [f|F]uzzTarget (#242)
Browse files Browse the repository at this point in the history
The last PR #239 should have included these changes to begin with,
somehow they got lost on the wire. The introduction of a new interface
called `FuzzTarget` caused a name conflict with a similarly named struct
field within `options`.
This PR ships a change that resolves this conflict.. whoops 🧐

Authored-by: 0xricksanchez <christopher.krah@code-intelligence.com>
  • Loading branch information
0xricksanchez committed Dec 23, 2022
1 parent 0048593 commit e943ebc
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 31 deletions.
10 changes: 5 additions & 5 deletions docs/fuzz-settings.md
Expand Up @@ -54,7 +54,7 @@ configuration in package.json:

```json
"scripts": {
"fuzz": "jazzer fuzz ... -h <path_to_file_with_custom_hooks>.js"
"fuzz": "jazzer fuzz ... -h <path_to_file_with_custom_hooks>.js"
}
```

Expand All @@ -80,10 +80,10 @@ hook function:

```typescript
function register<Before|Replace|After>Hook(
target: string, // target function name that we want to hook
pkg: string, // the name of the target library
async: boolean, // the hook function will be run in async (true) or sync (false) mode?
hookFn: HookFn // custom hook function
target: string, // target function name that we want to hook
pkg: string, // the name of the target library
async: boolean, // the hook function will be run in async (true) or sync (false) mode?
hookFn: HookFn // custom hook function
);
```

Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions packages/core/cli.ts
Expand Up @@ -145,10 +145,9 @@ yargs(process.argv.slice(2))
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(args: any) => {
const fT = path.join(process.cwd(), args.fuzzTarget);
const opts: Options = {
fuzzTarget: ensureSuffix(args.fuzzTarget),
fuzzFunction: args.fuzzFunction,
fuzzEntryPoint: args.fuzzFunction,
includes: args.instrumentation_includes.map((include: string) =>
// empty string matches every file
include === "*" ? "" : include
Expand Down
31 changes: 19 additions & 12 deletions packages/core/core.ts
Expand Up @@ -19,8 +19,10 @@ import * as hooking from "@jazzer.js/hooking";
import { registerInstrumentor } from "@jazzer.js/instrumentor";

export interface Options {
// `fuzzTarget` is the name of an external module containing a `fuzzer.FuzzTarget`
// that is resolved by `fuzzEntryPoint`.
fuzzTarget: string;
fuzzFunction: string;
fuzzEntryPoint: string;
includes: string[];
excludes: string[];
dryRun: boolean;
Expand All @@ -29,8 +31,8 @@ export interface Options {
customHooks: string[];
}

interface FuzzTarget {
[fuzzFunction: string]: fuzzer.FuzzFn;
interface FuzzModule {
[fuzzEntryPoint: string]: fuzzer.FuzzTarget;
}

/* eslint no-var: 0 */
Expand All @@ -55,20 +57,25 @@ export async function initFuzzing(options: Options) {
}
}

async function loadFuzzFunction(options: Options): Promise<fuzzer.FuzzFn> {
const fuzzTarget: FuzzTarget = await importModule(options.fuzzTarget);
const fuzzFn: fuzzer.FuzzFn = fuzzTarget[options.fuzzFunction];
async function loadFuzzFunction(options: Options): Promise<fuzzer.FuzzTarget> {
const fuzzTarget = await importModule(options.fuzzTarget);
if (!fuzzTarget) {
throw new Error(
`${options.fuzzTarget} could not be imported successfully"`
);
}
const fuzzFn: fuzzer.FuzzTarget = fuzzTarget[options.fuzzEntryPoint];
if (typeof fuzzFn !== "function") {
throw new Error(
`${options.fuzzTarget} does not export function "${options.fuzzFunction}"`
`${options.fuzzTarget} does not export function "${options.fuzzEntryPoint}"`
);
}
return fuzzFn;
}

export async function startFuzzing(options: Options) {
await initFuzzing(options);
const fuzzFn: fuzzer.FuzzFn = await loadFuzzFunction(options);
const fuzzFn: fuzzer.FuzzTarget = await loadFuzzFunction(options);
startFuzzingNoInit(
fuzzFn,
addFuzzerOptionsForDryRun(options.fuzzerOptions, options.dryRun)
Expand All @@ -95,23 +102,23 @@ export function addFuzzerOptionsForDryRun(
}

export function startFuzzingNoInit(
fuzzFn: fuzzer.FuzzFn,
fuzzFn: fuzzer.FuzzTarget,
fuzzerOptions: string[]
) {
Fuzzer.startFuzzing(fuzzFn, fuzzerOptions);
}

export async function startFuzzingAsync(options: Options) {
await initFuzzing(options);
const fuzzFn: fuzzer.FuzzFn = await loadFuzzFunction(options);
const fuzzFn: fuzzer.FuzzTarget = await loadFuzzFunction(options);
return startFuzzingAsyncNoInit(
fuzzFn,
addFuzzerOptionsForDryRun(options.fuzzerOptions, options.dryRun)
);
}

export function startFuzzingAsyncNoInit(
fuzzFn: fuzzer.FuzzFn,
fuzzFn: fuzzer.FuzzTarget,
fuzzerOptions: string[]
) {
return Fuzzer.startFuzzingAsync(fuzzFn, fuzzerOptions);
Expand Down Expand Up @@ -149,7 +156,7 @@ function cleanStack(stack: string): string {
return result.join("\n");
}

async function importModule(name: string): Promise<FuzzTarget> {
async function importModule(name: string): Promise<FuzzModule | void> {
return import(name);
}

Expand Down
13 changes: 8 additions & 5 deletions packages/fuzzer/fuzzer.ts
Expand Up @@ -169,15 +169,18 @@ function traceAndReturn(current: unknown, target: unknown, id: number) {
}

// Re-export everything from the native library.
export type FuzzFnAsyncOrValue = (data: Buffer) => void | Promise<void>;
export type FuzzFnCallback = (data: Buffer, done: (e?: Error) => void) => void;
export type FuzzFn = FuzzFnAsyncOrValue | FuzzFnCallback;
export type FuzzTargetAsyncOrValue = (data: Buffer) => void | Promise<void>;
export type FuzzTargetCallback = (
data: Buffer,
done: (e?: Error) => void
) => void;
export type FuzzTarget = FuzzTargetAsyncOrValue | FuzzTargetCallback;
export type FuzzOpts = string[];

export interface Fuzzer {
printVersion: () => void;
startFuzzing: (fuzzFn: FuzzFn, fuzzOpts: FuzzOpts) => void;
startFuzzingAsync: (fuzzFn: FuzzFn, fuzzOpts: FuzzOpts) => Promise<void>;
startFuzzing: (fuzzFn: FuzzTarget, fuzzOpts: FuzzOpts) => void;
startFuzzingAsync: (fuzzFn: FuzzTarget, fuzzOpts: FuzzOpts) => Promise<void>;
stopFuzzingAsync: () => void;
nextCounter: typeof nextCounter;
incrementCounter: typeof incrementCounter;
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-runner/config.ts
Expand Up @@ -21,8 +21,8 @@ export const defaultOptions: Options = {
dryRun: true,
includes: ["*"],
excludes: ["node_modules"],
fuzzFunction: "",
fuzzTarget: "",
fuzzEntryPoint: "",
customHooks: [],
fuzzerOptions: [],
sync: false,
Expand Down
16 changes: 10 additions & 6 deletions packages/jest-runner/fuzz.ts
Expand Up @@ -18,7 +18,11 @@

import { Global } from "@jest/types";
import * as core from "@jazzer.js/core";
import { FuzzFn, FuzzFnAsyncOrValue, FuzzFnCallback } from "@jazzer.js/fuzzer";
import {
FuzzTarget,
FuzzTargetAsyncOrValue,
FuzzTargetCallback,
} from "@jazzer.js/fuzzer";
import { loadConfig } from "./config";
import { JazzerWorker } from "./worker";
import { Corpus } from "./corpus";
Expand All @@ -38,7 +42,7 @@ export class FuzzerStartError extends FuzzerError {}
// Use Jests global object definition.
const g = globalThis as unknown as Global.Global;

export type FuzzTest = (name: Global.TestNameLike, fn: FuzzFn) => void;
export type FuzzTest = (name: Global.TestNameLike, fn: FuzzTarget) => void;

export const skip: FuzzTest = (name) => {
g.test.skip(toTestName(name), () => {
Expand Down Expand Up @@ -82,7 +86,7 @@ export const fuzz: FuzzTest = (name, fn) => {

export const runInFuzzingMode = (
name: Global.TestNameLike,
fn: FuzzFn,
fn: FuzzTarget,
corpus: Corpus,
fuzzerOptions: string[]
) => {
Expand All @@ -107,7 +111,7 @@ export const runInFuzzingMode = (

export const runInRegressionMode = (
name: Global.TestNameLike,
fn: FuzzFn,
fn: FuzzTarget,
corpus: Corpus,
timeout: number
) => {
Expand Down Expand Up @@ -140,7 +144,7 @@ export const runInRegressionMode = (
} else {
// Support sync and async fuzz tests.
return Promise.resolve()
.then(() => (fn as FuzzFnAsyncOrValue)(content))
.then(() => (fn as FuzzTargetAsyncOrValue)(content))
.then(resolve, reject);
}
}).then(
Expand All @@ -163,7 +167,7 @@ export const runInRegressionMode = (
};

const doneCallbackPromise = (
fn: FuzzFnCallback,
fn: FuzzTargetCallback,
content: Buffer,
resolve: (value: unknown) => void,
reject: (reason?: unknown) => void
Expand Down

0 comments on commit e943ebc

Please sign in to comment.