Règle
Détecter contradictoire ou impossible logique
Code qui vérifie conditions après qu'elles
déjà violées violées, ou supposent que les États
que sont impossible étant donné le contrôle .
Langues prises en charge : 45+Introduction
Une logique contradictoire apparaît lorsque le code vérifie des conditions déjà connues comme vraies ou fausses en fonction du flux de contrôle précédent. Cela se produit après un refactoring lorsque la validation est réordonnée, ou lorsque les développeurs ajoutent des vérifications défensives sans comprendre les garanties déjà existantes. Une fonction qui vérifie if (user !== null) après avoir appelé user.email contient une logique contradictoire, la vérification de nullité arrivant trop tard. Ces impossibilités logiques révèlent des problèmes plus profonds d'organisation du code ou un manque de compréhension de ce que chaque chemin d'exécution garantit.
Pourquoi c'est important
Implications de sécurité : Une fausse validation crée une dangereuse illusion de sécurité. Lorsque les vérifications de sécurité apparaissent après que les données ont déjà été utilisées, les attaquants peuvent exploiter la fenêtre avant que la validation ne se produise. Le code qui valide les permissions utilisateur après l'exécution d'opérations privilégiées n'offre aucune protection réelle, seulement des commentaires trompeurs sur la sécurité.
Maintenabilité du code : Une logique contradictoire suggère que le code ne correspond pas au modèle mental du développeur. Quelqu'un a pensé qu'une condition devait être vérifiée mais l'a mal placée, ou le code a été refactorisé sans mettre à jour les vérifications associées. Les futurs mainteneurs ne peuvent pas être sûrs que la validation existe là où elle est nécessaire, les obligeant à parcourir des fonctions entières pour comprendre les garanties réelles.
Indicateurs de bug : Les conditions impossibles existent rarement de manière isolée. Elles signalent des problèmes plus profonds comme une gestion d'erreurs manquante, des hypothèses incorrectes sur les contrats de fonction ou un refactoring échoué. Un contrôle qui ne peut jamais s'exécuter signifie souvent qu'un autre contrôle est manquant ailleurs et aurait dû empêcher cet état.
Exemples de code
❌ 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' };
}
Pourquoi c'est incorrect : Le code appelle order.items.reduce() qui plante si les éléments sont null ou non défini, puis vérifie si les éléments existent par la suite. Le total < 0 La vérification est également contradictoire car la fonction reduce renvoie toujours des valeurs non négatives lors de la somme des prix.
✅ 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' };
}
Pourquoi c'est important : Toute la validation a lieu avant l'utilisation des données, les vérifications se déroulent dans un ordre logique et les conditions reflètent les exigences réelles. La fonction valide les entrées en amont, puis traite les données valides sans vérifications redondantes ou contradictoires.
Conclusion
Placez la validation avant d'utiliser les données, pas après. Examinez les conditions qui semblent défensives mais apparaissent après que les données ont déjà été accédées ou modifiées. Lors du refactoring, mettez à jour ou supprimez les validations associées pour maintenir une cohérence logique dans toute la fonction.
.avif)
