Files
Archivestr/torch/scripts/agent/fuzz-lock-event.mjs
thePR0M3TH3AN deadeaafac update
2026-02-20 10:26:39 -05:00

141 lines
3.7 KiB
JavaScript

import { parseLockEvent } from '../../src/lib.mjs';
import fs from 'node:fs';
import path from 'node:path';
// Seeded random number generator (simple LCG)
function mulberry32(a) {
return function () {
let t = (a += 0x6d2b79f5);
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
const SEED = process.env.SEED ? parseInt(process.env.SEED, 10) : Date.now();
const ITERATIONS = 10000;
const rand = mulberry32(SEED);
console.log(`Starting fuzz run. SEED=${SEED}, ITERATIONS=${ITERATIONS}`);
const REPRO_DIR = 'examples/reproducers/fuzz-lock-event-' + new Date().toISOString().slice(0, 10).replace(/-/g, '');
if (!fs.existsSync(REPRO_DIR)) {
fs.mkdirSync(REPRO_DIR, { recursive: true });
}
let failures = 0;
function randomString(length) {
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(rand() * chars.length));
}
return result;
}
function randomJson() {
const types = ['object', 'array', 'string', 'number', 'boolean', 'null'];
const type = types[Math.floor(rand() * types.length)];
if (type === 'object') {
const obj = {};
const keys = Math.floor(rand() * 5);
for (let i = 0; i < keys; i++) {
obj[randomString(5)] = randomJson();
}
return obj;
} else if (type === 'array') {
const arr = [];
const len = Math.floor(rand() * 5);
for (let i = 0; i < len; i++) {
arr.push(randomJson());
}
return arr;
} else if (type === 'string') {
return randomString(10);
} else if (type === 'number') {
return rand() * 1000;
} else if (type === 'boolean') {
return rand() > 0.5;
} else {
return null;
}
}
function generateEvent() {
const malformed = rand() > 0.8;
const content = malformed ? randomString(100) : JSON.stringify(randomJson());
const tags = [];
const numTags = Math.floor(rand() * 5);
for (let i = 0; i < numTags; i++) {
const tagLen = Math.floor(rand() * 3) + 1;
const tag = [];
for (let j = 0; j < tagLen; j++) {
tag.push(randomString(10));
}
tags.push(tag);
}
// Sometimes add specific tags
if (rand() > 0.5) {
tags.push(['d', randomString(20)]);
}
if (rand() > 0.5) {
tags.push(['expiration', String(Math.floor(Date.now() / 1000) + 1000)]);
}
return {
id: randomString(64), // Mock ID
pubkey: randomString(64), // Mock Pubkey
created_at: Math.floor(Date.now() / 1000),
tags: tags,
content: content,
};
}
for (let i = 0; i < ITERATIONS; i++) {
const event = generateEvent();
try {
parseLockEvent(event);
} catch (err) {
failures++;
console.error(`Failure #${failures} at iteration ${i}: ${err.message}`);
const reproFile = path.join(REPRO_DIR, `repro-${i}.json`);
fs.writeFileSync(reproFile, JSON.stringify(event, null, 2));
const reproScript = path.join(REPRO_DIR, `run-repro-${i}.mjs`);
const scriptContent = `
import { parseLockEvent } from '../../../src/lib.mjs';
import fs from 'node:fs';
const event = JSON.parse(fs.readFileSync('repro-${i}.json', 'utf8'));
console.log('Running repro case...');
try {
parseLockEvent(event);
console.log('Success (no crash)');
} catch (err) {
console.error('Crash reproduced:', err);
process.exit(1);
}
`;
fs.writeFileSync(reproScript, scriptContent);
}
}
if (failures === 0) {
console.log('Fuzzing completed successfully. No failures found.');
// Clean up empty directory if no failures
try {
fs.rmdirSync(REPRO_DIR);
} catch {
// Ignore error if directory is not empty or missing
}
} else {
console.log(`Fuzzing completed with ${failures} failures.`);
process.exit(1);
}