Aikido

Come individuare ed eliminare il codice morto non raggiungibile

Leggibilità

Regola
Rimuovi non raggiungibili inattivi codice
Non raggiungibile codice è confuso, non verificabile,
e dovrebbe essere eliminato.

Lingue supportate: 45+

Introduzione

Il codice non raggiungibile indica una logica errata nel tuo codice. Il codice dopo return oppure lanciare Le istruzioni sono state scritte per essere eseguite, ma non vengono mai eseguite. Le condizioni che risultano sempre false nascondono una validazione o una gestione degli errori che non viene mai attivata. I rami che la logica non raggiunge mai a causa del flusso di controllo contengono funzionalità che non possono essere eseguite. Quando si individua del codice irraggiungibile, si è individuato un bug per cui il codice non sta facendo ciò che avrebbe dovuto fare.

Perché è importante

Vulnerabilità di sicurezza: I controlli di sicurezza non accessibili non proteggono la tua applicazione. Se l'autenticazione, l'autorizzazione o la convalida degli input vengono eseguite dopo un return Come hai detto, il tuo codice sembra sicuro ma in realtà non lo è. Gli hacker possono sfruttare funzioni che sembrano dotate di misure di sicurezza ma che in realtà le aggirano. Durante la revisione del codice queste vulnerabilità potrebbero sfuggire, poiché la logica di sicurezza è presente nel codice, ma non viene mai eseguita.

Errori logici in produzione: il codice morto significa che la funzione non sta implementando la logica che si ritiene stia implementando. Una validazione che non viene mai eseguita lascia passare dati non validi. Una gestione degli errori non raggiungibile fa sì che gli errori si propaghino senza essere intercettati. Le regole di business che vengono aggirate producono risultati errati. Il codice sembra corretto ma si comporta in modo diverso da quanto previsto.Lacune nei test: il codice irraggiungibile non può essere testato. Se la tua suite di test supera i controlli nonostante il codice critico sia irraggiungibile, significa che non disponi di test che coprano quei percorsi. Il codice irraggiungibile rivela lacune nella copertura dei test, dove esiste una logica importante ma non ci sono test che verifichino il suo funzionamento.

Impatto sulle dimensioni del bundle: il codice non raggiungibile viene comunque distribuito agli utenti come peso morto nel bundle JavaScript. Gli utenti scaricano e analizzano codice che non viene mai eseguito, ma questo aspetto è secondario rispetto ai bug logici che il codice morto indica.

Esempi di codice

❌ Non conforme:

function transferFunds(fromAccount, toAccount, amount) {
    if (!fromAccount || !toAccount) {
        return { success: false, error: 'Invalid accounts' };
    }

    if (amount <= 0) {
        return { success: false, error: 'Invalid amount' };
        logSuspiciousActivity(fromAccount, amount);
    }

    const balance = getBalance(fromAccount);
    if (balance >= amount) {
        deductFunds(fromAccount, amount);
        addFunds(toAccount, amount);
        return { success: true };
    }

    return { success: false, error: 'Insufficient funds' };

    // Check for fraud patterns
    if (isHighRiskTransaction(fromAccount, toAccount, amount)) {
        notifyFraudTeam(fromAccount, toAccount, amount);
        return { success: false, error: 'Transaction blocked' };
    }
}

Perché è sbagliato: la logica di rilevamento delle frodi non viene mai eseguita perché la funzione termina prima di raggiungerla. Anche la registrazione delle attività sospette dopo la verifica dell'importo non viene mai eseguita. Questa funzione sembra prevedere misure di sicurezza, ma in realtà elabora tutti i trasferimenti senza effettuare controlli antifrode.

✅ Conforme:

function transferFunds(fromAccount, toAccount, amount) {
    if (!fromAccount || !toAccount) {
        return { success: false, error: 'Invalid accounts' };
    }

    if (amount <= 0) {
        logSuspiciousActivity(fromAccount, amount);
        return { success: false, error: 'Invalid amount' };
    }

    if (isHighRiskTransaction(fromAccount, toAccount, amount)) {
        notifyFraudTeam(fromAccount, toAccount, amount);
        return { success: false, error: 'Transaction blocked' };
    }

    const balance = getBalance(fromAccount);
    if (balance >= amount) {
        deductFunds(fromAccount, amount);
        addFunds(toAccount, amount);
        return { success: true };
    }

    return { success: false, error: 'Insufficient funds' };
}

Perché è importante: tutti i controlli di sicurezza vengono eseguiti prima dell'elaborazione del trasferimento. Il rilevamento delle frodi viene effettuato su ogni transazione. Le attività sospette vengono registrate. La funzione implementa la logica di sicurezza che sembra avere.

Conclusione

Il codice irraggiungibile indica la presenza di bug nella logica del codice, per cui la funzionalità prevista non viene mai eseguita. Individualalo utilizzando strumenti di analisi statica nella tua pipeline di CI e consideralo un problema critico, non solo un’operazione di pulizia del codice. Quando individui del codice irraggiungibile, cerca di capire perché è presente e quale logica avrebbe dovuto essere eseguita ma non lo è.

Domande frequenti

Hai delle domande?

Come posso individuare il codice non raggiungibile in codebase di grandi dimensioni?

Gli strumenti di analisi statica sono in grado di individuare casi evidenti, come il codice che segue le istruzioni `return` o `throw`. Per i casi più complessi, utilizzare strumenti di copertura del codice durante la fase di test. Il codice che presenta una copertura pari a zero in tutte le esecuzioni dei test potrebbe essere irraggiungibile. Esaminare manualmente ogni singolo caso, poiché parte del codice potrebbe essere raggiungibile ma semplicemente non testata.

E il codice che segue i ritorni anticipati nei blocchi try-catch?

Il codice che si trova dopo un'istruzione `return` all'interno di un blocco `try`, ma prima di `finally`, è irraggiungibile. Tuttavia, i blocchi `finally` vengono sempre eseguiti anche dopo un'istruzione `return`. Errore comune: inserire operazioni di pulizia importanti dopo l'istruzione `return` all'interno di un blocco `try`, anziché nel blocco `finally`, dove verrebbero effettivamente eseguite.

Il codice non raggiungibile può causare errori di esecuzione?

No, perché non viene mai eseguito. Tuttavia, può fare riferimento a variabili non definite o chiamare funzioni inesistenti senza generare errori, il che lo rende ancora più insidioso. Questo codice difettoso supera tutti i test perché non viene mai eseguito, ma induce in errore chiunque legga il codice sorgente.

E per quanto riguarda i feature flag e la compilazione condizionale?

Il codice sottostante ai flag di funzionalità disabilitati è raggiungibile in fase di esecuzione anche se disabilitato nell'ambiente corrente. Il codice realmente irraggiungibile è strutturalmente impossibile da eseguire a causa del flusso di controllo. Il codice associato ai flag di funzionalità è raggiungibile in modo condizionale e dovrebbe rimanere fino a quando la funzionalità non viene completamente rimossa.

È opportuno rimuovere le funzioni e le importazioni inutilizzate?

Sì, ma si tratta di una categoria diversa di codice morto. Il codice irraggiungibile è strutturalmente impossibile da eseguire a causa del flusso di controllo. Le funzioni inutilizzate sono raggiungibili ma non vengono mai chiamate. Entrambe dovrebbero essere rimosse, ma richiedono strategie di rilevamento diverse. Il rilevamento del codice inutilizzato richiede un'analisi dell'intero programma, mentre quello del codice irraggiungibile avviene a livello di funzione.

Metti in sicurezza ora

Metti in sicurezza il tuo codice, il cloud e il runtime in un unico sistema centralizzato.
Trova e risolvi le vulnerabilità rapidamente e automaticamente.

Nessuna carta di credito richiesta | Risultati della scansione in 32 secondi.