Skip to content
Snippets Groups Projects
Commit 9e29cfae authored by David Douard's avatar David Douard
Browse files

tarball: extract safemembers() from within _uncompress_tar()

No need for it being a dynamically defined function, plus it makes pydocstyle
very unhappy (probably a bug in pydoctyle 4.0.0 but...).

Also rename it as _safemembers() for consistency sake.
parent 31731b3f
No related branches found
No related tags found
1 merge request!69tarball: extract safemembers() from within _uncompress_tar()
......@@ -82,6 +82,40 @@ def _uncompress_zip(tarpath, dirpath):
z.extractall(path=dirpath)
def _safemembers(tarpath, members, basepath):
"""Given a list of archive members, yield the members (directory,
file, hard-link) that stays in bounds with basepath. Note
that symbolic link are authorized to point outside the
basepath though.
Args:
tarpath: Name of the tarball
members: Archive members for such tarball
basepath: the basepath sandbox
Yields:
Safe TarInfo member
Raises:
ValueError when a member would be extracted outside basepath
"""
errormsg = 'Archive {} blocked. Illegal path to %s %s'.format(tarpath)
for finfo in members:
if finfo.isdir() and _badpath(finfo.name, basepath):
raise ValueError(errormsg % ('directory', finfo.name))
elif finfo.isfile() and _badpath(finfo.name, basepath):
raise ValueError(errormsg % ('file', finfo.name))
elif finfo.islnk() and _badlink(finfo, basepath):
raise ValueError(errormsg % ('hard-link', finfo.linkname))
# Authorize symlinks to point outside basepath
# elif finfo.issym() and _badlink(finfo, basepath):
# raise ValueError(errormsg % ('symlink', finfo.linkname))
else:
yield finfo
def _uncompress_tar(tarpath, dirpath):
"""Uncompress tarpath if the tarpath is safe.
Safe means, no file will be uncompressed outside of dirpath.
......@@ -94,43 +128,10 @@ def _uncompress_tar(tarpath, dirpath):
ValueError when a member would be extracted outside dirpath.
"""
def safemembers(tarpath, members, basepath):
"""Given a list of archive members, yield the members (directory,
file, hard-link) that stays in bounds with basepath. Note
that symbolic link are authorized to point outside the
basepath though.
Args:
tarpath: Name of the tarball
members: Archive members for such tarball
basepath: the basepath sandbox
Yields:
Safe TarInfo member
Raises:
ValueError when a member would be extracted outside basepath
"""
errormsg = 'Archive {} blocked. Illegal path to %s %s'.format(tarpath)
for finfo in members:
if finfo.isdir() and _badpath(finfo.name, basepath):
raise ValueError(errormsg % ('directory', finfo.name))
elif finfo.isfile() and _badpath(finfo.name, basepath):
raise ValueError(errormsg % ('file', finfo.name))
elif finfo.islnk() and _badlink(finfo, basepath):
raise ValueError(errormsg % ('hard-link', finfo.linkname))
# Authorize symlinks to point outside basepath
# elif finfo.issym() and _badlink(finfo, basepath):
# raise ValueError(errormsg % ('symlink', finfo.linkname))
else:
yield finfo
with tarfile.open(tarpath) as t:
members = t.getmembers()
t.extractall(path=dirpath,
members=safemembers(tarpath, members, dirpath))
members=_safemembers(tarpath, members, dirpath))
def uncompress(tarpath, dest):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment