Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_guess_encoding_binary():
assert File.guess_encoding(TEST_FILE1_PATH) == 'binary'
class OtoolHeaders(Otool):
def otool_options(self):
return super().otool_options() + ['-h']
class OtoolLibraries(Otool):
def otool_options(self):
return super().otool_options() + ['-L']
class OtoolDisassemble(Otool):
def otool_options(self):
return super().otool_options() + ['-tdvV']
class MachoFile(File):
RE_FILE_TYPE = re.compile(r'^Mach-O ')
RE_EXTRACT_ARCHS = re.compile(r'^(?:Architectures in the fat file: .* are|Non-fat file: .* is architecture): (.*)$')
@staticmethod
@tool_required('lipo')
def get_arch_from_macho(path):
lipo_output = subprocess.check_output(['lipo', '-info', path]).decode('utf-8')
lipo_match = MachoFile.RE_EXTRACT_ARCHS.match(lipo_output)
if lipo_match is None:
raise ValueError('lipo -info on Mach-O file %s did not produce expected output. Output was: %s' % path, lipo_output)
return lipo_match.group(1).split()
def compare_details(self, other, source=None):
differences = []
# Check for fat binaries, trigger a difference if the architectures differ
my_archs = MachoFile.get_arch_from_macho(self.path)
# along with diffoscope. If not, see .
import os
import stat
import logging
from diffoscope.tempfiles import get_named_temporary_file
from diffoscope.difference import Difference
from .binary import FilesystemFile
from .utils.file import File
logger = logging.getLogger(__name__)
class Device(File):
@staticmethod
def recognizes(file):
return file.is_device()
def get_device(self):
assert isinstance(self, FilesystemFile)
st = os.lstat(self.name)
return st.st_mode, os.major(st.st_rdev), os.minor(st.st_rdev)
def has_same_content_as(self, other):
logger.debug("has_same_content: %s %s", self, other)
try:
return self.get_device() == other.get_device()
except (AttributeError, OSError):
# 'other' is not a device, or something.
logger.debug("has_same_content: Not a device: %s", other)
def close_archive(self):
raise NotImplementedError()
@abc.abstractmethod
def get_member_names(self):
raise NotImplementedError()
@abc.abstractmethod
def extract(self, member_name, dest_dir):
raise NotImplementedError()
def get_member(self, member_name):
return ArchiveMember(self, member_name)
class ArchiveMember(File):
def __init__(self, container, member_name):
super().__init__(container=container)
self._name = member_name
self._temp_dir = None
self._path = None
@property
def path(self):
if self._path is None:
logger.debug("Unpacking %s from %s", self._name, self.container.source.name)
assert self._temp_dir is None
self._temp_dir = get_temporary_directory()
with profile('container_extract', self.container):
self._path = self.container.extract(self._name, self._temp_dir.name)
return self._path
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see .
import re
from diffoscope.difference import Difference
from .utils.file import File
from .utils.libarchive import LibarchiveContainer, list_libarchive
class CpioFile(File):
CONTAINER_CLASS = LibarchiveContainer
RE_FILE_TYPE = re.compile(r'\bcpio archive\b')
def compare_details(self, other, source=None):
return [Difference.from_text_readers(
list_libarchive(self.path),
list_libarchive(other.path),
self.path,
other.path,
source="file list",
)]
]
def _should_skip_section(name, type):
for x in READELF_COMMANDS:
if x.should_skip_section(name, type):
logger.debug("Skipping section %s, covered by %s", name, x)
return True
if name.startswith('.debug') or name.startswith('.zdebug'):
# section .debug_str looks much nicer with `readelf --string-dump`
# the rest is handled by READELF_DEBUG_DUMP_COMMANDS
return not name.endswith('_str')
return False
class ElfSection(File):
def __init__(self, elf_container, member_name):
super().__init__(container=elf_container)
self._name = member_name
@property
def name(self):
return self._name
@property
def progress_name(self):
return "{} [{}]".format(
self.container.source.progress_name,
super().progress_name,
)
@property
return member
else:
return specialize(member.as_container.get_member('content'))
@property
def control_tar(self):
for name, member in self.get_members().items():
if DebContainer.RE_CONTROL_TAR.match(name):
specialize(member)
if name.endswith('.tar'):
return member
else:
return specialize(member.as_container.get_member('content'))
class DebFile(File):
CONTAINER_CLASS = DebContainer
RE_FILE_TYPE = re.compile(r'^Debian binary package')
@property
def md5sums(self):
if not hasattr(self, '_md5sums'):
md5sums_file = self.as_container.control_tar.as_container.lookup_file('./md5sums')
if md5sums_file:
self._md5sums = md5sums_file.parse()
else:
logger.debug('Unable to find a md5sums file')
self._md5sums = {}
return self._md5sums
@property
def control(self):
import logging
import functools
import collections
from debian.deb822 import Dsc
from diffoscope.changes import Changes
from diffoscope.difference import Difference
from .utils.file import File
from .utils.container import Container
logger = logging.getLogger(__name__)
class DebControlMember(File):
def __init__(self, container, member_name):
self._container = container
self._name = member_name
self._path = None
@property
def container(self):
return self._container
@property
def name(self):
return self._name
@property
def path(self):
return os.path.join(
self._members.extend(current_dir)
return self
def close_archive(self):
pass
def get_member_names(self):
return self._members
def extract(self, member_name, dest_dir):
src_path = os.path.join(self._unpacked, member_name)
return src_path
class ApkFile(File):
RE_FILE_TYPE = re.compile(r'^(Java|Zip) archive data.*\b')
RE_FILE_EXTENSION = re.compile(r'\.apk$')
CONTAINER_CLASS = ApkContainer
def compare_details(self, other, source=None):
zipinfo_difference = Difference.from_command(Zipinfo, self.path, other.path) or \
Difference.from_command(ZipinfoVerbose, self.path, other.path)
return [zipinfo_difference]
def filter_apk_metadata(filepath, archive_name):
new_filename = os.path.join(os.path.dirname(filepath), 'APK metadata')
logger.debug("Moving APK metadata from %s to %s", filepath, new_filename)
re_filename = re.compile(
# 3. Create a file with the debug symbols in uncompressed form
objcopy('--decompress-debug-sections', debug_file.path, dest_path)
# 4. Update the .gnu_debuglink to this new file so we get the CRC right
objcopy('--remove-section=.gnu_debuglink', self.source.path)
objcopy('--add-gnu-debuglink={}'.format(dest_path), self.source.path)
logger.debug('Installed debug symbols at %s', dest_path)
def get_member_names(self):
return self._sections.keys()
def get_member(self, member_name):
return self._sections[member_name]
class ElfFile(File):
CONTAINER_CLASS = ElfContainer
RE_FILE_TYPE = re.compile(r'^ELF ')
def compare_details(self, other, source=None):
return _compare_elf_data(self.path, other.path)
class StaticLibFile(File):
CONTAINER_CLASS = ElfContainer
RE_FILE_TYPE = re.compile(r'\bar archive\b')
RE_FILE_EXTENSION = re.compile(r'\.a$')
@staticmethod
def recognizes(file):
return StaticLibFile.RE_FILE_TYPE.search(file.magic_file_type) and \
StaticLibFile.RE_FILE_EXTENSION.search(file.name)