説明
明確な終了条件がないまま自身を呼び出す再帰関数は、入力によってコールスタックを使い果たしたり、実行が終わらなくなったりする場合があります。外部から呼び出せる経路では、入力やリクエスト量に応じてサービスの可用性にも影響するおそれがあります。
想定される影響
- スタックの枯渇や終わらない実行で、プログラムが停止する可能性があります。
- 入力範囲によって、処理時間やリソース使用量を予測しにくくなる場合があります。
対処方法
- 再帰呼び出しの前に、終了条件と入力範囲を検証してください。
- 再帰の深さを制限するか、反復処理へ変更してください。
例
変更前
javascript
function factorial(x) {
return x * factorial(x - 1);
}
変更後
javascript
function factorial(x) {
if (!Number.isInteger(x) || x < 0 || x > 18) {
throw new RangeError("unsupported input");
}
if (x <= 1) {
return 1;
}
return x * factorial(x - 1);
}
解説:
- 変更前: 呼び出しを止める終了条件がなく、スタックを使い果たすおそれがあります。
- 変更後: 入力範囲を検証し、基底条件で処理を終了します。上限18は、階乗を
Numberの安全な整数範囲で計算するための例です。より大きな整数が必要なら、適切な数値表現とリソース制限を使ってください。