Skip to content

Commit ce54c00

Browse files
committed
Begin specializing support for flipping endianness (#3420)
1 parent 77ec810 commit ce54c00

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

polyfile/magic.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,9 @@ def all_extensions(self) -> LazyIterableSet[str]:
877877
"""Returns the set of all possible extensions that this test or any of its descendants could match against"""
878878
return LazyIterableSet(self._all_extensions())
879879

880+
def test_flip_endianness(self, data: bytes, absolute_offset: int, parent_match: Optional[TestResult]) -> TestResult:
881+
raise NotImplementedError(f"TODO: Implement test_flip_endianness for {self.__class__.__name__}")
882+
880883
@abstractmethod
881884
def test(self, data: bytes, absolute_offset: int, parent_match: Optional[TestResult]) -> TestResult:
882885
raise NotImplementedError()
@@ -925,14 +928,22 @@ def write(self, writer: ANSIWriter, is_current_test: bool = False, pre_mime_text
925928
def calculate_absolute_offset(self, data: bytes, parent_match: Optional[TestResult] = None) -> int:
926929
return self.offset.to_absolute(data, parent_match)
927930

928-
def _match(self, context: MatchContext, parent_match: Optional[TestResult] = None) -> Iterator[MatchedTest]:
931+
def _match(
932+
self,
933+
context: MatchContext,
934+
parent_match: Optional[TestResult] = None,
935+
flip_endianness: bool = False
936+
) -> Iterator[MatchedTest]:
929937
if context.only_match_mime and not self.can_match_mime:
930938
return
931939
try:
932940
absolute_offset = self.calculate_absolute_offset(context.data, parent_match)
933941
except InvalidOffsetError:
934942
return
935-
m = self.test(context.data, absolute_offset, parent_match)
943+
if flip_endianness:
944+
m = self.test_flip_endianness(context.data, absolute_offset, parent_match)
945+
else:
946+
m = self.test(context.data, absolute_offset, parent_match)
936947
if logging.root.level <= TRACE and (bool(m) or self.level > 0):
937948
log.trace(
938949
f"{self.source_info!s}\t{bool(m)}\t{absolute_offset}\t"
@@ -943,7 +954,7 @@ def _match(self, context: MatchContext, parent_match: Optional[TestResult] = Non
943954
yield m
944955
for child in self.children:
945956
if not context.only_match_mime or child.can_match_mime:
946-
yield from child._match(context=context, parent_match=m)
957+
yield from child._match(context=context, parent_match=m, flip_endianness=flip_endianness)
947958

948959
def match(self, to_match: Union[bytes, BinaryIO, str, Path, MatchContext]) -> Iterator[TestResult]:
949960
"""Yields all matches for the given data"""
@@ -2235,6 +2246,13 @@ def to_absolute(self, data: bytes, last_match: Optional[TestResult], allow_inval
22352246
def subtest_type(self) -> TestType:
22362247
return TestType.UNKNOWN
22372248

2249+
def test_flip_endianness(self, data: bytes, absolute_offset: int, parent_match: Optional[TestResult]) -> TestResult:
2250+
if parent_match is not None:
2251+
return MatchedTest(self, offset=parent_match.offset + parent_match.length, length=0, value=self.name,
2252+
parent=parent_match)
2253+
else:
2254+
raise ValueError("A named test must always be called from a `use` test.")
2255+
22382256
def test(self, data: bytes, absolute_offset: int, parent_match: Optional[TestResult]) -> MatchedTest:
22392257
if parent_match is not None:
22402258
return MatchedTest(self, offset=parent_match.offset + parent_match.length, length=0, value=self.name,
@@ -2273,9 +2291,13 @@ def referenced_tests(self) -> Set[NamedTest]:
22732291
result |= self.referenced_test.referenced_tests()
22742292
return result
22752293

2276-
def _match(self, context: MatchContext, parent_match: Optional[TestResult] = None) -> Iterator[TestResult]:
2277-
if self.flip_endianness:
2278-
raise NotImplementedError("TODO: Add support for use tests with flipped endianness")
2294+
def _match(
2295+
self,
2296+
context: MatchContext,
2297+
parent_match: Optional[TestResult] = None,
2298+
flip_endianness: bool = False
2299+
) -> Iterator[TestResult]:
2300+
flip_endianness = flip_endianness ^ self.flip_endianness
22792301
try:
22802302
absolute_offset = self.offset.to_absolute(context.data, last_match=parent_match)
22812303
except InvalidOffsetError:
@@ -2285,7 +2307,7 @@ def _match(self, context: MatchContext, parent_match: Optional[TestResult] = Non
22852307
)
22862308
use_match = MatchedTest(self, None, absolute_offset, 0, parent=parent_match)
22872309
yielded = False
2288-
for named_result in self.referenced_test._match(context, use_match):
2310+
for named_result in self.referenced_test._match(context, use_match, flip_endianness=flip_endianness):
22892311
if not yielded:
22902312
yielded = True
22912313
yield use_match
@@ -2298,7 +2320,7 @@ def _match(self, context: MatchContext, parent_match: Optional[TestResult] = Non
22982320
return
22992321
for child in self.children:
23002322
if not context.only_match_mime or child.can_match_mime:
2301-
yield from child._match(context=context, parent_match=use_match)
2323+
yield from child._match(context=context, parent_match=use_match, flip_endianness=flip_endianness)
23022324

23032325
def test(self, data: bytes, absolute_offset: int, parent_match: Optional[TestResult]) -> TestResult:
23042326
raise NotImplementedError("This function should never be called")

0 commit comments

Comments
 (0)