File indexing completed on 2025-02-02 04:26:01
0001 /* Copyright 2015 the unarr project authors (see AUTHORS file). 0002 License: LGPLv3 */ 0003 0004 #ifndef rar_rar_h 0005 #define rar_rar_h 0006 0007 #include "../common/unarr-imp.h" 0008 0009 #include "lzss.h" 0010 #include "../lzmasdk/Ppmd7.h" 0011 #include <limits.h> 0012 0013 static inline size_t smin(size_t a, size_t b) { return a < b ? a : b; } 0014 0015 typedef struct ar_archive_rar_s ar_archive_rar; 0016 0017 /***** parse-rar *****/ 0018 0019 #define FILE_SIGNATURE_SIZE 7 0020 0021 enum block_types { 0022 TYPE_FILE_SIGNATURE = 0x72, TYPE_MAIN_HEADER = 0x73, TYPE_FILE_ENTRY = 0x74, 0023 TYPE_NEWSUB = 0x7A, TYPE_END_OF_ARCHIVE = 0x7B, 0024 }; 0025 0026 enum archive_flags { 0027 MHD_VOLUME = 1 << 0, MHD_COMMENT = 1 << 1, MHD_LOCK = 1 << 2, 0028 MHD_SOLID = 1 << 3, MHD_PACK_COMMENT = 1 << 4, MHD_AV = 1 << 5, 0029 MHD_PROTECT = 1 << 6, MHD_PASSWORD = 1 << 7, MHD_FIRSTVOLUME = 1 << 8, 0030 MHD_ENCRYPTVER = 1 << 9, 0031 MHD_LONG_BLOCK = 1 << 15, 0032 }; 0033 0034 enum entry_flags { 0035 LHD_SPLIT_BEFORE = 1 << 0, LHD_SPLIT_AFTER = 1 << 1, LHD_PASSWORD = 1 << 2, 0036 LHD_COMMENT = 1 << 3, LHD_SOLID = 1 << 4, 0037 LHD_DIRECTORY = (1 << 5) | (1 << 6) | (1 << 7), 0038 LHD_LARGE = 1 << 8, LHD_UNICODE = 1 << 9, LHD_SALT = 1 << 10, 0039 LHD_VERSION = 1 << 11, LHD_EXTTIME = 1 << 12, LHD_EXTFLAGS = 1 << 13, 0040 LHD_LONG_BLOCK = 1 << 15, 0041 }; 0042 0043 enum compression_method { 0044 METHOD_STORE = 0x30, 0045 METHOD_FASTEST = 0x31, METHOD_FAST = 0x32, METHOD_NORMAL = 0x33, 0046 METHOD_GOOD = 0x34, METHOD_BEST = 0x35, 0047 }; 0048 0049 struct rar_header { 0050 uint16_t crc; 0051 uint8_t type; 0052 uint16_t flags; 0053 uint16_t size; 0054 uint64_t datasize; 0055 }; 0056 0057 struct rar_entry { 0058 uint64_t size; 0059 uint8_t os; 0060 uint32_t crc; 0061 uint32_t dosdate; 0062 uint8_t version; 0063 uint8_t method; 0064 uint16_t namelen; 0065 uint32_t attrs; 0066 }; 0067 0068 struct ar_archive_rar_entry { 0069 uint8_t version; 0070 uint8_t method; 0071 uint32_t crc; 0072 uint16_t header_size; 0073 bool solid; 0074 char *name; 0075 }; 0076 0077 bool rar_parse_header(ar_archive *ar, struct rar_header *header); 0078 bool rar_check_header_crc(ar_archive *ar); 0079 bool rar_parse_header_entry(ar_archive_rar *rar, struct rar_header *header, struct rar_entry *entry); 0080 const char *rar_get_name(ar_archive *ar); 0081 0082 /***** filter-rar *****/ 0083 0084 struct RARVirtualMachine; 0085 struct RARProgramCode; 0086 struct RARFilter; 0087 0088 struct ar_archive_rar_filters { 0089 struct RARVirtualMachine *vm; 0090 struct RARProgramCode *progs; 0091 struct RARFilter *stack; 0092 size_t filterstart; 0093 uint32_t lastfilternum; 0094 size_t lastend; 0095 uint8_t *bytes; 0096 size_t bytes_ready; 0097 }; 0098 0099 bool rar_parse_filter(ar_archive_rar *rar, const uint8_t *bytes, uint16_t length, uint8_t flags); 0100 bool rar_run_filters(ar_archive_rar *rar); 0101 void rar_clear_filters(struct ar_archive_rar_filters *filters); 0102 0103 /***** huffman-rar *****/ 0104 0105 struct huffman_code { 0106 struct { 0107 int branches[2]; 0108 } *tree; 0109 int numentries; 0110 int capacity; 0111 int minlength; 0112 int maxlength; 0113 struct { 0114 int length; 0115 int value; 0116 } *table; 0117 int tablesize; 0118 }; 0119 0120 bool rar_new_node(struct huffman_code *code); 0121 bool rar_add_value(struct huffman_code *code, int value, int codebits, int length); 0122 bool rar_create_code(struct huffman_code *code, uint8_t *lengths, int numsymbols); 0123 bool rar_make_table(struct huffman_code *code); 0124 void rar_free_code(struct huffman_code *code); 0125 0126 static inline bool rar_is_leaf_node(struct huffman_code *code, int node) { return code->tree[node].branches[0] == code->tree[node].branches[1]; } 0127 0128 /***** uncompress-rar *****/ 0129 0130 #define LZSS_WINDOW_SIZE 0x400000 0131 #define LZSS_OVERFLOW_SIZE 288 0132 0133 #define MAINCODE_SIZE 299 0134 #define OFFSETCODE_SIZE 60 0135 #define LOWOFFSETCODE_SIZE 17 0136 #define LENGTHCODE_SIZE 28 0137 #define HUFFMAN_TABLE_SIZE MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE 0138 0139 struct ByteReader { 0140 IByteIn super; 0141 ar_archive_rar *rar; 0142 }; 0143 0144 struct CPpmdRAR_RangeDec { 0145 IPpmd7_RangeDec super; 0146 UInt32 Range; 0147 UInt32 Code; 0148 UInt32 Low; 0149 IByteIn *Stream; 0150 }; 0151 0152 struct ar_archive_rar_uncomp_v3 { 0153 struct huffman_code maincode; 0154 struct huffman_code offsetcode; 0155 struct huffman_code lowoffsetcode; 0156 struct huffman_code lengthcode; 0157 uint8_t lengthtable[HUFFMAN_TABLE_SIZE]; 0158 uint32_t lastlength; 0159 uint32_t lastoffset; 0160 uint32_t oldoffset[4]; 0161 uint32_t lastlowoffset; 0162 uint32_t numlowoffsetrepeats; 0163 0164 bool is_ppmd_block; 0165 int ppmd_escape; 0166 CPpmd7 ppmd7_context; 0167 struct CPpmdRAR_RangeDec range_dec; 0168 struct ByteReader bytein; 0169 0170 struct ar_archive_rar_filters filters; 0171 }; 0172 0173 #define MAINCODE_SIZE_20 298 0174 #define OFFSETCODE_SIZE_20 48 0175 #define LENGTHCODE_SIZE_20 28 0176 #define HUFFMAN_TABLE_SIZE_20 4 * 257 0177 0178 struct AudioState { 0179 int8_t weight[5]; 0180 int16_t delta[4]; 0181 int8_t lastdelta; 0182 int error[11]; 0183 int count; 0184 uint8_t lastbyte; 0185 }; 0186 0187 struct ar_archive_rar_uncomp_v2 { 0188 struct huffman_code maincode; 0189 struct huffman_code offsetcode; 0190 struct huffman_code lengthcode; 0191 struct huffman_code audiocode[4]; 0192 uint8_t lengthtable[HUFFMAN_TABLE_SIZE_20]; 0193 uint32_t lastoffset; 0194 uint32_t lastlength; 0195 uint32_t oldoffset[4]; 0196 uint32_t oldoffsetindex; 0197 0198 bool audioblock; 0199 uint8_t channel; 0200 uint8_t numchannels; 0201 struct AudioState audiostate[4]; 0202 int8_t channeldelta; 0203 }; 0204 0205 struct ar_archive_rar_uncomp { 0206 uint8_t version; 0207 0208 LZSS lzss; 0209 size_t bytes_ready; 0210 bool start_new_table; 0211 0212 union { 0213 struct ar_archive_rar_uncomp_v3 v3; 0214 struct ar_archive_rar_uncomp_v2 v2; 0215 } state; 0216 0217 struct StreamBitReader { 0218 uint64_t bits; 0219 int available; 0220 bool at_eof; 0221 } br; 0222 }; 0223 0224 bool rar_uncompress_part(ar_archive_rar *rar, void *buffer, size_t buffer_size); 0225 int64_t rar_expand(ar_archive_rar *rar, int64_t end); 0226 void rar_clear_uncompress(struct ar_archive_rar_uncomp *uncomp); 0227 static inline void br_clear_leftover_bits(struct ar_archive_rar_uncomp *uncomp) { uncomp->br.available &= ~0x07; } 0228 0229 /***** rar *****/ 0230 0231 struct ar_archive_rar_progress { 0232 size_t data_left; 0233 size_t bytes_done; 0234 uint32_t crc; 0235 }; 0236 0237 struct ar_archive_rar_solid { 0238 size_t size_total; 0239 bool part_done; 0240 bool restart; 0241 }; 0242 0243 struct ar_archive_rar_s { 0244 ar_archive super; 0245 uint16_t archive_flags; 0246 struct ar_archive_rar_entry entry; 0247 struct ar_archive_rar_uncomp uncomp; 0248 struct ar_archive_rar_progress progress; 0249 struct ar_archive_rar_solid solid; 0250 }; 0251 0252 #endif