The Task That Ran Out of Stack — JavaScript Bug Hunt

Modelled on the findings in the Toyota unintended-acceleration case (Bookout v.

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Hard
  • Concepts: Recursion, Resource Limits
  • Modelled on: Toyota ETCS · Bookout 2013
  • Visible tests: a shallow graph sums correctly; a too-deep graph fails safe instead of crashing
  • Reward: 50 XP for a complete fix

Briefing

Modelled on the findings in the Toyota unintended-acceleration case (Bookout v. Toyota, 2013): the engine control software's stack usage was far larger than analysed, and there was no protection when it overflowed — a task could die silently and leave the throttle in its last commanded state.

ecu.js walks a nested task graph recursively with no depth limit and no fallback if the walk fails.

Fix computeThrottle so deep graphs cannot blow the stack, and a failed evaluation returns the safe default rather than the last value.

Bug report

BUG-ETCS · Priority: Critical (safety) · Reported by: powertrain

computeThrottle(graph, maxDepth) must:

  • sum the demand of every node in the tree
  • refuse graphs deeper than maxDepth, returning { ok: false, throttle: 0 }
  • return { ok: true, throttle: <sum> } otherwise

Observed: a deeply nested graph overflows the stack. The caller keeps the previous throttle value, which on the road means the pedal stops responding.

Logs

[ecu] RangeError: Maximum call stack size exceeded at depth 11
[ecu] throttle held at last commanded value

The code as shipped

src/ecu/ecu.js (editable)

// Sums the demand across the task graph.
function walk(node) {
  var total = node.demand;
  for (var i = 0; i < node.children.length; i++) {
    total += walk(node.children[i]);
  }
  return total;
}

exports.computeThrottle = function (graph, maxDepth) {
  return { ok: true, throttle: walk(graph) };
};

Read-only context: src/ecu/SAFETY.js.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.