This should do what you want. I'm sure someone can improve it. In these examples I assume a gzip compressed tar archive since this is the most common.
You want an archive where there are no sibling nodes in the root level directory tree.
Every entry in the tar content list must begin with the same pattern.
This pattern is the base directory path that all entries in the archive must share. If any two entries do not begin with the same pattern then they are siblings.
The first line in the tar content list will give you the minimal pattern you need to check for. This is the BASEPATH.
BASEPATH=$(tar ztf example.tar.gz | (read line; echo $line))
Then to test for explosive tarballs you need to check if any line of the tar content list does not begin with the BASEPATH.
tar ztf example.tar.gz | grep -qv "^${BASEPATH}"
Turn this into a shell function:
is_explosive() {
TARBALL_NAME=$1
tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
return $?
}
From here you can write a safe tar archive extraction function.
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 $?
}
But some punk projects put everything at the root :'-(
And some punk projects put everything inside a folder completely unnecessarily, considering that they're already putting everything inside an enclosing archive, so that when you download and unzip it into its own folder like any smart user would do, you end up with all the content buried another layer down. ;-) – Mason Wheeler Nov 11 '15 at 18:31--nobomb
switch that creates a directory if more than one dir or file would be created in root. Who's up for writing a patch? – Roger Dahl Nov 11 '15 at 19:37