MAINT010-infinite-loop-no-exit — Infinite loop with no exit
| Property | Value |
|---|---|
| Dimension | Maintainability |
| Severity | High |
| CWE | CWE-835 |
| Languages | Rust, Python, JavaScript, TypeScript |
What it detects
Flags unconditional infinite loops whose body, at the same nesting depth, contains no reachable exit statement.
- Rust:
loop {}expressions where the body (excluding nestedloop {},for,while, and closure bodies) contains nobreak,return, or diverging macro (panic!,unreachable!,todo!,unimplemented!). - Python:
while True:statements where the body (excluding nestedwhile,for,async for, function def, or class def bodies) contains nobreak,return,raise, or call tosys.exit/exit/os._exit. - JS/TS:
while (true) {}orfor (;;) {}statements where the body (excluding nested loops and function bodies) contains nobreak,return,throw, or call toprocess.exit.
Skips (intentional exclusions):
break/return/throwinside a nested loop or function body — these target the inner scope, not the outer loop.- Closures in Rust — their
returnreturns from the closure, not the enclosing loop.
Why it matters
An unconditional infinite loop with no exit will spin forever, consuming 100% of a CPU core and preventing any other work from being scheduled. In server software this causes a denial-of-service. In embedded or real-time systems it can cause a watchdog reset. In single-threaded runtimes it locks the entire event loop (CWE-835).
Examples — flagged
Python:
def spin():
while True:
x += 1 # no break, return, or raise — spins forever
Rust:
fn spin() {
loop {
x += 1; // no break, return, or panic! — spins forever
}
}
JavaScript / TypeScript:
while (true) {
x++; // no break, return, or throw — spins forever
}
for (;;) {
x++; // same
}
Examples — not flagged
Python (has break):
while True:
if condition:
break
Rust (has return):
loop {
return;
}
JS/TS (has throw):
for (;;) {
throw new Error("unreachable");
}
Rust (inner break does not count for outer loop):
loop {
for _ in 0..10 {
break; // this break targets the for loop
}
// outer loop still has no exit — DOES fire
}
Fix guidance
- Add a termination condition: Use
if condition { break; }(Rust/JS) orif condition: break(Python). - Return from the function: If the loop is at the end of a function,
returnterminates both the loop and the function. - Throw or raise: Use
throw new Error(...)(JS/TS) orraise RuntimeError(...)(Python) if the loop reaching the end is a programmer error. - Document intentional infinite loops: If the loop is genuinely intended to run forever (e.g. a server event loop), add a
// SAFETY: intentional server loopcomment (Rust) or# intentional server loopcomment (Python/JS) to make the intent clear. Consider suppressing the finding with azuit-ignorecomment.
Configuration
No configuration knobs in v1.
Implementation
crates/zuit-lang-rust/src/analyzers/infinite_loop_no_exit.rscrates/zuit-lang-python/src/analyzers/infinite_loop_no_exit.rscrates/zuit-lang-js/src/analyzers/infinite_loop_no_exit.rs