Irrelevanter Code
Beschreibung
Irrelevanter Code tritt auf, wenn ein Produkt Code enthält, der nicht benötigt wird - er führt keine Zustandsänderungen durch und hat keine Nebeneffekte, die Daten oder den Kontrollfluss verändern, sodass die Entfernung des Codes keine Auswirkungen auf die Funktionalität hätte. Dies umfasst toten Code (Code, der niemals ausgeführt werden kann), unbenutzte Variablen und Zuweisungen, leere Codeblöcke, unerreichbare Anweisungen und Code, der keine Auswirkung auf die Programmausgabe hat. Irrelevanter Code erhöht die Codekomplexität, verschwendet Ressourcen und kann Sicherheitsprobleme verbergen, indem er die Codeüberprüfung erschwert.
Risiko
Irrelevanter Code hat indirekte Sicherheitsauswirkungen. Toter Code kann alte Schwachstellen enthalten, die behoben zu sein scheinen, aber es nicht sind. Unbenutzte Variablen könnten sensible Daten enthalten haben. Leere Blöcke können auf fehlende Sicherheitsprüfungen hinweisen. Irrelevanter Code verschleiert die tatsächliche Programmlogik während der Überprüfung. Code-Coverage-Metriken werden durch unerreichbaren Code verzerrt. Die Wartung ist bei überschüssigem Code schwieriger. Compiler-Optimierungen können sich unerwartet verhalten. Sicherheitspatches können tote Codepfade übersehen, die später reaktiviert werden.
Lösung
Entfernen Sie allen toten und unerreichbaren Code. Löschen Sie unbenutzte Variablendeklarationen. Entfernen Sie leere Codeblöcke oder fügen Sie Kommentare hinzu, die erklären, warum sie leer sind. Verwenden Sie statische Analysetools zur Erkennung von irrelevantem Code. Aktivieren Sie Compiler-Warnungen für unbenutzte Variablen und unerreichbaren Code. Entfernen Sie auskommentierten Code - nutzen Sie stattdessen Versionskontrolle. Überprüfen und entfernen Sie veraltete Codepfade. Stellen Sie sicher, dass Code-Coverage-Tools unerreichbaren Code kennzeichnen. Pflegen Sie eine saubere Codebasis durch regelmäßige Bereinigung. Dokumentieren Sie absichtlich leere Blöcke.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Sonstiges | Bereich: Sonstiges Reduzierte Zuverlässigkeit - Irrelevanter Code kann Fehler verbergen und das System weniger zuverlässig machen. |
| Sonstiges | Bereich: Sonstiges Reduzierte Leistung - Irrelevanter Code kann dennoch Ressourcen verbrauchen (Kompilierzeit, Speicher). |
| Sonstiges | Bereich: Sonstiges Reduzierte Wartbarkeit - Zusätzlicher Code macht das System schwerer zu verstehen und zu warten. |
Beispielcode
Verwundbarer Code
// Verwundbar: Code mit mehreren Arten von irrelevantem Code
#include <string>
class UserProcessor {
public:
std::string processUser(User* user) {
std::string result;
// IRRELEVANT: Null-Zuweisung vor tatsächlicher Zuweisung
std::string s = nullptr;
// Bedingungsprüfung
if (user != nullptr) {
s = "Valid";
return s; // Frühe Rückgabe
}
// TOTER CODE: Diese Bedingung ist nach der Rückgabe unmöglich
if (s != nullptr) { // s ist hier sowieso immer null
Dead(); // Diese Funktion wird niemals ausgeführt
}
return result;
}
int calculate(int a, int b) {
// IRRELEVANT: Zuweisung ohne Verwendung überschrieben
int r = getName(); // r bekommt einen Wert
r = getNewBuffer(buf); // r sofort überschrieben - erster Wert unbenutzt
// LEERER BLOCK: Kein Code ausgeführt
if (a > 0) {
// TODO: später implementieren
}
// UNERREICHBARER CODE nach bedingungsloser Rückgabe
if (b > 0) {
return a + b;
}
return a - b;
// Dieser Code kann niemals ausgeführt werden
cleanup(); // Unerreichbar
log("Done"); // Unerreichbar
}
void authenticate(const std::string& user, const std::string& pass) {
// UNBENUTZTE VARIABLE
bool isValid; // Deklariert aber niemals verwendet
// TOTER CODE: Bedingung immer falsch
if (false) {
// Alter Authentifizierungscode - sollte gelöscht werden
oldAuthMethod(user, pass);
}
// Tatsächliche Authentifizierung
newAuthMethod(user, pass);
}
void processData(Data* data) {
// IRRELEVANT: Selbstzuweisung
data->value = data->value;
// IRRELEVANT: Nutzloser Vergleich
if (data->value == data->value) { // Immer wahr
process(data);
}
// AUSKOMMENTIERTER CODE: Sollte gelöscht oder Versionskontrolle verwendet werden
// if (data->needsValidation) {
// validateData(data);
// }
// IRRELEVANT: Konstante Bedingung
int x = 5;
if (x == 5) { // Immer wahr
doSomething();
}
}
};
# Verwundbar: Python mit irrelevantem Code
def process_order(order):
"""Bestellung verarbeiten mit verschiedenen irrelevanten Code-Mustern."""
# UNBENUTZTE VARIABLE
temp_result = None # Niemals verwendet
# TOTER CODE: Unerreichbar nach return
if not order:
return None
print("Order is invalid") # Wird niemals ausgeführt
# LEERER EXCEPT-BLOCK
try:
validate_order(order)
except ValidationError:
pass # Schluckt Fehler stillschweigend - wahrscheinlich ein Bug
# IRRELEVANT: Zuweisung überschrieben
status = "pending" # Dieser Wert wird niemals verwendet
status = calculate_status(order) # Sofort überschrieben
# TOTER CODE: Bedingung immer falsch
if False:
# Alter Code, der gelöscht werden sollte
legacy_process(order)
# IRRELEVANT: Vergleich mit sich selbst
if order.id == order.id: # Immer wahr
process_payment(order)
# UNBENUTZTER IMPORT (wäre am Anfang der Datei)
# import unused_module # Niemals verwendet
# TOTER CODE: Nach bedingungsloser Rückgabe
for item in order.items:
if item.quantity <= 0:
return Error("Invalid quantity")
log_error(item) # Wird niemals ausgeführt
# IRRELEVANT: Konstanter Ausdruck
DEBUG = False
if DEBUG: # Niemals wahr in diesem Code
print_debug_info(order)
return Success(order)
def authenticate(username, password):
"""Authentifizierung mit irrelevantem Code."""
# TOTER CODE: Unmögliche Bedingung
if username is None and username is not None:
# Dies kann niemals ausgeführt werden
handle_impossible_case()
# LEERER FUNKTIONSKÖRPER der etwas tun sollte
validate_input() # Tut nichts (siehe unten)
# Tatsächliche Auth-Logik
return check_credentials(username, password)
def validate_input():
"""Leere Funktion - sollte entweder etwas tun oder entfernt werden."""
pass # Tut nichts!
# TOTER CODE: Funktion wird niemals aufgerufen
def old_process_method(data):
"""Diese Funktion wird nirgendwo aufgerufen."""
return legacy_transform(data)
# IRRELEVANT: Klasse ohne Verhalten
class EmptyHandler:
"""Handler der nichts tut - sollte entfernt werden."""
pass
// Verwundbar: Java mit irrelevantem Code
public class PaymentProcessor {
// UNBENUTZTES FELD
private String unusedConfig; // Niemals gelesen oder geschrieben
public PaymentResult process(Payment payment) {
// UNBENUTZTE VARIABLE
PaymentResult tempResult;
// TOTER CODE: Immer falsch
if (1 == 2) {
// Alte Zahlungsmethode - sollte gelöscht werden
return oldProcess(payment);
}
// IRRELEVANT: Zuweisung dann sofortige Neuzuweisung
String status = "unknown"; // Wert wird niemals verwendet
status = validatePayment(payment);
// LEERER IF-BLOCK
if (payment.getAmount() > 10000) {
// TODO: Betrugsüberprüfung hinzufügen
}
// UNERREICHBARER CODE
if (status.equals("valid")) {
return executePayment(payment);
} else {
return PaymentResult.failure("Invalid");
}
// Alles darunter ist unerreichbar
logTransaction(payment); // Toter Code
notifyCustomer(payment); // Toter Code
}
// TOTER CODE: Methode wird niemals aufgerufen
private void legacyCleanup() {
// Diese gesamte Methode wird niemals aufgerufen
System.out.println("Cleaning up...");
}
public void handleError(Exception e) {
// LEERER CATCH-BLOCK - Ausnahme verschluckt
try {
processError(e);
} catch (ProcessingException pe) {
// Sollte behandelt oder weitergereicht werden, nicht ignoriert
}
}
// IRRELEVANT: Methode die nichts tut
public void validate(Payment payment) {
// Leerer Methodenkörper - sinnloser Aufruf
}
public void auditLog(Transaction tx) {
// TOTER CODE: Konstante Bedingung
final boolean AUDIT_ENABLED = false;
if (AUDIT_ENABLED) {
// Dieser Code wird niemals ausgeführt
writeAuditLog(tx);
}
}
}
Lösung
// Behoben: Sauberer Code ohne irrelevante Abschnitte
#include <string>
#include <optional>
class UserProcessor {
public:
std::optional<std::string> processUser(User* user) {
// Klare, direkte Logik - kein irrelevanter Code
if (user != nullptr) {
return "Valid";
}
return std::nullopt;
}
int calculate(int a, int b) {
// Ergebnis direkt verwenden - keine unbenutzten Zuweisungen
int result = processInput(a, b);
// Nicht-leerer Block mit tatsächlicher Logik
if (a > 0) {
result = applyPositiveModifier(result);
}
// Einzelner klarer Rückgabepfad
return (b > 0) ? a + b : a - b;
}
bool authenticate(const std::string& user, const std::string& pass) {
// Variable wird verwendet
bool isValid = newAuthMethod(user, pass);
// Ergebnis protokollieren
logAuthAttempt(user, isValid);
return isValid;
}
void processData(Data* data) {
// Nur direkte, sinnvolle Operationen
if (data->needsValidation) {
validateData(data);
}
process(data);
}
};
# Behoben: Sauberer Python-Code
def process_order(order):
"""Bestellung mit sauberem, relevantem Code verarbeiten."""
if not order:
return None
try:
validate_order(order)
except ValidationError as e:
# Fehler ordnungsgemäß behandeln statt ignorieren
log_error(f"Validierung fehlgeschlagen: {e}")
return Error(str(e))
# Variable wird verwendet
status = calculate_status(order)
# Zahlung verarbeiten
process_payment(order)
# Artikel prüfen
for item in order.items:
if item.quantity <= 0:
log_error(f"Ungültige Menge für Artikel: {item}")
return Error("Invalid quantity")
return Success(order)
def authenticate(username, password):
"""Saubere Authentifizierungsfunktion."""
# Eingabevalidierung die tatsächlich etwas tut
if not username or not password:
raise ValueError("Benutzername und Passwort erforderlich")
return check_credentials(username, password)
# Entfernt: validate_input() - leere Funktion gelöscht
# Entfernt: old_process_method() - niemals aufgerufen, gelöscht
# Entfernt: EmptyHandler-Klasse - leere Klasse gelöscht
// Behoben: Sauberer Java-Code
public class PaymentProcessor {
// Unbenutztes Feld entfernt
public PaymentResult process(Payment payment) {
// Direkte Zuweisung - Wert wird verwendet
String status = validatePayment(payment);
// Nicht-leerer Block mit tatsächlicher Implementierung
if (payment.getAmount() > 10000) {
FraudCheckResult fraudCheck = checkForFraud(payment);
if (fraudCheck.isSuspicious()) {
return PaymentResult.requiresReview("Hoher Betrag markiert");
}
}
// Klare bedingte Rückgabe
if (status.equals("valid")) {
PaymentResult result = executePayment(payment);
logTransaction(payment, result); // Code ist erreichbar und wird ausgeführt
notifyCustomer(payment, result);
return result;
} else {
return PaymentResult.failure("Invalid");
}
}
// legacyCleanup() entfernt - niemals aufgerufen
public void handleError(Exception e) {
try {
processError(e);
} catch (ProcessingException pe) {
// Ausnahme ordnungsgemäß behandeln
logger.error("Fehler bei Verarbeitung: " + pe.getMessage(), pe);
throw new RuntimeException("Verarbeitung fehlgeschlagen", pe);
}
}
// validate()-Methode hat jetzt tatsächliche Implementierung
public void validate(Payment payment) {
if (payment == null) {
throw new IllegalArgumentException("Zahlung darf nicht null sein");
}
if (payment.getAmount() <= 0) {
throw new ValidationException("Ungültiger Zahlungsbetrag");
}
// Zusätzliche Validierung...
}
// Audit-Logging durch Konfiguration gesteuert, nicht durch tote Konstante
public void auditLog(Transaction tx) {
if (config.isAuditEnabled()) {
writeAuditLog(tx);
}
}
}
CVE-Beispiele
Diese CWE ist für die direkte CVE-Zuordnung als VERBOTEN markiert, da sie ein Codequalitätsproblem darstellt und keine direkte Sicherheitsschwachstelle.
Verwandte CWEs
- CWE-710: Unsachgemäße Einhaltung von Codierungsstandards (übergeordnet)
- CWE-561: Toter Code (untergeordnet)
- CWE-563: Zuweisung an Variable ohne Verwendung (untergeordnet)
- CWE-1071: Leerer Codeblock (untergeordnet)
Referenzen
- MITRE Corporation. "CWE-1164: Irrelevant Code." https://cwe.mitre.org/data/definitions/1164.html
- "Clean Code" von Robert C. Martin - Eliminierung von totem Code
- Statische Analysetools zur Erkennung von totem Code