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

AuswirkungDetails
SonstigesBereich: Sonstiges

Reduzierte Zuverlässigkeit - Irrelevanter Code kann Fehler verbergen und das System weniger zuverlässig machen.
SonstigesBereich: Sonstiges

Reduzierte Leistung - Irrelevanter Code kann dennoch Ressourcen verbrauchen (Kompilierzeit, Speicher).
SonstigesBereich: 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

  1. MITRE Corporation. "CWE-1164: Irrelevant Code." https://cwe.mitre.org/data/definitions/1164.html
  2. "Clean Code" von Robert C. Martin - Eliminierung von totem Code
  3. Statische Analysetools zur Erkennung von totem Code