Division or Modulo by Zero
ID |
javascript.division_by_zero |
Severity |
critical |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
arithmetic, reliability |
Description
Reports division (/) or modulo (%) operations whose right-hand side is the literal 0 (or 0.0, 0n).
Rationale
JavaScript handles division by zero in three different ways depending on operand types, and none of them are usually what the author meant:
-
n / 0returnsInfinity(or-Infinity, orNaNifnis0). -
n % 0returnsNaN. -
bigint / 0nandbigint % 0nthrow aRangeErrorat runtime.
In every case the program continues with a non-finite value or an unhandled exception, often surfacing far from the offending divide as NaN propagation or a confusing stack trace.
The one shape that is not reported is 1/0, the pre-ES6 spelling of the +Infinity sentinel (-(1/0) for -Infinity), which transpilers, polyfills and compatibility code still emit; there the Infinity is the intent. This covers only a division whose numerator is a non-zero, non-BigInt numeric literal. x/0 is still reported (nothing proves x is a non-zero number), as are 0/0 and 1%0 (both NaN, not sentinels) and 1n/0n (a RangeError).
// Bad
const rate = total / 0; // Infinity
const rem = value % 0; // NaN
const big = 10n / 0n; // throws RangeError
Remediation
Guard the divisor or compute it from a value that cannot be zero:
// Good
const rate = count === 0 ? 0 : total / count;
const rem = divisor === 0 ? 0 : value % divisor;
If the literal zero was intended as a placeholder during development, replace it with the real divisor before committing.