Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/unblob/handlers/archive/stuffit.py: 92%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

26 statements  

1"""Stuffit handlers. 

2 

3We currently support detecting two specific Stuffit file formats: 

4 

5 - Stuffit SIT (with 'SIT!' magic) 

6 

7 - Stuffit 5 (with 'StuffIt (c)1997-' magic) 

8 

9Due to lack of access to sample files, source code, and really old 

10packing tools, we don't support the following Stuffit file formats at 

11the moment: 

12 

13 - Stuffit X ('StuffIt!' or 'StuffIt?' magic) 

14 

15 - Stuffit Delux ('SITD' magic) 

16 

17If you have the resources to add support for these archive formats, 

18feel free to do so ! 

19""" 

20 

21from typing import Optional 

22 

23from structlog import get_logger 

24 

25from ...extractors import Command 

26from ...file_utils import Endian 

27from ...models import ( 

28 File, 

29 HandlerDoc, 

30 HandlerType, 

31 HexString, 

32 Reference, 

33 StructHandler, 

34 ValidChunk, 

35) 

36 

37logger = get_logger() 

38 

39 

40class _StuffItHandlerBase(StructHandler): 

41 """A common base for all StuffIt formats.""" 

42 

43 def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]: 

44 header = self.parse_header(file, endian=Endian.BIG) 

45 

46 return ValidChunk( 

47 start_offset=start_offset, 

48 end_offset=start_offset + header.archive_length, 

49 ) 

50 

51 EXTRACTOR = Command("unar", "-no-directory", "-o", "{outdir}", "{inpath}") 

52 

53 

54class StuffItSITHandler(_StuffItHandlerBase): 

55 NAME = "stuffit" 

56 

57 PATTERNS = [ 

58 HexString( 

59 """ 

60 // "SIT!\\x00", then 6 bytes (uint16 number of files and uint32 size), then "rLau". 

61 53 49 54 21 [6] 72 4C 61 75 

62 """ 

63 ) 

64 ] 

65 

66 C_DEFINITIONS = r""" 

67 typedef struct sit_header 

68 { 

69 char signature[4]; 

70 uint16 num_files; 

71 uint32 archive_length; 

72 char signature2[4]; 

73 } sit_header_t; 

74 """ 

75 HEADER_STRUCT = "sit_header_t" 

76 

77 EXTRACTOR = Command("unar", "-no-directory", "-o", "{outdir}", "{inpath}") 

78 

79 DOC = HandlerDoc( 

80 name="Stuffit SIT", 

81 description="StuffIt SIT archives is a legacy compressed archive format commonly used on macOS and earlier Apple systems.", 

82 handler_type=HandlerType.ARCHIVE, 

83 vendor="StuffIt Technologies", 

84 references=[ 

85 Reference( 

86 title="StuffIt SIT File Format Documentation", 

87 url="https://en.wikipedia.org/wiki/StuffIt", 

88 ) 

89 ], 

90 limitations=[], 

91 ) 

92 

93 

94class StuffIt5Handler(_StuffItHandlerBase): 

95 NAME = "stuffit5" 

96 

97 PATTERNS = [ 

98 HexString( 

99 """ 

100 // "StuffIt (c)1997-" 

101 53 74 75 66 66 49 74 20 28 63 29 31 39 39 37 2D 

102 """ 

103 ) 

104 ] 

105 

106 C_DEFINITIONS = r""" 

107 typedef struct stuffit5_header 

108 { 

109 char signature[80]; 

110 uint32 unknown; 

111 uint32 archive_length; 

112 uint32 entry_offset; 

113 uint16 num_root_dir_entries; 

114 uint32 first_entry_offset; 

115 } stuffit5_header_t; 

116 """ 

117 HEADER_STRUCT = "stuffit5_header_t" 

118 

119 EXTRACTOR = Command("unar", "-no-directory", "-o", "{outdir}", "{inpath}") 

120 

121 DOC = HandlerDoc( 

122 name="Stuffit SIT (v5)", 

123 description="StuffIt SIT archives is a legacy compressed archive format commonly used on macOS and earlier Apple systems.", 

124 handler_type=HandlerType.ARCHIVE, 

125 vendor="StuffIt Technologies", 

126 references=[ 

127 Reference( 

128 title="StuffIt SIT File Format Documentation", 

129 url="https://en.wikipedia.org/wiki/StuffIt", 

130 ) 

131 ], 

132 limitations=[], 

133 )