the zipfile module does not restore file permissions
        so we'll do it manually

def _extract_file(self, zf, info, extract_dir):
        """
        the zipfile module does not restore file permissions
        so we'll do it manually
        """
        out_path = os.path.join(extract_dir, info.filename)
        out_path = os.path.abspath(out_path)
        if not out_path.startswith(extract_dir):
            raise ValueError(
                "malicious zipfile, %s outside of extract_dir %s" %
                (info.filename, extract_dir))

        zf.extract(info.filename, path=extract_dir)

        # not sure why zipfiles store the perms 16 bits away but they do
        perm = info.external_attr >> 16
        os.chmod(out_path, perm)