mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
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:
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
@@ -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 = {};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in new issue
Block a user