Files
bitvid/scripts/agent/fuzz-nostr-schemas.mjs
T
google-labs-jules[bot] 3e38916f35 feat(fuzz): add fuzzing suite for schemas, dms, and magnets
- Add `scripts/agent/fuzz-nostr-schemas.mjs` to fuzz event builders and validation
- Add `scripts/agent/fuzz-dm-decryptor.mjs` to fuzz DM unwrapping
- Add `scripts/agent/fuzz-magnet-utils.mjs` to fuzz magnet normalization
- Utilize `scripts/agent/fuzz-lib.mjs` for randomization and reporting
- Verify that `scripts/agent/setup-test-env.js` is imported to polyfill globals
- Output reports to `artifacts/`

No crashes were found during the initial fuzzing run (5000 iterations per target).
2026-01-21 16:34:50 +00:00

85 lines
3.0 KiB
JavaScript

import "./setup-test-env.js";
import { Fuzzer } from "./fuzz-lib.mjs";
import * as schemas from "../../js/nostrEventSchemas.js";
const fuzzer = new Fuzzer("nostr-schemas");
// Mappers for build functions
const BUILDERS = [
{ name: "buildVideoPostEvent", fn: schemas.buildVideoPostEvent },
{ name: "buildVideoMirrorEvent", fn: schemas.buildVideoMirrorEvent },
{ name: "buildRepostEvent", fn: schemas.buildRepostEvent },
{ name: "buildRelayListEvent", fn: schemas.buildRelayListEvent },
{ name: "buildDmRelayListEvent", fn: schemas.buildDmRelayListEvent },
{ name: "buildProfileMetadataEvent", fn: schemas.buildProfileMetadataEvent },
{ name: "buildMuteListEvent", fn: schemas.buildMuteListEvent },
{ name: "buildDmAttachmentEvent", fn: schemas.buildDmAttachmentEvent },
{ name: "buildDmReadReceiptEvent", fn: schemas.buildDmReadReceiptEvent },
{ name: "buildDmTypingIndicatorEvent", fn: schemas.buildDmTypingIndicatorEvent },
{ name: "buildViewEvent", fn: schemas.buildViewEvent },
{ name: "buildZapRequestEvent", fn: schemas.buildZapRequestEvent },
{ name: "buildReactionEvent", fn: schemas.buildReactionEvent },
{ name: "buildCommentEvent", fn: schemas.buildCommentEvent },
{ name: "buildWatchHistoryEvent", fn: schemas.buildWatchHistoryEvent },
{ name: "buildSubscriptionListEvent", fn: schemas.buildSubscriptionListEvent },
{ name: "buildBlockListEvent", fn: schemas.buildBlockListEvent },
{ name: "buildHashtagPreferenceEvent", fn: schemas.buildHashtagPreferenceEvent },
];
async function fuzzTest(fuzzer, state) {
// 1. Fuzz Builder Functions
const builder = fuzzer.pick(BUILDERS);
// Generate random params
const params = fuzzer.randJSON();
state.input = {
target: builder.name,
params: params
};
try {
// Some builders require specific args like buildAdminListEvent(listKey, params)
// but most take a single params object.
// We didn't include buildAdminListEvent in the list above because it takes 2 args.
const event = builder.fn(params);
// 2. Validate the generated event
if (event && event.kind) {
// Find schema type for this kind to validate
let type = null;
for (const [key, val] of Object.entries(schemas.NOTE_TYPES)) {
const schema = schemas.getNostrEventSchema(val);
if (schema && schema.kind === event.kind) {
type = val;
break;
}
}
if (type) {
schemas.validateEventAgainstSchema(type, event);
}
}
} catch (err) {
throw err;
}
// 3. Fuzz Validation directly with random events
if (fuzzer.randBool()) {
const types = Object.values(schemas.NOTE_TYPES);
const type = fuzzer.pick(types);
const randomEvent = fuzzer.randJSON();
state.input = {
target: "validateEventAgainstSchema",
type: type,
event: randomEvent
};
schemas.validateEventAgainstSchema(type, randomEvent);
}
}
// Run for 5000 iterations
fuzzer.runFuzzLoop(5000, fuzzTest).catch(console.error);