Skip to content
Snippets Groups Projects
Commit fe513c02 authored by FC (Fay) Stegerman's avatar FC (Fay) Stegerman :gay_pride_flag: Committed by Chris Lamb
Browse files

add specialize_as(), use it to speed up .smali comparison in APKs

parent bf334e1d
No related branches found
No related tags found
No related merge requests found
......@@ -35,9 +35,11 @@ from diffoscope.tools import (
)
from diffoscope.tempfiles import get_temporary_directory
from .utils.archive import Archive
from .text import TextFile
from .utils.archive import Archive, ArchiveMember
from .utils.command import Command
from .utils.compare import compare_files
from .utils.specialize import specialize_as
from .zip import ZipContainer, zipinfo_differences, ZipFileBase
from .missing_file import MissingFile
......@@ -157,6 +159,14 @@ class ApkContainer(Archive):
def get_member_names(self):
return self._members
def get_member(self, member_name):
member = ArchiveMember(self, member_name)
if member_name.endswith(".smali") and member_name.startswith("smali"):
# smali{,_classesN}/**/*.smali files from apktool are always text,
# and using libmagic on thousands of these files takes minutes
return specialize_as(TextFile, member)
return member
def extract(self, member_name, dest_dir):
return os.path.join(self._tmpdir.name, member_name)
......
......@@ -28,9 +28,6 @@ logger = logging.getLogger(__name__)
def try_recognize(file, cls, recognizes):
if isinstance(file, cls):
return True
# Does this file class match?
with profile("recognizes", file):
# logger.debug("trying %s on %s", cls, file)
......@@ -43,13 +40,22 @@ def try_recognize(file, cls, recognizes):
format_class(cls, strip="diffoscope.comparators."),
file.name,
)
new_cls = type(cls.__name__, (cls, type(file)), {})
file.__class__ = new_cls
specialize_as(cls, file)
return True
def specialize_as(cls, file):
new_cls = type(cls.__name__, (cls, type(file)), {})
file.__class__ = new_cls
return file
def specialize(file):
for cls in ComparatorManager().classes:
if isinstance(file, cls):
return file
for cls in ComparatorManager().classes:
if try_recognize(file, cls, cls.recognizes):
return file
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment