def compare_details(self, other, source=None): differences = [] for field in sorted( set(self.deb822.keys()).union(set(other.deb822.keys()))): if field.startswith('Checksums-') or field == 'Files': continue my_value = '' if field in self.deb822: my_value = self.deb822.get_as_string(field).lstrip() other_value = '' if field in other.deb822: other_value = other.deb822.get_as_string(field).lstrip() differences.append( Difference.from_text(my_value, other_value, self.path, other.path, source=field)) # compare Files as string differences.append( Difference.from_text(self.deb822.get_as_string('Files'), other.deb822.get_as_string('Files'), self.path, other.path, source='Files')) return differences
def compare_details(self, other, source=None): differences = [] for field in sorted(set(self.deb822.keys()).union(set(other.deb822.keys()))): if field.startswith('Checksums-') or field == 'Files': continue my_value = '' if field in self.deb822: my_value = self.deb822.get_as_string(field).lstrip() other_value = '' if field in other.deb822: other_value = other.deb822.get_as_string(field).lstrip() differences.append(Difference.from_text( my_value, other_value, self.path, other.path, source=field)) # compare Files as string if self.deb822.get('Files'): differences.append(Difference.from_text(self.deb822.get_as_string('Files'), other.deb822.get_as_string('Files'), self.path, other.path, source='Files')) else: differences.append(Difference.from_text(self.deb822.get_as_string('Checksums-Sha256'), other.deb822.get_as_string('Checksums-Sha256'), self.path, other.path, source='Checksums-Sha256')) return differences
def compare_details(self, other, source=None): difference = Difference.from_text(self.dumps(self), self.dumps(other), self.path, other.path) if difference: return [difference] difference = Difference.from_text(self.dumps(self, sort_keys=False), self.dumps(other, sort_keys=False), self.path, other.path, comment="ordering differences only") return [difference]
def compare(self, other, source=None): differences = [] listing_diff = Difference.from_text( '\n'.join(list_files(self.path)), '\n'.join(list_files(other.path)), self.path, other.path, source='file list', ) if listing_diff: differences.append(listing_diff) differences.extend(compare_meta(self.name, other.name)) my_container = DirectoryContainer(self) other_container = DirectoryContainer(other) differences.extend(my_container.compare(other_container)) if not differences: return None difference = Difference(None, self.path, other.path, source) difference.add_details(differences) return difference
def compare(self, other, source=None): differences = [] try: listing_diff = Difference.from_text( '\n'.join(list_files(self.path)), '\n'.join(list_files(other.path)), self.path, other.path, source='file list') if listing_diff: differences.append(listing_diff) except RequiredToolNotFound: logger.info("Unable to find 'getfacl'.") differences.extend(compare_meta(self.name, other.name)) my_container = DirectoryContainer(self) other_container = DirectoryContainer(other) 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) 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
def compare(self, other, source=None): differences = [] try: listing_diff = Difference.from_text('\n'.join(list_files(self.path)), '\n'.join(list_files(other.path)), self.path, other.path, source='file list') if listing_diff: differences.append(listing_diff) except RequiredToolNotFound: logger.info("Unable to find 'getfacl'.") differences.extend(compare_meta(self.name, other.name)) my_container = DirectoryContainer(self) other_container = DirectoryContainer(other) 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) 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
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]
def compare_details(self, other, source=None): return [Difference.from_text( describe_index(self.path), describe_index(other.path), self.path, other.path, )]
def compare(self, other, source=None): my_encoding = self.encoding or 'utf-8' other_encoding = other.encoding or 'utf-8' try: with codecs.open(self.path, 'r', encoding=my_encoding) as my_content, \ codecs.open(other.path, 'r', encoding=other_encoding) as other_content: difference = Difference.from_text_readers( my_content, other_content, self.name, other.name, source) # Check if difference is only in line order. if difference and order_only_difference( difference.unified_diff): difference.add_comment("ordering differences only") if my_encoding != other_encoding: if difference is None: difference = Difference(None, self.path, other.path, source) difference.add_details([ Difference.from_text(my_encoding, other_encoding, None, None, source='encoding') ]) return difference except (LookupError, UnicodeDecodeError): # unknown or misdetected encoding return self.compare_bytes(other, source)
def compare_details(self, other, source=None): return [Difference.from_text( json.dumps(self.parsed, indent=4, sort_keys=True), json.dumps(other.parsed, indent=4, sort_keys=True), self, other, )]
def compare_details(self, other, source=None): """ Compares self.object with another, returning a Difference object Args: other -- A XMLFile object source Returns: A diffoscope.difference.Difference object """ if isinstance(other, MissingFile): return [ Difference( None, self.name, other.name, comment="Trying to compare two non-existing files.", ) ] return [ Difference.from_text(self.dumps(self), self.dumps(other), self.name, other.name) ]
def xattr(path1, path2): try: import xattr as xattr_ except ImportError: return None # Support the case where the python3-xattr package is installed but # python3-pyxattr is not; python3-xattr has an xattr class that can be used # like a dict. try: get_all = xattr_.get_all except AttributeError: def get_all(x): return xattr_.xattr(x).items() def fn(x): return '\n'.join( '{}: {}'.format( k.decode('utf-8', 'ignore'), v.decode('utf-8', 'ignore') ) for k, v in get_all(x) ) return Difference.from_text( fn(path1), fn(path2), path1, path2, source='extended file attributes' )
def compare_details(self, other, source=None): differences = [] differences.append(Difference.from_text( self.magic_file_type, other.magic_file_type, self, other, source='metadata')) with GzipContainer(self).open() as my_container, \ GzipContainer(other).open() as other_container: differences.extend(my_container.compare(other_container)) return differences
def compare_details(self, other, source=None): return [ Difference.from_text(self.magic_file_type, other.magic_file_type, self, other, source='metadata') ]
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
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)
def compare_binary_files(file1, file2, source=None): try: with xxd(file1.path) as xxd1, xxd(file2.path) as xxd2: return Difference.from_raw_readers(xxd1, xxd2, file1.name, file2.name, source) 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)
def compare_rpm_headers(path1, path2): # compare headers with get_temporary_directory() as rpmdb_dir: rpm.addMacro("_dbpath", rpmdb_dir) ts = rpm.TransactionSet() ts.setVSFlags(-1) header1 = get_rpm_header(path1, ts) header2 = get_rpm_header(path2, ts) return Difference.from_text(header1, header2, path1, path2, source="header")
def compare_details(self, other, source=None): differences = [] # look up differences in metadata content1 = get_ar_content(self.path) content2 = get_ar_content(other.path) differences.append(Difference.from_text( content1, content2, self.path, other.path, source="metadata")) differences.extend(_compare_elf_data(self.path, other.path)) return differences
def compare_details(self, other, source=None): my_content = get_ar_content(self.path) other_content = get_ar_content(other.path) return [ Difference.from_text(my_content, other_content, self.path, other.path, source="metadata") ]
def compare_details(self, other, source=None): differences = [] my_content = get_ar_content(self.path) other_content = get_ar_content(other.path) differences.append(Difference.from_text( my_content, other_content, self.path, other.path, source="metadata")) with DebContainer(self).open() as my_container, \ DebContainer(other).open() as other_container: differences.extend(my_container.compare(other_container)) return differences
def _compare_using_details(self, other, source): details = [] difference = Difference(None, self.name, other.name, source=source) if hasattr(self, 'compare_details'): details.extend(self.compare_details(other, source)) if self.as_container: if self.as_container.auto_diff_metadata: details.extend([ Difference.from_text( self.magic_file_type, other.magic_file_type, self, other, source='filetype from file(1)', ), Difference.from_text( self.__class__.__name__, other.__class__.__name__, self, other, source='filetype from diffoscope', ), ]) # Don't recurse forever on archive quines, etc. depth = self._as_container.depth no_recurse = depth >= Config().max_container_depth if no_recurse: msg = "Reached max container depth ({})".format(depth) logger.debug(msg) difference.add_comment(msg) details.extend( self.as_container.compare(other.as_container, no_recurse=no_recurse)) details = [x for x in details if x] if not details: return None difference.add_details(details) return difference
def compare_details(self, other, source=None): differences = [] my_fs = '' other_fs = '' if hasattr(self.as_container, 'fs'): my_fs = self.as_container.fs if hasattr(other.as_container, 'fs'): other_fs = other.as_container.fs if my_fs != other_fs: differences.append(Difference.from_text(my_fs, other_fs, None, None, source="filesystem")) return differences
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)
def compare_bytes(self, other, source=None): from .compare import compare_binary_files # Don't attempt to compare directories with any other type as binaries if os.path.isdir(self.path) or os.path.isdir(other.path): return Difference.from_text( "type: {}".format(self.file_type), "type: {}".format(other.file_type), self.name, other.name, source, ) return compare_binary_files(self, other, source)
def compare(self, other, source=None): my_encoding = self.encoding or 'utf-8' other_encoding = other.encoding or 'utf-8' try: with codecs.open(self.path, 'r', encoding=my_encoding) as my_content, \ codecs.open(other.path, 'r', encoding=other_encoding) as other_content: difference = Difference.from_text_readers(my_content, other_content, self.name, other.name, source) if my_encoding != other_encoding: if difference is None: difference = Difference(None, self.path, other.path, source) difference.add_details([Difference.from_text(my_encoding, other_encoding, None, None, source='encoding')]) return difference except (LookupError, UnicodeDecodeError): # unknown or misdetected encoding return self.compare_bytes(other, source)
def compare_details(self, other, source=None): differences = [] with FsImageContainer(self).open() as my_container, \ FsImageContainer(other).open() as other_container: my_fs = '' other_fs = '' if hasattr(my_container, 'fs'): my_fs = my_container.fs if hasattr(other_container, 'fs'): other_fs = other_container.fs if my_fs != other_fs: differences.append(Difference.from_text(my_fs, other_fs, None, None, source="filesystem")) differences.extend(my_container.compare(other_container)) return differences
def compare_details(self, other, source=None): differences = [] for field in sorted(set(self.deb822.keys()).union(set(other.deb822.keys()))): if field.startswith('Checksums-') or field == 'Files': continue my_value = '' if field in self.deb822: my_value = self.deb822.get_as_string(field).lstrip() other_value = '' if field in other.deb822: other_value = other.deb822.get_as_string(field).lstrip() differences.append(Difference.from_text( my_value, other_value, self.path, other.path, source=field)) # compare Files as string differences.append(Difference.from_text(self.deb822.get_as_string('Files'), other.deb822.get_as_string('Files'), self.path, other.path, source='Files')) with DebControlContainer(self).open() as my_container, \ DebControlContainer(other).open() as other_container: differences.extend(my_container.compare(other_container)) return differences
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
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]
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
def compare_details(self, other, source=None): if isinstance(other, MissingFile): return [ Difference( None, self.name, other.name, comment="Trying to compare two non-existing files.", ) ] return [ Difference.from_text( self.dump(self), self.dump(other), self.name, other.name, source='ssconvert', ) ]
def compare_details(self, other, source=None): differences = [] my_fs = '' other_fs = '' if hasattr(self.as_container, 'fs'): my_fs = self.as_container.fs if hasattr(other.as_container, 'fs'): other_fs = other.as_container.fs if my_fs != other_fs: differences.append( Difference.from_text( my_fs, other_fs, None, None, source="filesystem" ) ) if not guestfs: differences.add_comment( "guestfs not available; falling back to binary diff" ) return differences
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]
The command line `ar` tool is not used any more so remove it from the required tools. --- diffoscope/comparators/elf.py.orig 2016-01-31 06:32:02 UTC +++ diffoscope/comparators/elf.py @@ -24,8 +24,9 @@ import subprocess from diffoscope import tool_required, OutputParsingError from diffoscope import logger from diffoscope.comparators.binary import File +from diffoscope.comparators.libarchive import list_libarchive from diffoscope.comparators.deb import DebFile, get_build_id_map -from diffoscope.comparators.utils import get_ar_content, Command, Container +from diffoscope.comparators.utils import Command, Container from diffoscope.difference import Difference @@ -415,10 +416,8 @@ class StaticLibFile(File): def compare_details(self, other, source=None): differences = [] - # look up differences in metadata - content1 = get_ar_content(self.path) - content2 = get_ar_content(other.path) - differences.append(Difference.from_text( - content1, content2, self.path, other.path, source="metadata")) + differences.append(Difference.from_text_readers(list_libarchive(self.path), + list_libarchive(other.path), + self.path, other.path, source="file list")) differences.extend(_compare_elf_data(self.path, other.path)) return differences
def compare_details(self, other, source=None): return [Difference.from_text(self.magic_file_type, other.magic_file_type, self, other, source='metadata')]