Commit e0563c81 authored by Ximin Luo's avatar Ximin Luo
Browse files

Better way of performing the entry name sanitisation

parent 7195a5cc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
diffoscope (76) UNRELEASED; urgency=medium

  * Don't write to arbitrary locations when extracting archive members.
    (Closes: #XXXXXX)
    (Closes: #854723)

 -- Ximin Luo <infinity0@debian.org>  Thu, 09 Feb 2017 22:14:46 +0100

+11 −3
Original line number Diff line number Diff line
@@ -212,15 +212,23 @@ class LibarchiveContainer(Archive):
                if entry.isdir:
                    continue

                clean_name = os.path.basename(entry.pathname.rstrip('/' + os.sep))
                if not clean_name:
                # All extracted locations must be underneath self._unpacked
                force_prefix = os.path.join(self._unpacked, "")

                # Try to pick a safe and reasonable candidate name
                candidate_name = os.path.normpath(entry.pathname.rstrip('/' + os.sep))
                if os.path.isabs(candidate_name):
                    candidate_name = os.path.relpath(candidate_name, os.path.join(os.path.sep))

                dst = os.path.normpath(os.path.join(self._unpacked, candidate_name))
                if not dst.startswith(force_prefix):
                    logger.warn("Skipping member because we could not make a safe name to extract it to: '%s'",
                                entry.pathname)
                    continue

                # TODO: need to fix reading these cleaned members. currently
                # reading will still try to use the uncleaned name.
                dst = os.path.join(self._unpacked, clean_name)
                #logging.debug("Extracting %s to %s", entry.pathname, dst)
                os.makedirs(os.path.dirname(dst), exist_ok=True)

                with open(dst, 'wb') as f: