Isso deve fazer o que você quiser. Tenho certeza que alguém pode melhorar isso. Nestes exemplos, eu assumo um arquivo compactado gzip comprimido, já que este é o mais comum.
Você deseja um arquivo no qual não haja nós irmãos na árvore de diretórios do nível raiz.
Cada entrada na lista de conteúdo tar deve começar com o mesmo padrão.
Esse padrão é o caminho do diretório base que todas as entradas no archive devem compartilhar. Se quaisquer duas entradas não começarem com o mesmo padrão, elas são irmãos.
A primeira linha na lista de conteúdo tar lhe dará o padrão mínimo que você precisa verificar. Este é o BASEPATH.
BASEPATH=$(tar ztf example.tar.gz | (read line; echo $line))
Em seguida, para testar para tarballs explosivos, você precisa verificar se qualquer linha da lista de conteúdo tar não começa com o BASEPATH
tar ztf example.tar.gz | grep -qv "^${BASEPATH}"
Transforme isso em uma função de shell:
is_explosive() {
TARBALL_NAME=$1
tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
return $?
}
A partir daqui você pode escrever uma função segura de extração de arquivos 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 $?
}