diff --git a/application/controllers/RiskController.php b/application/controllers/RiskController.php index e0c162e..3de9435 100644 --- a/application/controllers/RiskController.php +++ b/application/controllers/RiskController.php @@ -340,6 +340,12 @@ class RiskController extends BaseController $this->jsonError('Rischio non trovato', 404, 'NOT_FOUND'); } + // Limiti coerenti con le colonne DB per evitare overflow: + // fair_tef_* DECIMAL(10,2) -> max ~99.999.999 | fair_lm_* DECIMAL(14,2) -> max ~999 mld + // ale_* DECIMAL(16,2). Cappiamo TEF e Loss Magnitude a valori realistici così che + // ALE = TEF * vuln * LM resti entro DECIMAL(16,2). + $TEF_MAX = 1000000.0; // 1M eventi/anno (limite prudenziale) + $LM_MAX = 1000000000000.0; // 1.000 mld EUR per evento $params = [ 'tef_min' => (float) $this->getParam('tef_min', 0), 'tef_ml' => (float) $this->getParam('tef_ml', 0), @@ -349,6 +355,25 @@ class RiskController extends BaseController 'lm_ml' => (float) $this->getParam('lm_ml', 0), 'lm_max' => (float) $this->getParam('lm_max', 0), ]; + // Validazione: niente valori negativi o NaN/inf + foreach ($params as $k => $v) { + if (!is_finite($v) || $v < 0) { + $this->jsonError("Parametro FAIR non valido: {$k}", 422, 'INVALID_FAIR_PARAM'); + } + } + foreach (['tef_min', 'tef_ml', 'tef_max'] as $k) { + if ($params[$k] > $TEF_MAX) { + $this->jsonError("Frequenza eventi ({$k}) oltre il limite ammesso ({$TEF_MAX})", 422, 'FAIR_OUT_OF_RANGE'); + } + } + foreach (['lm_min', 'lm_ml', 'lm_max'] as $k) { + if ($params[$k] > $LM_MAX) { + $this->jsonError("Magnitudo di perdita ({$k}) oltre il limite ammesso ({$LM_MAX})", 422, 'FAIR_OUT_OF_RANGE'); + } + } + if ($params['vuln'] > 1) { + $this->jsonError('La vulnerabilità deve essere compresa tra 0 e 1', 422, 'FAIR_OUT_OF_RANGE'); + } $iterations = (int) $this->getParam('iterations', FairService::DEFAULT_ITERATIONS); $sim = FairService::simulate($params, $iterations);