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