1 /* Copyright 2015 the unarr project authors (see AUTHORS file). 2 License: LGPLv3 */ 3 4 #ifndef zip_zip_h 5 #define zip_zip_h 6 7 #include "../common/unarr-imp.h" 8 9 #ifdef HAVE_ZLIB 10 #include <zlib.h> 11 #endif 12 #include "inflate.h" 13 #ifdef HAVE_BZIP2 14 #include <bzlib.h> 15 #endif 16 #include "../lzmasdk/LzmaDec.h" 17 #include "../lzmasdk/Ppmd8.h" 18 19 typedef struct ar_archive_zip_s ar_archive_zip; 20 21 /***** parse-zip *****/ 22 23 enum zip_signatures { 24 SIG_LOCAL_FILE_HEADER = 0x04034B50, 25 SIG_CENTRAL_DIRECTORY = 0x02014B50, 26 SIG_END_OF_CENTRAL_DIRECTORY_64 = 0x06064B50, 27 SIG_END_OF_CENTRAL_DIRECTORY_64_LOCATOR = 0x07064B50, 28 SIG_END_OF_CENTRAL_DIRECTORY = 0x06054B50, 29 }; 30 31 enum compression_method { 32 METHOD_STORE = 0, METHOD_DEFLATE = 8, 33 METHOD_DEFLATE64 = 9, METHOD_BZIP2 = 12, METHOD_LZMA = 14, 34 METHOD_PPMD = 98, 35 }; 36 37 #define ZIP_LOCAL_ENTRY_FIXED_SIZE 30 38 #define ZIP_DIR_ENTRY_FIXED_SIZE 46 39 #define ZIP_END_OF_CENTRAL_DIR_SIZE 22 40 41 struct zip_entry { 42 uint32_t signature; 43 uint16_t version; 44 uint16_t min_version; 45 uint16_t flags; 46 uint16_t method; 47 uint32_t dosdate; 48 uint32_t crc; 49 uint64_t datasize; 50 uint64_t uncompressed; 51 uint16_t namelen; 52 uint16_t extralen; 53 uint16_t commentlen; 54 uint32_t disk; 55 uint16_t attr_internal; 56 uint32_t attr_external; 57 off64_t header_offset; 58 }; 59 60 struct zip_eocd64 { 61 uint32_t signature; 62 uint16_t version; 63 uint16_t min_version; 64 uint32_t diskno; 65 uint32_t diskno_dir; 66 uint64_t numentries_disk; 67 uint64_t numentries; 68 uint64_t dir_size; 69 off64_t dir_offset; 70 uint16_t commentlen; 71 }; 72 73 struct ar_archive_zip_entry { 74 off64_t offset; 75 uint16_t method; 76 uint16_t flags; 77 uint32_t crc; 78 char *name; 79 uint32_t dosdate; 80 }; 81 82 bool zip_seek_to_compressed_data(ar_archive_zip *zip); 83 bool zip_parse_local_file_entry(ar_archive_zip *zip, struct zip_entry *entry); 84 off64_t zip_find_next_local_file_entry(ar_stream *stream, off64_t offset); 85 bool zip_parse_directory_entry(ar_archive_zip *zip, struct zip_entry *entry); 86 off64_t zip_find_end_of_last_directory_entry(ar_stream *stream, struct zip_eocd64 *eocd); 87 bool zip_parse_end_of_central_directory(ar_stream *stream, struct zip_eocd64 *eocd); 88 off64_t zip_find_end_of_central_directory(ar_stream *stream); 89 const char *zip_get_name(ar_archive *ar); 90 91 /***** uncompress-zip *****/ 92 93 struct ar_archive_zip_uncomp; 94 95 typedef uint32_t (* zip_uncomp_uncompress_data_fn)(struct ar_archive_zip_uncomp *uncomp, void *buffer, uint32_t buffer_size, bool is_last_chunk); 96 typedef void (* zip_uncomp_clear_state_fn)(struct ar_archive_zip_uncomp *uncomp); 97 98 struct InputBuffer { 99 uint8_t data[4096]; 100 uint16_t offset; 101 uint16_t bytes_left; 102 bool at_eof; 103 }; 104 105 struct ByteReader { 106 IByteIn super; 107 struct InputBuffer *input; 108 ar_archive_zip *zip; 109 }; 110 111 struct ar_archive_zip_uncomp { 112 bool initialized; 113 zip_uncomp_uncompress_data_fn uncompress_data; 114 zip_uncomp_clear_state_fn clear_state; 115 union { 116 #ifdef HAVE_ZLIB 117 z_stream zstream; 118 #endif 119 inflate_state *inflate; 120 #ifdef HAVE_BZIP2 121 bz_stream bstream; 122 #endif 123 struct { 124 CLzmaDec dec; 125 ELzmaFinishMode finish; 126 ISzAlloc alloc; 127 } lzma; 128 struct { 129 CPpmd8 ctx; 130 struct ByteReader bytein; 131 ISzAlloc alloc; 132 } ppmd8; 133 } state; 134 struct InputBuffer input; 135 }; 136 137 bool zip_uncompress_part(ar_archive_zip *zip, void *buffer, size_t buffer_size); 138 void zip_clear_uncompress(struct ar_archive_zip_uncomp *uncomp); 139 140 /***** zip *****/ 141 142 struct ar_archive_zip_dir { 143 /* off64_t offset; // use ar_archive::entry_offset_first */ 144 off64_t end_offset; 145 }; 146 147 struct ar_archive_zip_progress { 148 size_t data_left; 149 size_t bytes_done; 150 uint32_t crc; 151 }; 152 153 struct ar_archive_zip_s { 154 ar_archive super; 155 struct ar_archive_zip_dir dir; 156 struct ar_archive_zip_entry entry; 157 struct ar_archive_zip_uncomp uncomp; 158 struct ar_archive_zip_progress progress; 159 bool deflatedonly; 160 off64_t comment_offset; 161 uint16_t comment_size; 162 }; 163 164 #endif 165