Regola
Rileva contraddittorie o impossibili logica
Codice che verifica le condizioni dopo che
già stato violate, oppure presuppone afferma
che sono impossibili dato le flusso di controllo.
Linguaggi supportati: 45+Introduzione
Si verifica una logica contraddittoria quando il codice verifica condizioni di cui si sa già, in base al flusso di controllo precedente, che sono vere o false. Ciò accade dopo una rifattorizzazione, quando l’ordine delle verifiche viene modificato, oppure quando gli sviluppatori aggiungono controlli difensivi senza comprendere quali garanzie esistano già. Una funzione che verifica if (user !== null) dopo aver chiamato user.email presenta una logica contraddittoria; il controllo di null viene eseguito troppo tardi. Queste incongruenze logiche indicano problemi più profondi nell'organizzazione del codice o una comprensione insufficiente di ciò che garantisce ciascun percorso di esecuzione.
Perché è importante
Implicazioni per la sicurezza: una convalida errata crea una pericolosa illusione di sicurezza. Quando i controlli di sicurezza vengono effettuati solo dopo che i dati sono già stati utilizzati, gli aggressori possono sfruttare il lasso di tempo che intercorre prima che avvenga la convalida. Il codice che verifica le autorizzazioni dell’utente dopo l’esecuzione di operazioni con privilegi non offre alcuna protezione effettiva, ma solo commenti fuorvianti in materia di sicurezza.
Manutenibilità del codice: una logica contraddittoria suggerisce che il codice non corrisponda al modello mentale dello sviluppatore. Qualcuno ha ritenuto necessario verificare una condizione ma l’ha inserita nel punto sbagliato, oppure il codice è stato rifattorizzato senza aggiornare i controlli correlati. I futuri manutentori non possono essere certi che la validazione sia presente dove necessario, il che li costringe a esaminare intere funzioni per comprendere quali siano le garanzie effettive.
Indicatori di bug: le condizioni impossibili raramente si presentano isolatamente. Esse segnalano problemi più profondi, quali la mancanza di una gestione degli errori, ipotesi errate sui contratti delle funzioni o un refactoring non riuscito. Un controllo che non può mai essere eseguito spesso indica che altrove manca un altro controllo che avrebbe dovuto impedire il verificarsi di tale stato.
Esempi di codice
❌ Non conforme:
function processOrder(order) {
if (!order) {
return { error: 'Order required' };
}
const total = order.items.reduce(
(sum, item) => sum + item.price,
0
);
if (order.items && order.items.length > 0) {
applyDiscount(order);
}
if (total < 0) {
throw new Error('Invalid total');
}
return { total, status: 'processed' };
}
Perché è sbagliato: Il codice chiama order.items.reduce() che va in crash se `items` è null oppure non definito, quindi verifica se gli elementi esistono in seguito. Il total < 0 Questa verifica è inoltre contraddittoria, poiché la funzione `reduce` restituisce sempre valori non negativi quando si sommano i prezzi.
✅ Conforme:
function processOrder(order) {
if (!order || !order.items || order.items.length === 0) {
return { error: 'Valid order with items required' };
}
const hasInvalidPrice = order.items.some(
item => typeof item.price !== 'number' || item.price < 0
);
if (hasInvalidPrice) {
throw new Error('Invalid item prices');
}
const total = order.items.reduce(
(sum, item) => sum + item.price,
0
);
if (order.items.length >= 5) {
applyBulkDiscount(order);
}
return { total, status: 'processed' };
}
Perché è importante: tutte le operazioni di convalida avvengono prima dell'utilizzo dei dati, i controlli vengono eseguiti in ordine logico e le condizioni rispecchiano i requisiti effettivi. La funzione convalida gli input in anticipo, quindi elabora i dati validi senza controlli ridondanti o contraddittori.
Conclusione
Effettua la convalida prima di utilizzare i dati, non dopo. Esamina le condizioni che sembrano "difensive", ovvero quelle che compaiono dopo che i dati sono già stati consultati o modificati. Durante la rifattorizzazione, aggiorna o rimuovi le convalide correlate per mantenere la coerenza logica in tutta la funzione.

