summaryrefslogtreecommitdiffstats
path: root/test/fuzzing/fuzz.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/fuzzing/fuzz.js')
-rw-r--r--test/fuzzing/fuzz.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/fuzzing/fuzz.js b/test/fuzzing/fuzz.js
new file mode 100644
index 0000000..c268178
--- /dev/null
+++ b/test/fuzzing/fuzz.js
@@ -0,0 +1,66 @@
+'use strict'
+
+const net = require('net')
+const fs = require('fs/promises')
+const path = require('path')
+const serverFuzzFnMap = require('./server')
+const clientFuzzFnMap = require('./client')
+
+const port = process.env.PORT || 0
+const timeout = parseInt(process.env.TIMEOUT, 10) || 300_000 // 5 minutes by default
+
+const netServer = net.createServer((socket) => {
+ socket.on('data', (data) => {
+ // Select server fuzz fn
+ const serverFuzzFns = Object.values(serverFuzzFnMap)
+ const serverFuzzFn = serverFuzzFns[Math.floor(Math.random() * serverFuzzFns.length)]
+
+ serverFuzzFn(socket, data)
+ })
+})
+const waitForNetServer = netServer.listen(port)
+
+// Set script to exit gracefully after a set period of time.
+const timer = setTimeout(() => {
+ process.kill(process.pid, 'SIGINT')
+}, timeout)
+
+async function writeResults (resultsPath, data) {
+ try {
+ await fs.writeFile(resultsPath, JSON.stringify(data, null, 2))
+ console.log(`=== Written results to ${resultsPath} ===`)
+ } catch (err) {
+ console.log(`=== Unable to write results to ${resultsPath}`, err, '===')
+ }
+}
+
+async function fuzz (buf) {
+ // Wait for net server to be ready
+ await waitForNetServer
+
+ // Select client fuzz fn based on the buf input
+ await Promise.all(
+ Object.entries(clientFuzzFnMap).map(async ([clientFuzzFnName, clientFuzzFn]) => {
+ const results = {}
+ try {
+ await clientFuzzFn(netServer, results, buf)
+ } catch (err) {
+ clearTimeout(timer)
+ const output = { clientFuzzFnName, buf: { raw: buf, string: buf.toString() }, raw: JSON.stringify({ clientFuzzFnName, buf: { raw: buf, string: buf.toString() }, err, ...results }), err, ...results }
+
+ console.log(`=== Failed fuzz ${clientFuzzFnName} with input '${buf}' ===`)
+ console.log('=== Fuzz results start ===')
+ console.log(output)
+ console.log('=== Fuzz results end ===')
+
+ await writeResults(path.resolve(`fuzz-results-${Date.now()}.json`), output)
+
+ throw err
+ }
+ })
+ )
+}
+
+module.exports = {
+ fuzz
+}