diff --git a/refinery/units/formats/ifps.py b/refinery/units/formats/ifps.py index 804fd173e3..dd462d98a7 100644 --- a/refinery/units/formats/ifps.py +++ b/refinery/units/formats/ifps.py @@ -381,28 +381,31 @@ def __repr__(self): return self.represent(self.name or '(*)') @classmethod - def ParseF(cls, reader: StructReader[bytes]): - def readcc(): + def ParseF(cls, reader: StructReader[bytes], load_flags: bool): + def ascii(): + return reader.read_c_string('latin1') + + def boolean(): + return bool(reader.u8()) + + def cc(): return { 0: 'register', 1: 'pascal', 2: 'cdecl', 3: 'stdcall', }.get(reader.u8(), cls.calling_convention) + kw = {} parameters = None if reader.peek(4) == b'dll:': reader.seekrel(4) if reader.peek(6) == B'files:': reader.seekrel(6) - kw.update( - module=reader.read_c_string('latin1'), - name=reader.read_c_string('latin1'), - calling_convention=readcc(), - delay_load=bool(reader.u8()), - load_with_altered_search_path=bool(reader.u8()) - ) - void = not reader.u8() + kw.update(module=ascii(), name=ascii(), calling_convention=cc()) + if load_flags: + kw.update(delay_load=boolean(), load_with_altered_search_path=boolean()) + void = not boolean() elif reader.peek(6) == b'class:': reader.seekrel(6) if reader.remaining_bytes == 1: @@ -420,7 +423,7 @@ def readcc(): if name[-1] == '@': kw.update(is_property=True) name = name[:-1] - kw.update(name=name, calling_convention=readcc()) + kw.update(name=name, calling_convention=cc()) void = not reader.u8() else: void = not reader.u8() @@ -589,6 +592,10 @@ def __init__(self, reader: StructReader[memoryview]): self._load_functions() self._load_variables() + @property + def _load_flags(self): + return self.version >= 23 + def _load_types(self): reader = self.reader types = self.types @@ -687,7 +694,8 @@ def _load_functions(self): if imported: name = reader.read_length_prefixed_ascii(8) if exported: - decl = DeclSpec.ParseF(StructReader(bytes(reader.read_length_prefixed()))) + read = StructReader(bytes(reader.read_length_prefixed())) + decl = DeclSpec.ParseF(read, self._load_flags) else: offset = reader.u32() size = reader.u32() diff --git a/test/units/formats/test_ifps.py b/test/units/formats/test_ifps.py index 3658e0a672..12b9caf232 100644 --- a/test/units/formats/test_ifps.py +++ b/test/units/formats/test_ifps.py @@ -30,3 +30,9 @@ def test_pup_installer_script(self): R'https''://''d1pqn6m5ywnw3a.cloudfront''.''net/f/', ): self.assertIn(string, strings) + + def test_function_signature_parsing_version_22(self): + data = self.download_sample('fb0fc2e3c2059e6159540920a4ff7f75f92212639b318da7eb7fadece4a46ecc') + goal = {'path', 'b512c1_Flash7231FixClass_b512c1', 'mp3-cd-ripper-beta-', 'A1ADB8BE8E677894E', 'M'} + test = data | self.ldu('ifpsstr') | {str} + self.assertSetEqual(test, goal)