Merge pull request #1822 from PR0M3TH3AN/ai/fuzz-robustness-20260127-16938882270581666950

Fuzz tests and robustness fixes for nostrEventSchemas, dmDecryptor, and magnetUtils
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-27 12:05:56 -05:00
commit faef22b94b
5 files changed
+112 -4

No files matched your search

@@ -0,0 +1,11 @@
{
"target": "nostrEventSchemas",
"error": {
"message": "Maximum call stack size exceeded",
"name": "RangeError"
},
"input": {
"circular": true,
"description": "Object with circular reference passed to setNostrEventSchemaOverrides"
}
}
+10 -1
View File
@@ -701,7 +701,16 @@ function resolveOverride(type) {
export function setNostrEventSchemaOverrides(overrides = {}) {
if (overrides && typeof overrides === "object") {
schemaOverrides = overrides;
try {
JSON.stringify(overrides);
schemaOverrides = overrides;
} catch (error) {
devLogger.warn(
"[nostrEventSchemas] Invalid overrides provided (circular structure?):",
error
);
schemaOverrides = {};
}
} else {
schemaOverrides = {};
}
+8 -1
View File
@@ -25,12 +25,19 @@ const DmDecryptor = await import(tempPath);
async function fuzzTest(iteration) {
const genEvent = () => {
const tags = rng.array(() => rng.array(() => rng.mixedString(20), 5), 5);
if (rng.bool()) {
// Circular tag structure
const circularTag = ["p"];
circularTag.push(circularTag); // Circular reference
tags.push(circularTag);
}
return {
kind: rng.oneOf([4, 1059, rng.int(0, 20000)]),
pubkey: rng.mixedString(64),
created_at: rng.int(0, 2000000000),
content: rng.mixedString(100),
tags: rng.array(() => rng.array(() => rng.mixedString(20), 5), 5)
tags
};
};
+65 -1
View File
@@ -16,7 +16,71 @@ async function fuzzTest(iteration) {
// Randomize window protocol sometimes
global.window.location.protocol = rng.bool() ? "https:" : "http:";
const rawValue = rng.mixedString(100);
const genMagnet = () => {
if (rng.bool()) return rng.mixedString(100); // Random garbage
// Construct semi-valid magnet
let magnet = "magnet:?";
const params = [];
// xt (Exact Topic)
if (rng.bool()) {
const hash = rng.bool() ? rng.mixedString(40) : "urn:btih:" + rng.mixedString(40);
params.push(`xt=${hash}`);
}
// dn (Display Name)
if (rng.bool()) {
const val = rng.mixedString(20);
try {
params.push(`dn=${encodeURIComponent(val)}`);
} catch {
params.push(`dn=${val}`);
}
}
// tr (Trackers)
if (rng.bool()) {
const trackers = rng.array(() => {
const proto = rng.oneOf(["udp", "http", "https", "wss", "ws"]);
const val = `${proto}://${rng.mixedString(20)}`;
try {
return encodeURIComponent(val);
} catch {
return val;
}
}, 5);
trackers.forEach(t => params.push(`tr=${t}`));
}
// ws (Web Seeds)
if (rng.bool()) {
const val = "https://" + rng.mixedString(20);
try {
params.push(`ws=${encodeURIComponent(val)}`);
} catch {
params.push(`ws=${val}`);
}
}
// Random params
if (rng.bool()) {
params.push(`${rng.string(5)}=${rng.mixedString(10)}`);
}
magnet += params.join("&");
// Corrupt it
if (Math.random() < 0.2) {
// Inject garbage
const pos = rng.int(0, magnet.length);
magnet = magnet.slice(0, pos) + rng.nastyString() + magnet.slice(pos);
}
return magnet;
};
const rawValue = genMagnet();
const genOptions = () => {
if (rng.bool()) return null;
+18 -1
View File
@@ -24,7 +24,8 @@ async function fuzzTest(iteration) {
"buildReactionEvent",
"buildZapRequestEvent",
"sanitizeAdditionalTags",
"validateEventStructure"
"validateEventStructure",
"setNostrEventSchemaOverrides"
];
const targetName = rng.oneOf(targets);
@@ -115,6 +116,22 @@ async function fuzzTest(iteration) {
inputs = { type, event };
Schemas.validateEventStructure(type, event);
break;
case "setNostrEventSchemaOverrides":
const randomType = rng.oneOf(Object.values(Schemas.NOTE_TYPES));
if (rng.bool()) {
// Circular object
const obj = { foo: "bar" };
obj.self = obj;
inputs = { [randomType]: obj };
} else {
inputs = { [randomType]: genParams() };
}
// If we set overrides, we should also trigger usage of them to see if it crashes later
Schemas.setNostrEventSchemaOverrides(inputs);
// Trigger usage
Schemas.getNostrEventSchema(randomType);
break;
}
return { target: targetName, inputs };