Esempio n. 1
0
 def compare_details(self, other, source=None):
     content_diff = Difference.from_command(Img2Txt,
                                            self.path,
                                            other.path,
                                            source="Image content")
     if (content_diff is not None and Config().compute_visual_diffs
             and same_size(self, other)):
         try:
             logger.debug(
                 "Generating visual difference for %s and %s",
                 self.path,
                 other.path,
             )
             content_diff.add_visuals([
                 pixel_difference(self.path, other.path),
                 flicker_difference(self.path, other.path),
             ])
         except subprocess.CalledProcessError:  # noqa
             pass
     return [
         content_diff,
         Difference.from_command(Identify,
                                 self.path,
                                 other.path,
                                 source="Image metadata"),
     ]
Esempio n. 2
0
    def compare_details(self, other, source=None):
        differences = []

        for klass in (ISO9660PVD, ISO9660Listing):
            differences.append(
                Difference.from_command(
                    klass,
                    self.path,
                    other.path,
                ))

        for x in ('joliet', 'rockridge'):
            try:
                differences.append(
                    Difference.from_command(
                        ISO9660Listing,
                        self.path,
                        other.path,
                        command_args=(x, ),
                    ))
            except subprocess.CalledProcessError:
                # Probably no joliet or rockridge data
                pass

        return differences
Esempio n. 3
0
    def compare_details(self, other, source=None):
        differences = []

        # img2txt does not support .ico files directly so convert to .PNG.
        try:
            png_a, png_b = [ICOImageFile.convert(x) for x in (self, other)]
        except subprocess.CalledProcessError:  # noqa
            pass
        else:
            content_diff = Difference.from_command(Img2Txt,
                                                   png_a,
                                                   png_b,
                                                   source="Image content")
            if (content_diff is not None and Config().compute_visual_diffs
                    and same_size(self, other)):
                if get_image_size(self.path) == get_image_size(other.path):
                    logger.debug(
                        "Generating visual difference for %s and %s",
                        self.path,
                        other.path,
                    )
                    content_diff.add_visuals([
                        pixel_difference(self.path, other.path),
                        flicker_difference(self.path, other.path),
                    ])
            differences.append(content_diff)

        differences.append(
            Difference.from_command(Identify,
                                    self.path,
                                    other.path,
                                    source="Image metadata"))

        return differences
Esempio n. 4
0
def compare_meta(path1, path2):
    logger.debug('compare_meta(%s, %s)', path1, path2)
    differences = []
    try:
        differences.append(Difference.from_command(Stat, path1, path2))
    except RequiredToolNotFound:
        logger.warn("'stat' not found! Is PATH wrong?")
    if os.path.islink(path1) or os.path.islink(path2):
        return [d for d in differences if d is not None]
    try:
        lsattr1 = lsattr(path1)
        lsattr2 = lsattr(path2)
        differences.append(
            Difference.from_text(lsattr1,
                                 lsattr2,
                                 path1,
                                 path2,
                                 source="lattr"))
    except RequiredToolNotFound:
        logger.info("Unable to find 'lsattr'.")
    try:
        differences.append(Difference.from_command(Getfacl, path1, path2))
    except RequiredToolNotFound:
        logger.info("Unable to find 'getfacl'.")
    return [d for d in differences if d is not None]
Esempio n. 5
0
 def compare_details(self, other, source=None):
     differences = []
     differences.append(Difference.from_command(SquashfsSuperblock, self.path, other.path))
     differences.append(Difference.from_command(SquashfsListing, self.path, other.path))
     with SquashfsContainer(self).open() as my_container, \
          SquashfsContainer(other).open() as other_container:
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 6
0
    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)
        other_archs = MachoFile.get_arch_from_macho(other.path)

        differences.append(
            Difference.from_text(
                '\n'.join(my_archs),
                '\n'.join(other_archs),
                self.name,
                other.name,
                source='architectures',
            ))

        # Compare common architectures for differences
        for common_arch in set(my_archs) & set(other_archs):
            differences.append(
                Difference.from_command(
                    OtoolHeaders,
                    self.path,
                    other.path,
                    command_args=[common_arch],
                    comment="Mach-O headers for architecture %s" % common_arch,
                ))
            differences.append(
                Difference.from_command(
                    OtoolLibraries,
                    self.path,
                    other.path,
                    command_args=[common_arch],
                    comment="Mach-O load commands for architecture %s" %
                    common_arch,
                ))

            x = Difference.from_command(
                OtoolDisassemble,
                self.path,
                other.path,
                command_args=[common_arch],
                comment="Code for architecture %s" % common_arch,
            )
            differences.append(x)

            # If the LLVM disassembler does not work, try the internal one.
            if x is None:
                differences.append(
                    Difference.from_command(
                        OtoolDisassembleInternal,
                        self.path,
                        other.path,
                        command_args=[common_arch],
                        comment=
                        "Code for architecture %s (internal disassembler)" %
                        common_arch,
                    ))

        return differences
Esempio n. 7
0
 def compare_details(self, other, source=None):
     differences = []
     # look up differences in metadata
     zipinfo_difference = Difference.from_command(Zipinfo, self.path, other.path) or \
                          Difference.from_command(ZipinfoVerbose, self.path, other.path)
     differences.append(zipinfo_difference)
     with ZipContainer(self).open() as my_container, \
          ZipContainer(other).open() as other_container:
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 8
0
 def compare_details(self, other, source=None):
     differences = []
     differences.append(Difference.from_command(ISO9660PVD, self.path, other.path))
     differences.append(Difference.from_command(ISO9660Listing, self.path, other.path))
     for extension in ('joliet', 'rockridge'):
         try:
             differences.append(Difference.from_command(ISO9660Listing, self.path, other.path, command_args=(extension,)))
         except subprocess.CalledProcessError:
             pass # probably no joliet or rockridge data
     return differences
Esempio n. 9
0
 def compare_details(self, other, source=None):
     if Config().exclude_directory_metadata == 'recursive':
         return []
     zipinfo_difference = (
         Difference.from_command(MozillaZipinfo, self.path, other.path)
         or Difference.from_command(
             MozillaZipinfoVerbose, self.path, other.path
         )
         or Difference.from_command(BsdtarVerbose, self.path, other.path)
     )
     return [zipinfo_difference]
Esempio n. 10
0
 def compare_details(self, other, source=None):
     differences = []
     differences.append(Difference.from_command(ISO9660PVD, self.path, other.path))
     differences.append(Difference.from_command(ISO9660Listing, self.path, other.path))
     for extension in ('joliet', 'rockridge'):
         try:
             differences.append(Difference.from_command(ISO9660Listing, self.path, other.path, command_args=(extension,)))
         except subprocess.CalledProcessError:
             pass # probably no joliet or rockridge data
     with LibarchiveContainer(self).open() as my_container, \
          LibarchiveContainer(other).open() as other_container:
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 11
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(DbDump,
                                 self.path,
                                 other.path,
                                 source="Berkeley DB file")
     ]
Esempio n. 12
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(Dumpxsb,
                                 self.path,
                                 other.path,
                                 source='dumpxsb')
     ]
Esempio n. 13
0
 def compare(self, other, source=None):
     differences = []
     try:
         find_diff = Difference.from_command(FindAll, self.path, other.path)
         if find_diff:
             differences.append(find_diff)
     except RequiredToolNotFound:
         logger.info("Unable to find 'getfacl'.")
     differences.extend(compare_meta(self.name, other.name))
     with DirectoryContainer(self).open() as my_container, \
          DirectoryContainer(other).open() as other_container:
         my_names = my_container.get_member_names()
         other_names = other_container.get_member_names()
         for name in sorted(set(my_names).intersection(other_names)):
             my_file = my_container.get_member(name)
             other_file = other_container.get_member(name)
             with my_file.get_content(), other_file.get_content():
                 inner_difference = diffoscope.comparators.compare_files(
                                        my_file, other_file, source=name)
                 meta_differences = compare_meta(my_file.name, other_file.name)
                 if meta_differences and not inner_difference:
                     inner_difference = Difference(None, my_file.path, other_file.path)
                 if inner_difference:
                     inner_difference.add_details(meta_differences)
                     differences.append(inner_difference)
     if not differences:
         return None
     difference = Difference(None, self.path, other.path, source)
     difference.add_details(differences)
     return difference
Esempio n. 14
0
    def compare_details(self, other, source=None):
        gifbuild_diff = Difference.from_command(
            Gifbuild,
            self.path,
            other.path,
            source="gifbuild",
        )

        differences = [gifbuild_diff]

        if gifbuild_diff is not None and Config().compute_visual_diffs and \
                can_compose_gif_images(self, other):
            try:
                logger.debug(
                    "Generating visual difference for %s and %s",
                    self.path,
                    other.path,
                )
                content_diff = Difference(
                    None,
                    self.path,
                    other.path,
                    source="Image content",
                )
                content_diff.add_visuals([
                    pixel_difference(self.path, other.path),
                    flicker_difference(self.path, other.path),
                ])
                differences.append(content_diff)
            except subprocess.CalledProcessError:  # noqa
                pass

        return differences
Esempio n. 15
0
 def compare_details(self, other, source=None):
     differences = []
     with TarContainer(self).open() as my_container, \
          TarContainer(other).open() as other_container:
         differences.append(Difference.from_command(TarListing, self.path, other.path))
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 16
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(OggDump,
                                 self.path,
                                 other.path,
                                 source='oggDump')
     ]
Esempio n. 17
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(Kbxutil,
                                 self.path,
                                 other.path,
                                 source='kbxutil')
     ]
Esempio n. 18
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(
         Docx2txt,
         self.path,
         other.path,
         source='docx2txt',
     )]
Esempio n. 19
0
 def compare(self, other, source=None):
     return Difference.from_command(
         ObjdumpDisassembleSection,
         self.path,
         other.path,
         command_args=[self._name],
     )
Esempio n. 20
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(Ffprobe,
                                 self.path,
                                 other.path,
                                 source='ffprobe')
     ]
Esempio n. 21
0
    def compare_details(self, other, source=None):
        sng_diff = Difference.from_command(
            Sng, self.path, other.path, source='sng'
        )
        differences = [sng_diff]

        if (
            sng_diff is not None
            and Config().compute_visual_diffs
            and same_size(self, other)
        ):
            try:
                logger.debug(
                    "Generating visual difference for %s and %s",
                    self.path,
                    other.path,
                )
                content_diff = Difference(
                    None, self.path, other.path, source="Image content"
                )
                content_diff.add_visuals(
                    [
                        pixel_difference(self.path, other.path),
                        flicker_difference(self.path, other.path),
                    ]
                )
                differences.append(content_diff)
            except subprocess.CalledProcessError:  # noqa
                pass

        return differences
Esempio n. 22
0
 def compare(self, other, source=None):
     return Difference.from_command(
         ReadelfStringSection,
         self.path,
         other.path,
         command_args=[self._name],
     )
Esempio n. 23
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(
         Pgpdump,
         self.path,
         other.path,
         source='pgpdump',
    )]
Esempio n. 24
0
 def compare_details(self, other, source=None):
     differences = []
     ignore_files = self.container.source.container.source.files_with_same_content_in_data
     with DebTarContainer(self, ignore_files).open() as my_container, \
          DebTarContainer(other, ignore_files).open() as other_container:
         differences.append(Difference.from_command(TarListing, self.path, other.path))
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 25
0
 def compare_details(self, other, source=None):
     differences = []
     differences.append(Difference.from_command(
         CpioContent, self.path, other.path, source="file list"))
     with LibarchiveContainer(self).open() as my_container, \
          LibarchiveContainer(other).open() as other_container:
         differences.extend(my_container.compare(other_container))
     return differences
Esempio n. 26
0
def compare_binary_files(file1, file2, source=None):
    import diffoscope.comparators.utils
    try:
        return Difference.from_command(diffoscope.comparators.utils.Xxd, file1.path, file2.path, source=[file1.name, file2.name])
    except RequiredToolNotFound:
        hexdump1 = hexdump_fallback(file1.path)
        hexdump2 = hexdump_fallback(file2.path)
        comment = 'xxd not available in path. Falling back to Python hexlify.\n'
        return Difference.from_text(hexdump1, hexdump2, file1.name, file2.name, source, comment)
Esempio n. 27
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(ArSymbolTableDumper, self.path,
                                 other.path),
         Difference.from_text_readers(list_libarchive(self.path),
                                      list_libarchive(other.path),
                                      self.path,
                                      other.path,
                                      source="file list")
     ]
Esempio n. 28
0
def test_trim_stderr_in_command():
    class FillStderr(Command):
        def cmdline(self):
            return ['tee', '/dev/stderr']

        def feed_stdin(self, stdin):
            for dummy in range(0, Command.MAX_STDERR_LINES + 1):
                stdin.write('error {}\n'.format(self.path).encode('utf-8'))
    difference = Difference.from_command(FillStderr, 'dummy1', 'dummy2')
    assert '[ 1 lines ignored ]' in difference.comment
Esempio n. 29
0
def compare_meta(path1, path2):
    logger.debug('compare_meta(%s, %s)', path1, path2)
    differences = []
    try:
        differences.append(Difference.from_command(Stat, path1, path2))
    except RequiredToolNotFound:
        logger.warn("'stat' not found! Is PATH wrong?")
    try:
        lsattr1 = lsattr(path1)
        lsattr2 = lsattr(path2)
        differences.append(Difference.from_text(
                               lsattr1, lsattr2, path1, path2, source="lattr"))
    except RequiredToolNotFound:
        logger.info("Unable to find 'lsattr'.")
    try:
        differences.append(Difference.from_command(Getfacl, path1, path2))
    except RequiredToolNotFound:
        logger.info("Unable to find 'getfacl'.")
    return [d for d in differences if d is not None]
Esempio n. 30
0
 def compare_details(self, other, source=None):
     differences = []
     zipinfo_difference = None
     if Config().exclude_directory_metadata != 'recursive':
         zipinfo_difference = (
             Difference.from_command(Zipinfo, self.path, other.path)
             or Difference.from_command(
                 ZipinfoVerbose, self.path, other.path
             )
             or Difference.from_command(
                 BsdtarVerbose, self.path, other.path
             )
         )
     zipnote_difference = Difference.from_command(
         Zipnote, self.path, other.path
     )
     for x in (zipinfo_difference, zipnote_difference):
         if x is not None:
             differences.append(x)
     return differences
Esempio n. 31
0
    def compare(self, other, source=None):
        differences = super().compare(other, source)
        details = None
        try:
            details = Difference.from_command(Pstotext, self.path, other.path)
        except RequiredToolNotFound:
            logger.debug('ps2ascii not found')

        if details:
            differences.add_details([details])
        return differences
Esempio n. 32
0
    def compare(self, other, source=None):
        differences = super().compare(other, source)
        details = None
        try:
            details = Difference.from_command(Pstotext, self.path, other.path)
        except RequiredToolNotFound:  # noqa
            logger.debug('ps2ascii not found')

        if details:
            differences.add_details([details])
        return differences
Esempio n. 33
0
    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)
        other_archs = MachoFile.get_arch_from_macho(other.path)

        differences.append(Difference.from_text('\n'.join(my_archs),
                                                '\n'.join(other_archs),
                                                self.name, other.name, source='architectures'))

        # Compare common architectures for differences
        for common_arch in set(my_archs) & set(other_archs):
            differences.append(Difference.from_command(OtoolHeaders, self.path, other.path, command_args=[common_arch],
                                                       comment="Mach-O headers for architecture %s" % common_arch))
            differences.append(Difference.from_command(OtoolLibraries, self.path, other.path, command_args=[common_arch],
                                                       comment="Mach-O load commands for architecture %s" % common_arch))
            differences.append(Difference.from_command(OtoolDisassemble, self.path, other.path, command_args=[common_arch],
                                                       comment="Code for architecture %s" % common_arch))

        return differences
Esempio n. 34
0
def test_trim_stderr_in_command():
    class FillStderr(Command):
        def cmdline(self):
            return ['tee', '/dev/stderr']

        def feed_stdin(self, stdin):
            for dummy in range(0, Command.MAX_STDERR_LINES + 1):
                stdin.write('error {}\n'.format(self.path).encode('utf-8'))

    difference = Difference.from_command(FillStderr, 'dummy1', 'dummy2')
    assert '[ 1 lines ignored ]' in difference.comment
Esempio n. 35
0
def compare_meta(path1, path2):
    if Config().exclude_directory_metadata in ('yes', 'recursive'):
        logger.debug(
            "Excluding directory metadata for paths (%s, %s)", path1, path2
        )
        return []

    logger.debug('compare_meta(%s, %s)', path1, path2)
    differences = []

    # Don't run any commands if any of the paths do not exist
    if not os.path.exists(path1) or not os.path.exists(path2):
        return differences

    try:
        differences.append(Difference.from_command(Stat, path1, path2))
    except RequiredToolNotFound:
        logger.error("Unable to find 'stat'! Is PATH wrong?")
    if os.path.islink(path1) or os.path.islink(path2):
        return [d for d in differences if d is not None]
    try:
        differences.append(Difference.from_command(Getfacl, path1, path2))
    except RequiredToolNotFound:
        logger.info(
            "Unable to find 'getfacl', some directory metadata differences might not be noticed."
        )
    try:
        lsattr1 = lsattr(path1)
        lsattr2 = lsattr(path2)
        differences.append(
            Difference.from_text(
                lsattr1, lsattr2, path1, path2, source='lsattr'
            )
        )
    except RequiredToolNotFound:
        logger.info(
            "Unable to find 'lsattr', some directory metadata differences might not be noticed."
        )
    differences.append(xattr(path1, path2))
    return [d for d in differences if d is not None]
Esempio n. 36
0
def compare_binary_files(file1, file2, source=None):
    try:
        return Difference.from_command(Xxd,
                                       file1.path,
                                       file2.path,
                                       source=[file1.name, file2.name],
                                       has_internal_linenos=True)
    except RequiredToolNotFound:
        hexdump1 = hexdump_fallback(file1.path)
        hexdump2 = hexdump_fallback(file2.path)
        comment = 'xxd not available in path. Falling back to Python hexlify.\n'
        return Difference.from_text(hexdump1, hexdump2, file1.name, file2.name,
                                    source, comment)
Esempio n. 37
0
def compare_binary_files(file1, file2, source=None):
    import diffoscope.comparators.utils
    try:
        return Difference.from_command(diffoscope.comparators.utils.Xxd,
                                       file1.path,
                                       file2.path,
                                       source=[file1.name, file2.name])
    except RequiredToolNotFound:
        hexdump1 = hexdump_fallback(file1.path)
        hexdump2 = hexdump_fallback(file2.path)
        comment = 'xxd not available in path. Falling back to Python hexlify.\n'
        return Difference.from_text(hexdump1, hexdump2, file1.name, file2.name,
                                    source, comment)
Esempio n. 38
0
    def compare(self, other, source=None):
        # Don't display signatures as hexdumps; use TextFile's comparisons...
        difference = super().compare(other, source)

        # ... but attach pgpdump of outout
        difference.add_details(
            [
                Difference.from_command(
                    Pgpdump, self.path, other.path, source='pgpdump'
                )
            ]
        )

        return difference
Esempio n. 39
0
    def compare_details(self, other, source=None):
        xs = []

        if PyPDF2 is not None:
            difference = Difference.from_text(
                self.dump_pypdf2_metadata(self),
                self.dump_pypdf2_metadata(other),
                self.path,
                other.path,
            )
            if difference:
                difference.add_comment("Document info")
            xs.append(difference)

        xs.append(Difference.from_command(Pdftotext, self.path, other.path))

        return xs
Esempio n. 40
0
def test_trim_stderr_in_command():
    class FillStderr(Command):
        def cmdline(self):
            return ['tee', '/dev/stderr']

        def stdin(self):
            r, w = os.pipe()
            r, w = os.fdopen(r), os.fdopen(w, "w")

            def write():
                for dummy in range(0, Command.MAX_STDERR_LINES + 1):
                    w.write('error {}\n'.format(self.path))

            threading.Thread(target=write).start()
            return r

    difference = Difference.from_command(FillStderr, 'dummy1', 'dummy2')
    assert '[ 1 lines ignored ]' in difference.comment
Esempio n. 41
0
    def compare_details(self, other, source=None):
        diff = []

        for decompiler in self.decompilers:
            try:
                single_diff = Difference.from_command(decompiler, self.path,
                                                      other.path)
                if single_diff:
                    diff.append(single_diff)
                    break
            except RequiredToolNotFound:
                logger.debug("Unable to find %s. Falling back...",
                             decompiler.__name__)

        if not diff:
            raise RequiredToolNotFound(self.decompilers[-1])

        return diff
Esempio n. 42
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(SquashfsSuperblock, self.path, other.path),
             Difference.from_command(SquashfsListing, self.path, other.path)]
Esempio n. 43
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(Img2Txt, self.path, other.path)]
Esempio n. 44
0
def _compare_elf_data(path1, path2):
    differences = []
    differences.append(Difference.from_command(ReadelfAll, path1, path2))
    differences.append(Difference.from_command(ReadelfDebugDump, path1, path2))
    differences.append(Difference.from_command(ObjdumpDisassemble, path1, path2))
    return differences
Esempio n. 45
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(CbfsListing, self.path, other.path)]
Esempio n. 46
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(Sqlite3Dump, self.path, other.path)]
Esempio n. 47
0
 def compare_details(self, other, source=None):
     zipinfo_difference = Difference.from_command(MozillaZipinfo, self.path, other.path) or \
                          Difference.from_command(MozillaZipinfoVerbose, self.path, other.path)
     return [zipinfo_difference]
Esempio n. 48
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(Msgunfmt, self.path, other.path)]
Esempio n. 49
0
 def compare_details(self, other, source=None):
     return [
         Difference.from_command(Pdftotext, self.path, other.path),
         Difference.from_command(Pdftk, self.path, other.path),
     ]
Esempio n. 50
0
 def compare(self, other, source=None):
     return Difference.from_command(ReadelfStringSection,
             self.path, other.path,
             command_args=[self._name])
Esempio n. 51
0
 def compare(self, other, source=None):
     return Difference.from_command(ObjdumpDisassembleSection,
             self.path, other.path,
             command_args=[self._name])
Esempio n. 52
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(Sng, self.path, other.path, source='sng')]
Esempio n. 53
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(LlvmBcAnalyzer,   self.path, other.path),
             Difference.from_command(LlvmBcDisassembler, self.path, other.path)]
Esempio n. 54
0
 def compare_details(self, other, source=None):
     return [Difference.from_command(ShowIface, self.path, other.path)]
Esempio n. 55
0
def _compare_elf_data(path1, path2):
    return [Difference.from_command(cmd, path1, path2) for cmd in READELF_COMMANDS + READELF_DEBUG_DUMP_COMMANDS]