diff --git a/examples/reproducers/nostr-schemas/18c960c07a1b14b0.json b/examples/reproducers/nostr-schemas/18c960c07a1b14b0.json new file mode 100644 index 00000000..4e97ff82 --- /dev/null +++ b/examples/reproducers/nostr-schemas/18c960c07a1b14b0.json @@ -0,0 +1,22 @@ +{ + "hash": "18c960c07a1b14b0", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "211f1794817bb9666b6c4efa29c91560f72ceab6cb4b64088d08d14f470996b6", + "content": "젴㨁ၱ괚æ⑑\udb40麗ሉ傯\uda90뷉呉\udae4戩廈\udfd1갓賏\uda06굦ꪉ璔믡」십쑴떣笓˸\udc5a\udae2烜\ud950䧾䍂땃挠줁鐼屎\uddc3튏锄\udd4e\ude2c傏", + "additionalTags": [ + [ + "q77wm", + "fSO71LLMPq" + ] + ], + "dTagValue": "hSAuaQM2FZ", + "eventId": "7261d7919e592b16974bc6d0c043eb6321c83d78844ea4c30357ade246032aa2", + "cxosb": 8411.55359292702 + } + }, + "timestamp": "2026-01-20T16:34:19.506Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/227e8db93b7456c9.json b/examples/reproducers/nostr-schemas/227e8db93b7456c9.json new file mode 100644 index 00000000..1dce252a --- /dev/null +++ b/examples/reproducers/nostr-schemas/227e8db93b7456c9.json @@ -0,0 +1,26 @@ +{ + "hash": "227e8db93b7456c9", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "cc401e3196abdc664a40862d3cd9025af82aa2ac55bbee7e69c7faefbd81cb74", + "created_at": 1768926859, + "content": "ꔳ幰\udbc7岽\udef9\udea2㦉땮\udeee䏓ᄁ⡏ﱳ䋯䓙\udaed굘ӹ旎⎪\udee6紌\udd16瑩Ꟈ\udf75鎍⑩ᭌ瘫ǻ刧敃摢穃翂櫵ᙾ拷젙\uddb3\udeb7씰\udc28␋\udfa4軤", + "additionalTags": [ + [ + "OGAEp", + "sCThZka3DJ" + ], + [ + "elm64", + "uN1X33bJV2" + ] + ], + "dTagValue": "OAOTVCvayE", + "eventId": "c5c0e46d9c509a99eaa7b237dd7e9741e07bf9fe424d83aaaab1f5c68ca810e3" + } + }, + "timestamp": "2026-01-20T16:34:19.531Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/2388d33b32f5dd1f.json b/examples/reproducers/nostr-schemas/2388d33b32f5dd1f.json new file mode 100644 index 00000000..72482005 --- /dev/null +++ b/examples/reproducers/nostr-schemas/2388d33b32f5dd1f.json @@ -0,0 +1,17 @@ +{ + "hash": "2388d33b32f5dd1f", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "576173493bdf93c35219b1a1e842fd06493d6ca8a7e652f37e3e9e1dfdc03a74", + "created_at": 1768926859, + "content": "薁睶\ude68㩻﵆\udd0e菕
挠\ude84tℋ䂖騺鍱\udb31ᜧά갛\udc08\udcd4㐟䗝㲳忠\uda44⯒狙뻡㩼餵睊琻塘\udfbe\udb02鱫瀭鄉\udde3삭鲢䤫圢\udb48ᗷ\ude96", + "dTagValue": "NVe9A407cH", + "eventId": "7f6cf3739e77207b2d5f9f2aacb90fac8545125e372775e551716e184e2c63f9", + "cpmtW": null + } + }, + "timestamp": "2026-01-20T16:34:19.543Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/2d038dd6ff3603e4.json b/examples/reproducers/nostr-schemas/2d038dd6ff3603e4.json new file mode 100644 index 00000000..3cf9637f --- /dev/null +++ b/examples/reproducers/nostr-schemas/2d038dd6ff3603e4.json @@ -0,0 +1,29 @@ +{ + "hash": "2d038dd6ff3603e4", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "d33cbc19b939f4c690253ba9586c0762968fb9cfcffcd085f1251441a51c737a", + "created_at": 1768926859, + "additionalTags": [ + [ + "EEL1e", + "Zr5ZuL4HR8" + ], + [ + "Q2rEl", + "tTrkEYP54t" + ], + [ + "upLL8", + "AoPmhLHLNv" + ] + ], + "dTagValue": "VR73sR2X8M", + "eventId": "87e7c3605c9a88ef9d9e3984e7e6b49d3a790e746a35bbcb3157695828615e6a" + } + }, + "timestamp": "2026-01-20T16:34:19.549Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/7d28c8f4e78c2a83.json b/examples/reproducers/nostr-schemas/7d28c8f4e78c2a83.json new file mode 100644 index 00000000..427aeccb --- /dev/null +++ b/examples/reproducers/nostr-schemas/7d28c8f4e78c2a83.json @@ -0,0 +1,26 @@ +{ + "hash": "7d28c8f4e78c2a83", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "d1f3b06f1f9ab423b6bbcb9b9b8ae956e21893bdb09feba59cc01f451e92ae95", + "content": "졹즮ﮕ냿㦫斮냲Ѻ㝫翗\udee3瑌⡚㢴\udb99刭繐시둥睧襼ﹶꃛ򙳴ꃿ哉狏騣隚䰰₤\udacf☯刴\udcc2搧\udce8㚲䜼傫ꦖ勃뱭", + "additionalTags": [ + [ + "iVEpY", + "Sm5vcAEAuR" + ], + [ + "Ui2Kv", + "C3lqEHkIIf" + ] + ], + "dTagValue": "5M3K7s1CZ3", + "eventId": "1428c4a55f48084251e0c8899f90f045b1346abfd938897aa424227d2d16ad4c", + "fJXSq": false + } + }, + "timestamp": "2026-01-20T16:34:19.508Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/85fde36936a9aa86.json b/examples/reproducers/nostr-schemas/85fde36936a9aa86.json new file mode 100644 index 00000000..146b034c --- /dev/null +++ b/examples/reproducers/nostr-schemas/85fde36936a9aa86.json @@ -0,0 +1,33 @@ +{ + "hash": "85fde36936a9aa86", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "415eaf447da61c89b247562016620bb385c07e8b870d92c7d3d799eb300a720e", + "created_at": 1768926859, + "content": "锅瘜퇍\udbf7ヨ茸\udad9ꔶ궍Ⓒ\udfdc⣶ﹰ쿃咖\uda15\ud910ྀ餂뚲\udd7d򧳇蔪冷宷拉蟒綹𮭶錅死쭽뷟掴᳓ԯ縱ꏫ㺅㨼괾᤼鯏", + "additionalTags": [ + [ + "zGn0s", + "YkXLolqsxO" + ] + ], + "dTagValue": "OvQLBvFwWi", + "eventId": "843ae1e4b92b44b37c439ebadcf3c62444dd544e266e51c45bee1535782ca20b", + "cfiJH": { + "obfx4": { + "tRVaR": "倂\udaf8\udaf2ᜑ\udf10榦\ude58Ю쫪᳑礅ꈑᛖ竣皰遐伹狍致ㅧ䙠\ud97b颢萕酂侕秀㍓〧ퟮ탛\ud951Խ繶㩎", + "oIPt2": 2116.4722459860054, + "nYQ7a": { + "tKuK2": "⏤췟蠚꛲昄팍朱Ừ㦄㲟킪௔塅\udb7b養ﭪੀꙋ珎儠罼꿇鬇ᡞ\udbde󹖏穎꣫蝿敐\udfb4⼺囱浊僵ڨ\uda97\ud8c7\ud949\ud90aᆿ\udc50\uddd6큪ꪷꁬꌉ෽⊢㇑᫟\udb2c鶬槳ᐉ룧\ud862쥰ꐞ耔륥\ude7f\udf91廢阬룾\ud9ea遼祘펰涊Ꝓᆽ󴞨﫺\udc6f𗗖狋ਸᅜ\ude1d魫碦炲붻", + "BU1mk": "㺡ฑӢ쳁ﵑ䟫됯䠝鳚\ude01◜๬\udfa2蹒⋶柵\ud8d5鱍뒮᱈䝒\ud8a0섧Ọ㊓⺉횢邗玹\udf9e碊\udbda\ud8ec涁\ude12힛别걍␵堥㢯끂ꘀ︓\udddc孭걎셽则揽林傸독\ud934䴊蔵䉡䏐뱲椠ѕ\ude01頣꼱꼿맅謹\udae2񲁨\ud808콛玵長嘦봓暆哶죕鷱", + "4oh3t": true + } + } + } + } + }, + "timestamp": "2026-01-20T16:34:19.543Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/8d1d49645b90d7ce.json b/examples/reproducers/nostr-schemas/8d1d49645b90d7ce.json new file mode 100644 index 00000000..00d35b38 --- /dev/null +++ b/examples/reproducers/nostr-schemas/8d1d49645b90d7ce.json @@ -0,0 +1,38 @@ +{ + "hash": "8d1d49645b90d7ce", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "897ba807670635e9028915f0d2a5d8dccfc3cef45dc00537013bed46915e0e2b", + "created_at": 1768926859, + "content": "寱嫤\udf71ᆲ褥齼㝃੨\ud839✈\udc53貂ꭣﵘᲬ잸⚩ڛ矈䛋ᵻ햙睡缳㙙\udd85䵇森즶┅䧊⌝လ㍼\udebfҩ뒮孴憅襖\ud987큜", + "additionalTags": [ + [ + "WX2IY", + "mpSajY2xeL" + ], + [ + "nsM2D", + "SdgpCEcGjK" + ], + [ + "3Kfhr", + "08NTDSgrSs" + ], + [ + "0QMFV", + "gNv4TRO4nD" + ], + [ + "lDdW5", + "XRC6qfbLWJ" + ] + ], + "eventId": "8afbfbd0712f801f8dbcb769e04334ebc644b5098d9811db5e64f0b079833ffd", + "9TAlG": null + } + }, + "timestamp": "2026-01-20T16:34:19.517Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/91f935834c393ec6.json b/examples/reproducers/nostr-schemas/91f935834c393ec6.json new file mode 100644 index 00000000..466fc99c --- /dev/null +++ b/examples/reproducers/nostr-schemas/91f935834c393ec6.json @@ -0,0 +1,34 @@ +{ + "hash": "91f935834c393ec6", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "407827d56783cf92690806e83584f140ac020f77863bde94b98b1be645dc754b", + "created_at": 1768926859, + "content": "괾趞劵呆쨱ꌓ⸢\uda4a艦Ꜻ瓸ʲ㴭\ud826䵌ꆪ즜뼙䝁껊맒ꉳ裟\udc48춾讄閅㛡\uddb5䲲ᴡ䥾\ude96飽ⅻ奈턍䁑鲉骆浀워\ud983멍쇳\ud9f5폘廨\udde9", + "additionalTags": [ + [ + "Hex9u", + "xuTpbZTCJZ" + ], + [ + "0Pj8H", + "xGRidktuGx" + ], + [ + "50YMk", + "L6x6dP7NuV" + ], + [ + "G6Y7w", + "rL5ziZzTJP" + ] + ], + "dTagValue": "698DG6ofzq", + "eventId": "c293397373b188cd1739673a53b3441d8366e97eec0b49ce42220d7dd52ea18d" + } + }, + "timestamp": "2026-01-20T16:34:19.532Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/9542c7dff1386872.json b/examples/reproducers/nostr-schemas/9542c7dff1386872.json new file mode 100644 index 00000000..c0ff96f7 --- /dev/null +++ b/examples/reproducers/nostr-schemas/9542c7dff1386872.json @@ -0,0 +1,31 @@ +{ + "hash": "9542c7dff1386872", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "a1f6dc0c6ed04eb5a7c445d75b235503fab159dfe2a6c81908e18de21b276629", + "created_at": 1768926859, + "content": "띬띔횎\ud92eⵡ濐椻绍笜\udbe0\ud9e4꒝꒕\udf63\ud829\uddde羠珠䤑ꎺ郔\uda35願쐝剨鲨妆璐녮\udac2夆㍬㒔঱\udc19䚝\ud9df轛㹻䛊梨骪䬼", + "additionalTags": [ + [ + "vamZy", + "GSc8LqPhma" + ], + [ + "kTMoy", + "CVvoRUIw7e" + ], + [ + "Xhqdf", + "A6DC90idgK" + ] + ], + "dTagValue": "ceP4ztRvZA", + "eventId": "6223d12f986cfb6023dec140c80720bb96457cc5847a088b02e53b606ab70e88", + "s3KNd": false + } + }, + "timestamp": "2026-01-20T16:34:19.566Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/97b4273a8fe15fbe.json b/examples/reproducers/nostr-schemas/97b4273a8fe15fbe.json new file mode 100644 index 00000000..cb5919fc --- /dev/null +++ b/examples/reproducers/nostr-schemas/97b4273a8fe15fbe.json @@ -0,0 +1,109 @@ +{ + "hash": "97b4273a8fe15fbe", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "7c3724fd1df9c80af92bbdf94217cac149df0f4d5624da9d55b9be030ef1c476", + "created_at": 1768926859, + "content": "䁟面\ude5b뷌ﺃ蛿\ud973\ud87a潟\ud9a3狱癉뢓䁞⺵敊睚蟬탯䒌ﳕ\udfd5䟜\udcc7\ud82d윷\ud926ྖ惻\ude45馍ﱩ龵魯莺ᴚ洨⣐\ude4a߸௘덻", + "additionalTags": [ + [ + "s1OI3", + "gdsJFyYpaq" + ], + [ + "ZQ69f", + "oyglX4Gl01" + ], + [ + "NlTNs", + "O1U4EsfdJB" + ], + [ + "1BSQP", + "QlFRMWP1Aw" + ], + [ + "yM5dw", + "x7MC08UOCO" + ] + ], + "eventId": "145f4a20c49b9e6eb5a5da9d080a49e346db18ef87311823bfb208ddaf99337c", + "Kta5T": { + "sjSQd": null, + "EAIXe": "\udccc踞㈧\udb24⧪幖⥼븛\udf03\uded1\udc6d쫙㬵﹥檛ꗧ榗퉳\udea8⢑緿汅묰宮\ud985夂䩃ᴣ殄䡎\uda14琽寮硫ᵪ꺀᫖곭򵘨ᒕྨ䯁Ⴐ螥䱰ﴟ\uddf6\udd6aZ汼獴攳䬎䣋\udc4b堠\udf46񃹅\udb55皒\uded7ֹ硓繌칪汴䡁\uda12Თ徝벹ꉓ㩥㙰敚\udfa3", + "shQ9t": 9712.102376936997, + "XQ27X": { + "JGJTu": { + "HkOET": [ + [ + [ + true, + null, + true + ], + { + "fO3Pp": 265.33605545970175, + "PdIMd": { + "o4z7g": 5652.840913340699, + "ViLwB": { + "T7DVJ": null, + "hEVDx": null, + "KSJNy": {}, + "Lg5pm": "듈輳\udf16ťᰭ份毽園맋乷⏥ᡙ\udb94뵺\udd79篱랁\ud8d3ᔠ菝⊍샺헡뷾㲐澴蛊⟖\udf95̭\uddca\ud8e4碄\ud828" + } + }, + "ddTzu": "", + "hAmUf": [ + { + "AxxMA": 5577.908593874583, + "kMpqu": { + "9tIb0": [ + 9373.082458292405, + 910.9792573057307, + null + ], + "KLf1v": [ + [ + true, + [ + null + ], + null + ] + ], + "7lfoe": "Ⲙ榵鐶\udf22\udeeb淽\udf41\udef7㙏\udaff\udaf8猔얒\ud8ad愽귿\udad3꤭倛׻ꢓ禈؟䵶\uda48跓鹒గ欺ﰩ䐆Ⴟ磶\ude2e킲\ud96d𽕓퇳ѱ⡘\udfe1㒖\udf8a" + } + } + ], + "kwKRg": { + "tIRii": [], + "ED8W0": "鋻뺕哓鈍彚簎먇\udd4eⰱ񊛡ꙫꂓ䏏\udc39\uda1aう\udd3e뻺\udef3욞믊\ud9b6㶶윺槠㍱㖌ᄬ틭񿹶਺\ude1c฼죲칇绌䉎ﲃ\ude5aㄸᶪ棨䂍鱌納⻇淰⢦佾␬뜃ﲣ嘵򅢞㈥녏蝧ﭯ\udeaa馩㪚\udde2ॄ㑉㱋盆ⶌ" + } + }, + { + "zu4Uv": 8618.712144946234, + "gMudq": true, + "xwA25": false + } + ] + ] + }, + "x99oQ": null, + "OVXDu": 6984.617523492656, + "GxxAh": [ + {}, + null + ], + "Mbljc": [ + false, + [] + ] + } + } + } + }, + "timestamp": "2026-01-20T16:34:19.482Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/9a68a21eb821d150.json b/examples/reproducers/nostr-schemas/9a68a21eb821d150.json new file mode 100644 index 00000000..9b3917ab --- /dev/null +++ b/examples/reproducers/nostr-schemas/9a68a21eb821d150.json @@ -0,0 +1,39 @@ +{ + "hash": "9a68a21eb821d150", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "eead25bac11265dbf5d5dc85e2a4e13475799a942db587944066a33d994dd535", + "created_at": 1768926859, + "content": "\udaa1Ĝ䗷ܬ\udf57荮\udd34࠶짽တ呦瘁埽\udec6ﳅ\ud869\udb63ẜȚ䒜냛᫬谅ꛉ\udf64濧陋\udb95㕍ɔ炩抻⩄䬄쐕潝먔獽ꪟ쓶阻ꑫ嬀⡉ᳶ", + "additionalTags": [ + [ + "707fp", + "1loFnMJca4" + ], + [ + "HhEan", + "yciSPB5wlB" + ], + [ + "0p6W5", + "5IMUKnIeic" + ], + [ + "cB5SQ", + "BXCZ7JxWkl" + ], + [ + "pt11s", + "w2TOjbcwXl" + ] + ], + "dTagValue": "exrKZf3lsj", + "eventId": "be8ee7354cbabac4647130b09d4e050f81b61e8f3182dc9357ec29fed575cac4", + "iJzUL": "삻翘㝃暞\ud977茇殸⪼닝峎땟˽蓽ᬇ\ud947智\udcffƐ䑳\udea7玖\udcafុ刯\udb8d廬ꯨ왙돕邢񟹲\udda3꠴ᢙ拘Ꜭ䁋\ud84e鱆\udd91ᷗ謷\ud980\udd70來ﱀ酐\udc0f끸噶翤ᘭ㚩ꉁ瞡䆇\ud811詔極孬팿󐾖\udb36渎䭢᪂푝ⓤ䄊\udd0a\udb03䔹雲ψ\uddce껵덹㟷鋯\uda3d낉軓\udb55\ud8a8ꦬ\udd67ߥ" + } + }, + "timestamp": "2026-01-20T16:34:19.551Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/9e2b76583d4b46cf.json b/examples/reproducers/nostr-schemas/9e2b76583d4b46cf.json new file mode 100644 index 00000000..f2d2073e --- /dev/null +++ b/examples/reproducers/nostr-schemas/9e2b76583d4b46cf.json @@ -0,0 +1,22 @@ +{ + "hash": "9e2b76583d4b46cf", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "eb2c35eeab443722897ed1add9c97202797ac45a0a58f9950de20460f30c8bad", + "created_at": 1768926859, + "content": "\udfe3죸⨘\udd6b힖䢍\udf04觚卵瀞佭\ude9aẕ䳽\ud9cd評롘잤桭貒暃꣚뛀턻뢛閕慏ᘂﮔ괵ԫ\uda4e뙤岱\ud95d雉ߒ\ud9ab悜荙怟\udc34뙦\udfda㒬㈅", + "additionalTags": [ + [ + "DuYKZ", + "PfHnMIr5Bk" + ] + ], + "dTagValue": "973aEhQQcO", + "eventId": "e1e45c178921b470bc7018c909df5c14a08907cc4468a124ac80056182bbd4db" + } + }, + "timestamp": "2026-01-20T16:34:19.541Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/a58dd9ee08c19eca.json b/examples/reproducers/nostr-schemas/a58dd9ee08c19eca.json new file mode 100644 index 00000000..87bb3104 --- /dev/null +++ b/examples/reproducers/nostr-schemas/a58dd9ee08c19eca.json @@ -0,0 +1,37 @@ +{ + "hash": "a58dd9ee08c19eca", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "29f5fc4f9ed239aa66179a85a767352536e9e0eef3f7d3e7cfa15443bd66f4b4", + "created_at": 1768926859, + "content": "壳䨘둈貍䢹ӌꙈ鱨䲗\ud949粏窞\udb56㷧跿茶\uda13ᰜ騿貸싵\udb12۩꧅鞊꾾᢯趹\udf6bꮆ㿅\udd87报㝒䢱啨\ude90⮅ึ✑記먙⦂砲문鯻瞗", + "additionalTags": [ + [ + "4kSJm", + "8PGGWlUJk7" + ], + [ + "PoqmU", + "yi5kUCLwTa" + ], + [ + "VuPQD", + "pWCxsp8Zgy" + ], + [ + "A42dG", + "aS26J6nAsP" + ] + ], + "dTagValue": "9jQxiKeSIo", + "eventId": "9b4eb0132046934e6f2507ad51e3d799038ea9b4d0610b6059bf5c33b1235115", + "CON5u": [ + 8867.612802646758 + ] + } + }, + "timestamp": "2026-01-20T16:34:19.540Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/c1a8c5dbd064fa0b.json b/examples/reproducers/nostr-schemas/c1a8c5dbd064fa0b.json new file mode 100644 index 00000000..c72ab4ed --- /dev/null +++ b/examples/reproducers/nostr-schemas/c1a8c5dbd064fa0b.json @@ -0,0 +1,22 @@ +{ + "hash": "c1a8c5dbd064fa0b", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "468deb5661f468407499e44c1a73b551625f052d35bf79f88829b0c95a288eb4", + "content": "춁俳㌻鸂\udaea꠲\udb11\udd57\uddeaፋ菅酫઒鳾㋅䥴\udefb驩ᕦ熞䤺䐐\udd21뭌츔㵻\ud885㘪㭴埳躇৬쥢軎\udcbc᪹鵓럢쓶䋸铇ꦈ\ud851", + "additionalTags": [ + [ + "tYyDa", + "KspWQJHOod" + ] + ], + "dTagValue": "vQbH1Ux6oW", + "eventId": "c2fc8377e82146d86a87d0b738e910c29ca0ba3645b82dfe807e71532c8f902b", + "9AH9x": [] + } + }, + "timestamp": "2026-01-20T16:34:19.554Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/c446637259d72e96.json b/examples/reproducers/nostr-schemas/c446637259d72e96.json new file mode 100644 index 00000000..59693ca7 --- /dev/null +++ b/examples/reproducers/nostr-schemas/c446637259d72e96.json @@ -0,0 +1,26 @@ +{ + "hash": "c446637259d72e96", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "46f6cca0676ceb29c7e448929842451213b103a3bc11ee591646bc9e55b28d7f", + "content": "€린\udd2a䵿鳷k곊廚峡\udb2b缝睐\ude22ꀔ짧忀\ud8f4떰ꗰ\udc50풬ႆ蟶\udade兞᫝\ud9e8떏楚儷䜼쐥鼶ᒜ὏䄗ꙫ᫷皲莜\ud9c4⻛ギ␊", + "additionalTags": [ + [ + "NpumS", + "ufHBSpG49L" + ], + [ + "t4p5f", + "WnzWK88bUH" + ] + ], + "dTagValue": "I0SdpsWAAn", + "eventId": "d905ec3d877e235ec34b5292b7240c4501953be24fdb017b8105402c91da7157", + "aS4ID": 1532.0835797977606 + } + }, + "timestamp": "2026-01-20T16:34:19.535Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/ca5e0379db09a508.json b/examples/reproducers/nostr-schemas/ca5e0379db09a508.json new file mode 100644 index 00000000..3fd09f56 --- /dev/null +++ b/examples/reproducers/nostr-schemas/ca5e0379db09a508.json @@ -0,0 +1,18 @@ +{ + "hash": "ca5e0379db09a508", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "61137f8c918da5e6a3efae6174d31b8870ec06b1e41ba6395fe593491106d7ec", + "created_at": 1768926859, + "content": "\ude91酭蓈\uddba鯳㶈\udd57뢫재\uda14俳皂ꥒ\udd28\udb2a㬛쬨\ud8db橥\ude01蹍隕뾣\ud81e㈖\udcd2竺\udfbb읩얏䛟읮本ᓰノ\udbe2\udff9뙰꧷퇷䶫焞\udce1\udec2஄\udb40", + "additionalTags": [], + "dTagValue": "YZMwTXBnF0", + "eventId": "160f8475a536a8af8140239d59fb0e9b130b8428d1aaf99abb48ca6aada188f9", + "DsDHJ": null + } + }, + "timestamp": "2026-01-20T16:34:19.555Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/d770efd177e76757.json b/examples/reproducers/nostr-schemas/d770efd177e76757.json new file mode 100644 index 00000000..b34e4660 --- /dev/null +++ b/examples/reproducers/nostr-schemas/d770efd177e76757.json @@ -0,0 +1,16 @@ +{ + "hash": "d770efd177e76757", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "created_at": 1768926859, + "content": "\ude79ꉋ詟\ud929\ud94d\udc4b῱⤘倳ꖨ萊䉕з忠쨌⦯ധ⊐神羈\udebc򰚩\uda86ᡵ񩉈쑰檨\ud8ee\ud875ꊛຒ敛\udd1f񊙓肿蠢둼襛✆荏", + "additionalTags": [], + "eventId": "798a916303e40319bdd0e7afcc95fdd448b4dc84501fdb8604e23d31f18a8fe4", + "pzxvb": 9780.324581105677 + } + }, + "timestamp": "2026-01-20T16:34:19.561Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/e4db9b78fcd4b2a5.json b/examples/reproducers/nostr-schemas/e4db9b78fcd4b2a5.json new file mode 100644 index 00000000..51d27850 --- /dev/null +++ b/examples/reproducers/nostr-schemas/e4db9b78fcd4b2a5.json @@ -0,0 +1,6 @@ +{ + "hash": "e4db9b78fcd4b2a5", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:23)", + "timestamp": "2026-01-20T16:32:00.400Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/e5ac4b49024a9315.json b/examples/reproducers/nostr-schemas/e5ac4b49024a9315.json new file mode 100644 index 00000000..81177d61 --- /dev/null +++ b/examples/reproducers/nostr-schemas/e5ac4b49024a9315.json @@ -0,0 +1,47 @@ +{ + "hash": "e5ac4b49024a9315", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "63a10c52b6909024935c9e0b2a2c68e3db1ea1115f2434b50a797fb559b58bca", + "created_at": 1768926859, + "additionalTags": [ + [ + "Elx3b", + "MmFA1VNdgc" + ], + [ + "I3ybr", + "XJDkDHqKnS" + ], + [ + "ktZT5", + "YVcLFQ1tgg" + ], + [ + "rViGm", + "Y58vBKHbbM" + ], + [ + "HjDaJ", + "ZY4F4o1jts" + ] + ], + "dTagValue": "CU7mmWlnIL", + "eventId": "728ee10a08594bde492cccd82af025639361b8ff608da37e5110d4bc4b98d785", + "XP1x6": [ + { + "PsmRN": [ + true + ], + "EHNwp": 872.9927942691252, + "oHHhu": "ⲉ㿙㘅磳쓿ֆ垜\ud8c7嘮ᭀᣵ򰿪\udd8d㨔\uda9d\ud933≄뎡\ude03\udaed旍菜㉉厕\udd94\udc2e쏞笒뚏\udb05ℛ鼇憑샄\udff4", + "iT9Mb": 7962.070659919705 + } + ] + } + }, + "timestamp": "2026-01-20T16:34:19.546Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/f5565f667ef0bd28.json b/examples/reproducers/nostr-schemas/f5565f667ef0bd28.json new file mode 100644 index 00000000..769e5e39 --- /dev/null +++ b/examples/reproducers/nostr-schemas/f5565f667ef0bd28.json @@ -0,0 +1,18 @@ +{ + "hash": "f5565f667ef0bd28", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "7e8b1efc8fef112e00addea54f4ff10ca29ab88ca2ab5e36a7fb0822627f2a3b", + "created_at": 1768926859, + "content": "ፂ킆ⅷ隰\ude47\udc98烥낷쪾⸛꒻ᕬ㦑屔\udef5㷣\ud8e7鄬䀟࠭ᩝ\udd6c䥶村\udffe\ud878嶁\udf84㩓䂹\ud81b㑤쇼᷒抪࿨燉䷓\udaf5哐冡\udbfa\uda10", + "additionalTags": [], + "dTagValue": "Go7SKAG4O3", + "eventId": "5374e07583039dbf7be03119c6d5e0c7ea8545ce55050620e1021b5ce7fc6924", + "M5lVs": {} + } + }, + "timestamp": "2026-01-20T16:34:19.526Z" +} \ No newline at end of file diff --git a/examples/reproducers/nostr-schemas/f5dd74590c3975b4.json b/examples/reproducers/nostr-schemas/f5dd74590c3975b4.json new file mode 100644 index 00000000..81d405bd --- /dev/null +++ b/examples/reproducers/nostr-schemas/f5dd74590c3975b4.json @@ -0,0 +1,17 @@ +{ + "hash": "f5dd74590c3975b4", + "message": "missing-event-relay", + "stack": "Error: missing-event-relay\n at buildRepostEvent (file:///app/js/nostrEventSchemas.js:869:13)\n at test (file:///app/scripts/agent/fuzz-nostr-schemas.mjs:91:9)\n at Fuzzer.runFuzzLoop (file:///app/scripts/agent/fuzz-lib.mjs:142:15)", + "input": { + "target": "buildRepostEvent", + "params": { + "pubkey": "817aa90feff264c4dd1b9eb9281aea0f683364befe1c4f19504c67730688a033", + "created_at": 1768926859, + "content": "鋈፟돞\ud857苜퀯锬\ud99f嫴䝺嵵⤓\uddce葔埤↤\ude82߁㨡䓶㶻\udad6렃腫諧䑠數䐇它ꁦ㾝紵垥ᒸ듿⡗嗸ⶹ杮\udbe6񹚑\ud828ꏮ쮡낛鿻存", + "dTagValue": "aYFKrxoRwN", + "eventId": "1b7081e18c97001a19a5777da2d877331830f925db75f72161e504d01e889a4c", + "FRqDH": {} + } + }, + "timestamp": "2026-01-20T16:34:19.529Z" +} \ No newline at end of file diff --git a/js/nostrEventSchemas.js b/js/nostrEventSchemas.js index 3f578610..e3586e84 100644 --- a/js/nostrEventSchemas.js +++ b/js/nostrEventSchemas.js @@ -865,10 +865,11 @@ export function buildRepostEvent(params) { typeof eventRelay === "string" ? eventRelay.trim() : ""; if (normalizedEventId) { - if (!normalizedEventRelay) { - throw new Error("missing-event-relay"); + if (normalizedEventRelay) { + tags.push(["e", normalizedEventId, normalizedEventRelay]); + } else { + tags.push(["e", normalizedEventId]); } - tags.push(["e", normalizedEventId, normalizedEventRelay]); } const normalizedAddress = typeof address === "string" ? address.trim() : ""; diff --git a/scripts/agent/fuzz-dm-decryptor.mjs b/scripts/agent/fuzz-dm-decryptor.mjs new file mode 100644 index 00000000..8c332dce --- /dev/null +++ b/scripts/agent/fuzz-dm-decryptor.mjs @@ -0,0 +1,72 @@ +import { Fuzzer } from "./fuzz-lib.mjs"; +import { decryptDM } from "../../js/dmDecryptor.js"; + +// Mock global dependencies +if (typeof global.window === "undefined") { + global.window = { + location: { protocol: "https:" }, + crypto: { + getRandomValues: (arr) => crypto.randomFillSync(arr), + subtle: { + digest: async (algo, data) => { + const hash = crypto.createHash("sha256").update(data).digest(); + return hash.buffer; + } + } + } + }; +} +if (typeof global.localStorage === "undefined") { + global.localStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {} + }; +} + +const fuzzer = new Fuzzer("dm-decryptor"); + +async function test(fuzzer, state) { + // Generate random event + const event = { + kind: fuzzer.randBool() ? fuzzer.pick([4, 1059]) : fuzzer.randInt(0, 20000), // 4=DM, 1059=GiftWrap + created_at: Math.floor(Date.now() / 1000), + tags: fuzzer.randArray(() => { + const tagType = fuzzer.pick(["p", "e", "encrypted"]); + if (tagType === "p") return ["p", fuzzer.randString(64, "0123456789abcdef")]; + if (tagType === "encrypted") return ["encrypted", fuzzer.pick(["nip04", "nip44", "nip44_v2"])]; + return [fuzzer.randString(5), fuzzer.randString(10)]; + }, 0, 5), + content: fuzzer.randUnicodeString(fuzzer.randInt(0, 200)), + pubkey: fuzzer.randString(64, "0123456789abcdef"), + id: fuzzer.randString(64, "0123456789abcdef") + }; + + if (fuzzer.randBool()) event.content = fuzzer.randJSON(); // Garbage content + + // Mock decryptors + const decryptors = fuzzer.randArray(() => { + return { + decrypt: async (pubkey, ciphertext) => { + if (fuzzer.randBool()) throw new Error("Decrypt failed"); + // Return random valid JSON or garbage + if (fuzzer.randBool()) return JSON.stringify(fuzzer.randJSON()); + return fuzzer.randUnicodeString(50); + }, + scheme: fuzzer.pick(["nip04", "nip44", "nip44_v2", "unknown"]), + priority: fuzzer.randInt(0, 10), + supportsGiftWrap: fuzzer.randBool() + }; + }, 0, 3); + + const context = { + actorPubkey: fuzzer.randString(64, "0123456789abcdef"), + decryptors: decryptors + }; + + state.input = { event, context }; + + await decryptDM(event, context); +} + +fuzzer.runFuzzLoop(2000, test); diff --git a/scripts/agent/fuzz-lib.mjs b/scripts/agent/fuzz-lib.mjs new file mode 100644 index 00000000..d09b08cd --- /dev/null +++ b/scripts/agent/fuzz-lib.mjs @@ -0,0 +1,190 @@ +import fs from "fs"; +import path from "path"; +import crypto from "crypto"; + +export class Fuzzer { + constructor(targetName) { + this.targetName = targetName; + this.artifactsDir = path.join(process.cwd(), "artifacts"); + this.reproducersDir = path.join(process.cwd(), "examples", "reproducers", targetName); + this.reportPath = path.join(this.artifactsDir, `fuzz-report-${targetName}.json`); + this.issues = []; + + if (!fs.existsSync(this.artifactsDir)) { + fs.mkdirSync(this.artifactsDir, { recursive: true }); + } + if (!fs.existsSync(this.reproducersDir)) { + fs.mkdirSync(this.reproducersDir, { recursive: true }); + } + } + + // Random Primitives + + randInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + randBool() { + return Math.random() < 0.5; + } + + randByte() { + return this.randInt(0, 255); + } + + randBytes(length) { + return crypto.randomBytes(length); + } + + randString(length, charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") { + let result = ""; + for (let i = 0; i < length; i++) { + result += charset.charAt(this.randInt(0, charset.length - 1)); + } + return result; + } + + randUnicodeString(length) { + let result = ""; + for (let i = 0; i < length; i++) { + // Basic multilingual plane + some surrogate pairs + if (Math.random() < 0.1) { + // High surrogate + result += String.fromCharCode(this.randInt(0xD800, 0xDBFF)); + } else if (Math.random() < 0.1) { + // Low surrogate + result += String.fromCharCode(this.randInt(0xDC00, 0xDFFF)); + } else { + result += String.fromCharCode(this.randInt(0, 0xFFFF)); + } + } + return result; + } + + randBuffer(length) { + return this.randBytes(length); + } + + // Structured Data + + randArray(generator, minLen = 0, maxLen = 10) { + const len = this.randInt(minLen, maxLen); + const arr = []; + for (let i = 0; i < len; i++) { + arr.push(generator()); + } + return arr; + } + + randObject(schema) { + const obj = {}; + for (const [key, generator] of Object.entries(schema)) { + if (Math.random() > 0.1) { // 10% chance to miss field + obj[key] = generator(); + } + } + return obj; + } + + randJSON() { + const types = ["string", "number", "object", "array", "boolean", "null"]; + const type = types[this.randInt(0, types.length - 1)]; + + switch (type) { + case "string": return this.randUnicodeString(this.randInt(0, 100)); + case "number": return Math.random() * 10000; + case "boolean": return this.randBool(); + case "null": return null; + case "array": return this.randArray(() => this.randJSON(), 0, 3); // keep depth low + case "object": { + const obj = {}; + const keys = this.randInt(0, 5); + for(let i=0; i i.hash === hash)) return; + + this.issues.push(issue); + console.error(`\n[Found Issue] ${error.message} (Hash: ${hash})`); + + // Write reproducer + const reproPath = path.join(this.reproducersDir, `${hash}.json`); + fs.writeFileSync(reproPath, JSON.stringify(issue, null, 2)); + } + + writeReport() { + const report = { + target: this.targetName, + timestamp: new Date().toISOString(), + issues: this.issues + }; + fs.writeFileSync(this.reportPath, JSON.stringify(report, null, 2)); + console.log(`Report written to ${this.reportPath}`); + if (this.issues.length > 0) { + console.log(`Found ${this.issues.length} unique issues.`); + } else { + console.log("No issues found."); + } + } +} diff --git a/scripts/agent/fuzz-magnet-utils.mjs b/scripts/agent/fuzz-magnet-utils.mjs new file mode 100644 index 00000000..a0776e3f --- /dev/null +++ b/scripts/agent/fuzz-magnet-utils.mjs @@ -0,0 +1,36 @@ +import { Fuzzer } from "./fuzz-lib.mjs"; +import { normalizeAndAugmentMagnet } from "../../js/magnetUtils.js"; + +// Mock global dependencies if needed +if (typeof global.window === "undefined") { + global.window = { + location: { protocol: "https:" } + }; +} + +const fuzzer = new Fuzzer("magnet-utils"); + +async function test(fuzzer, state) { + const rawValue = fuzzer.randBool() ? + `magnet:?xt=urn:btih:${fuzzer.randString(40, "0123456789abcdef")}&dn=${fuzzer.randString(10)}` : + fuzzer.randUnicodeString(100); + + const options = { + webSeed: fuzzer.randBool() ? fuzzer.randString(50) : fuzzer.randArray(() => fuzzer.randString(50), 0, 3), + torrentUrl: fuzzer.randBool() ? fuzzer.randString(50) : undefined, + xs: fuzzer.randBool() ? fuzzer.randString(50) : undefined, + extraTrackers: fuzzer.randArray(() => fuzzer.randString(30), 0, 5), + appProtocol: fuzzer.pick(["http:", "https:", "magnet:", "unknown:"]), + logger: () => {} // No-op logger + }; + + // Sometimes pass garbage options + if (fuzzer.randBool()) { + options.webSeed = fuzzer.randJSON(); + } + + state.input = { rawValue, options }; + normalizeAndAugmentMagnet(rawValue, options); +} + +fuzzer.runFuzzLoop(5000, test); diff --git a/scripts/agent/fuzz-nostr-schemas.mjs b/scripts/agent/fuzz-nostr-schemas.mjs new file mode 100644 index 00000000..bf5e117d --- /dev/null +++ b/scripts/agent/fuzz-nostr-schemas.mjs @@ -0,0 +1,106 @@ +import { Fuzzer } from "./fuzz-lib.mjs"; +import * as schemas from "../../js/nostrEventSchemas.js"; + +// Mock global dependencies if needed +if (typeof global.window === "undefined") { + global.window = {}; +} + +const fuzzer = new Fuzzer("nostr-schemas"); + +// Builders take a params object. +const builders = [ + "buildVideoPostEvent", + "buildVideoMirrorEvent", + "buildRepostEvent", + "buildRelayListEvent", + "buildDmRelayListEvent", + "buildProfileMetadataEvent", + "buildMuteListEvent", + "buildDmAttachmentEvent", + "buildDmReadReceiptEvent", + "buildDmTypingIndicatorEvent", + "buildViewEvent", + "buildZapRequestEvent", + "buildReactionEvent", + "buildCommentEvent", + "buildWatchHistoryEvent", + "buildSubscriptionListEvent", + "buildBlockListEvent", + "buildHashtagPreferenceEvent", +]; + +async function test(fuzzer, state) { + const action = fuzzer.randInt(0, 3); + let input = {}; + + if (action === 0) { + // Fuzz sanitizeAdditionalTags + const tags = fuzzer.randArray(() => { + if (fuzzer.randBool()) { + return fuzzer.randArray(() => fuzzer.randString(10), 0, 5); + } else { + return fuzzer.randJSON(); // Garbage + } + }, 0, 20); + input = { target: "sanitizeAdditionalTags", tags }; + state.input = input; + schemas.sanitizeAdditionalTags(tags); + + } else if (action === 1) { + // Fuzz validateEventAgainstSchema + const types = Object.keys(schemas.NOTE_TYPES); + const type = fuzzer.pick(types); + const event = { + kind: fuzzer.randInt(0, 40000), + content: fuzzer.randUnicodeString(100), + tags: fuzzer.randArray(() => fuzzer.randArray(() => fuzzer.randString(10), 0, 5), 0, 10), + pubkey: fuzzer.randString(64, "0123456789abcdef"), + created_at: Math.floor(Date.now() / 1000) + }; + + // Mutate event + if (fuzzer.randBool()) event.content = fuzzer.randJSON(); + if (fuzzer.randBool()) event.tags = "not an array"; + + input = { target: "validateEventAgainstSchema", type, event }; + state.input = input; + schemas.validateEventAgainstSchema(type, event); + + } else if (action === 2) { + // Fuzz Builders + const builderName = fuzzer.pick(builders); + const builderFn = schemas[builderName]; + + // Generate random params + const params = fuzzer.randObject({ + pubkey: () => fuzzer.randString(64, "0123456789abcdef"), + created_at: () => Math.floor(Date.now() / 1000), + content: () => fuzzer.randUnicodeString(50), + additionalTags: () => fuzzer.randArray(() => [fuzzer.randString(5), fuzzer.randString(10)], 0, 5), + dTagValue: () => fuzzer.randString(10), + eventId: () => fuzzer.randString(64, "0123456789abcdef"), + // Add more random keys that might be expected or unexpected + [fuzzer.randString(5)]: () => fuzzer.randJSON() + }); + + input = { target: builderName, params }; + state.input = input; + + if (typeof builderFn === "function") { + builderFn(params); + } + } else if (action === 3) { + // buildAdminListEvent special case + const listKey = fuzzer.pick(["moderation", "editors", "whitelist", "blacklist", fuzzer.randString(5)]); + const params = { + pubkey: fuzzer.randString(64, "0123456789abcdef"), + hexPubkeys: fuzzer.randArray(() => fuzzer.randString(64, "0123456789abcdef"), 0, 5) + }; + input = { target: "buildAdminListEvent", listKey, params }; + state.input = input; + schemas.buildAdminListEvent(listKey, params); + } +} + +fuzzer.runFuzzLoop(2000, test);