summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rwxr-xr-xrtt-module.js20
2 files changed, 21 insertions, 1 deletions
diff --git a/README.md b/README.md
index af5aa6c..f1d884f 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ It uses [Jazzer.js](https://github.com/CodeIntelligenceTesting/jazzer.js/) as a
Fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. With rtt-fuzzer you can test the rules for any RTT module. It will play random moves and check for unexpected errors.
Currently rtt-fuzzer can detect the following errors:
-* A game taking an excessive number of steps, this could indicate infinite loops and other logical flaws in the rules. By default it will accept up to 2048 action steps, but that is configurable via the `MAX_STEPS` environment variable.
+* A game taking an excessive number of steps, this could indicate infinite loops and other logical flaws in the rules. This is configurable via the `MAX_STEPS` environment variable, set it to a positive value to crash and to a negative value to skip & ignore.
* Dead-end game states where no other actions are available (besides `undo`).
* Any crashes of the rules.js module
diff --git a/rtt-module.js b/rtt-module.js
index b1df281..b7e727d 100755
--- a/rtt-module.js
+++ b/rtt-module.js
@@ -8,6 +8,7 @@ const { FuzzedDataProvider } = require("@jazzer.js/core")
const RULES_JS_FILE = process.env.RTT_RULES || "rules.js"
const NO_UNDO = process.env.NO_UNDO === 'true'
const NO_SCHEMA = process.env.NO_SCHEMA === 'true'
+const MAX_STEPS = parseInt(process.env.MAX_STEPS || 0)
console.log(`Loading rtt-fuzzer RTT_RULES='${RULES_JS_FILE}'`)
if (!fs.existsSync(RULES_JS_FILE)) {
@@ -48,6 +49,12 @@ module.exports.fuzz = function(fuzzerInputData) {
// insufficient bytes to continue
return
}
+
+ if (MAX_STEPS < 0 && step > -MAX_STEPS) {
+ // Skip & ignore if we reach the limit
+ return
+ }
+
let active = state.active
if (active === 'Both' || active === 'All') {
// If multiple players can act, we'll pick a random player to go first.
@@ -62,6 +69,11 @@ module.exports.fuzz = function(fuzzerInputData) {
throw new RulesCrashError(e, e.stack)
}
+ if (MAX_STEPS > 0 && step > MAX_STEPS) {
+ log_crash(game_setup, state, view, step, active)
+ throw new MaxStepError("MAX_STEPS reached")
+ }
+
if (rules_view_schema && !rules_view_schema(view)) {
log_crash(game_setup, state, view, step, active)
console.log(rules_view_schema.errors)
@@ -100,6 +112,7 @@ module.exports.fuzz = function(fuzzerInputData) {
log_crash(game_setup, state, view, step, active)
throw new NoMoreActionsError("No more actions to take (besides undo)")
}
+
let action = data.pickValue(Object.keys(actions))
let args = actions[action]
@@ -147,6 +160,13 @@ class UnknownStateError extends Error {
}
}
+class MaxStepError extends Error {
+ constructor(message) {
+ super(message)
+ this.name = "MaxStepError"
+ }
+}
+
class NoMoreActionsError extends Error {
constructor(message) {
super(message)