How to use the diffoscope.comparators.utils.file.File function in diffoscope

To help you get started, we’ve selected a few diffoscope examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github anthraxx / diffoscope / tests / comparators / test_binary.py View on Github external
def test_guess_encoding_binary():
    assert File.guess_encoding(TEST_FILE1_PATH) == 'binary'
github anthraxx / diffoscope / diffoscope / comparators / macho.py View on Github external
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)
github anthraxx / diffoscope / diffoscope / comparators / device.py View on Github external
# 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)
github anthraxx / diffoscope / diffoscope / comparators / utils / archive.py View on Github external
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
github anthraxx / diffoscope / diffoscope / comparators / cpio.py View on Github external
# 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",
        )]
github anthraxx / diffoscope / diffoscope / comparators / elf.py View on Github external
]


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
github anthraxx / diffoscope / diffoscope / comparators / deb.py View on Github external
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):
github anthraxx / diffoscope / diffoscope / comparators / debian.py View on Github external
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(
github anthraxx / diffoscope / diffoscope / comparators / apk.py View on Github external
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(
github anthraxx / diffoscope / diffoscope / comparators / elf.py View on Github external
# 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)