Come annullare la sicurezza, senza inquinare la directory corrente in caso di tarbomb?


33

Progetti rispettabili rilasciano archivi tar che contengono una singola directory, per esempio, zyrgus-3.18.tar.gzcontiene una zyrgus-3.18cartella che a sua volta contiene src, build, dist, etc.

Ma alcuni progetti punk mettono tutto alla radice: '- (Questo si traduce in un disastro totale durante l'archiviazione. La creazione manuale di una cartella ogni volta è una seccatura e non è necessaria la maggior parte delle volte.

  • Esiste un modo super veloce per dire se un file .tar o .tar.gz contiene più di una singola directory alla radice? Anche per un grande archivio.
  • O ancora meglio, esiste uno strumento che in questi casi creerebbe una directory (nome dell'archivio senza estensione) e inserirà tutto?


2
Penso che l'imballaggio rotto meriti una segnalazione di bug all'autore del pacchetto.

14
Storicamente (dalla metà degli anni '90) non sono mai entrato in una sottodirectory. Se è tutto inserito in una singola directory (come dovrebbe essere), i suoi contenuti possono essere spostati nel posto giusto con mv, quindi è possibile eliminare la directory extra superflua. Due passaggi aggiuntivi sì, ma batte la pulizia del pasticcio da un file tar errato.
TED

6
But some punk projects put everything at the root :'-(E alcuni progetti punk mettono tutto inutilmente in una cartella, considerando che stanno già inserendo tutto in un archivio allegato, in modo che quando scarichi e decomprimilo nella sua cartella come farebbe qualsiasi utente intelligente, finisci con tutto il il contenuto ha seppellito un altro livello. ;-)
Mason Wheeler,

2
@MasonWheeler Esiste una sorta di "standard di fatto" per gli archivi tar che contengono tutto in una cartella.
glglgl,

Risposte:


30

patool gestisce diversi tipi di archivi e crea una sottodirectory nel caso in cui l'archivio contenga più file per evitare di ingombrare la directory di lavoro con i file estratti.

Estrai archivio

patool extract archive.tar

Per ottenere un elenco dei formati supportati, utilizzare patool formats.


Cordiali saluti: L'ho trovato su sourceforge.net/projects/patool . È un rpm e lo alienconvertivo in deb per Ubuntu.
Joe,

patooldovrebbe essere nei repository per Debian e Ubuntu se si esegue una versione corrente.
Marco,

12

Potresti fare qualcosa del genere

tar tf thefile.tar | cut -d/ -f1 | sort -u

per vedere quali voci di livello superiore ha un tar; pipe per wc -lverificare se ce n'è più di uno. Si noti che ci sono alcuni casi in cui ciò fallirebbe, ad esempio se tar contiene percorsi di file del modulo somedir/whatevere anche ./somedir/whatever(o qualcosa di più folle); questo dovrebbe essere raro, però.

Questo leggerà l'intero file tar prima di emettere qualcosa, a causa del sort, anche se dovrebbe essere più veloce dell'effettiva estrazione perché è solo una lettura sequenziale e può saltare file di grandi dimensioni.

Se lo stai facendo in modo interattivo e il file potrebbe essere di grandi dimensioni, puoi cambiare sort -uin + uniqe se stampa più di una cosa.ControlC


2
sort | uniqpuò essere abbreviato in sort -u.
Marco,

4
a meno che tu non voglia fareuniq -c
cas l'

7

tu puoi fare:

pax <some.tar

... per elencare il contenuto di un tarfile.

se vuoi sapere quanti livelli ci sono, puoi fare:

pax <some.tar | tr -dc /\\n | sort -r | head -n1

puoi proibire esplicitamente un'esplosione durante l'estrazione con:

mkdir some.tar
pax -'rs|^|some.tar/|' <some.tar

2

Questo dovrebbe fare quello che vuoi. Sono sicuro che qualcuno può migliorarlo. In questi esempi presumo un archivio tar compresso con gzip poiché questo è il più comune.

Si desidera un archivio in cui non sono presenti nodi di pari livello nella struttura di directory a livello di radice.

Ogni voce nell'elenco dei contenuti tar deve iniziare con lo stesso modello. Questo modello è il percorso della directory di base che devono condividere tutte le voci nell'archivio. Se due voci non iniziano con lo stesso modello, sono fratelli.

La prima riga nell'elenco dei contenuti tar ti fornirà il modello minimo che devi controllare. Questo è il BASEPATH.

BASEPATH=$(tar ztf example.tar.gz | (read line; echo $line))

Quindi, per verificare la presenza di tarball esplosivi, è necessario verificare se una riga dell'elenco dei contenuti di tar non inizia con BASEPATH.

tar ztf example.tar.gz | grep -qv "^${BASEPATH}"

Trasformalo in una funzione shell:

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

Da qui è possibile scrivere una funzione di estrazione sicura dell'archivio tar.

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

safe_tar_x() {
    TARBALL_NAME=$1
    if is_explosive ${TARBALL_NAME}; then
        SUBDIR=${TARBALL_NAME%.tar.gz}
        SUBDIR=${SUBDIR##*/}
        mkdir "${SUBDIR}"
        echo "WARNING: This tarball is explosive. Opening in subdirectory, ${SUBDIR}, for safety." >&2
    else
        SUBDIR="."
    fi
    # Tar quirks: "--directory" must be last, and using more than
    #     one option group requires that all groups start with a dash.
    tar -zxf "${TARBALL_NAME}" --directory "${SUBDIR}"
    return $?
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.