暫無描述

zip.c 73KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916
  1. /* zip.c -- IO on .zip files using zlib
  2. Version 1.1, February 14h, 2010
  3. part of the MiniZip project
  4. Copyright (C) 1998-2010 Gilles Vollant
  5. http://www.winimage.com/zLibDll/minizip.html
  6. Modifications for Zip64 support
  7. Copyright (C) 2009-2010 Mathias Svensson
  8. http://result42.com
  9. Modifications for AES, PKWARE disk spanning
  10. Copyright (C) 2010-2014 Nathan Moinvaziri
  11. This program is distributed under the terms of the same license as zlib.
  12. See the accompanying LICENSE file for the full text of the license.
  13. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <time.h>
  18. #include "zlib.h"
  19. #include "zip.h"
  20. #ifdef STDC
  21. # include <stddef.h>
  22. # include <string.h>
  23. # include <stdlib.h>
  24. #endif
  25. #ifdef NO_ERRNO_H
  26. extern int errno;
  27. #else
  28. # include <errno.h>
  29. #endif
  30. #ifdef HAVE_AES
  31. # define AES_METHOD (99)
  32. # define AES_PWVERIFYSIZE (2)
  33. # define AES_AUTHCODESIZE (10)
  34. # define AES_MAXSALTLENGTH (16)
  35. # define AES_VERSION (0x0001)
  36. # define AES_ENCRYPTIONMODE (0x03)
  37. # include "aes.h"
  38. # include "fileenc.h"
  39. # include "prng.h"
  40. # include "entropy.h"
  41. #endif
  42. #ifndef NOCRYPT
  43. # define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  44. # include "crypt.h"
  45. #endif
  46. #ifndef local
  47. # define local static
  48. #endif
  49. /* compile with -Dlocal if your debugger can't find static symbols */
  50. #define SIZEDATA_INDATABLOCK (4096 - (4 * 4))
  51. #define DISKHEADERMAGIC (0x08074b50)
  52. #define LOCALHEADERMAGIC (0x04034b50)
  53. #define CENTRALHEADERMAGIC (0x02014b50)
  54. #define ENDHEADERMAGIC (0x06054b50)
  55. #define ZIP64ENDHEADERMAGIC (0x06064b50)
  56. #define ZIP64ENDLOCHEADERMAGIC (0x07064b50)
  57. #define FLAG_LOCALHEADER_OFFSET (0x06)
  58. #define CRC_LOCALHEADER_OFFSET (0x0e)
  59. #define SIZECENTRALHEADER (0x2e) /* 46 */
  60. #define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */
  61. #define SIZECENTRALDIRITEM (0x2e)
  62. #define SIZEZIPLOCALHEADER (0x1e)
  63. #ifndef BUFREADCOMMENT
  64. # define BUFREADCOMMENT (0x400)
  65. #endif
  66. #ifndef VERSIONMADEBY
  67. # define VERSIONMADEBY (0x0) /* platform dependent */
  68. #endif
  69. #ifndef Z_BUFSIZE
  70. # define Z_BUFSIZE (64 * 1024)
  71. #endif
  72. #ifndef Z_MAXFILENAMEINZIP
  73. # define Z_MAXFILENAMEINZIP (256)
  74. #endif
  75. #ifndef ALLOC
  76. # define ALLOC(size) (malloc(size))
  77. #endif
  78. #ifndef TRYFREE
  79. # define TRYFREE(p) {if (p) free(p); }
  80. #endif
  81. /* NOT sure that this work on ALL platform */
  82. #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
  83. #ifndef DEF_MEM_LEVEL
  84. # if MAX_MEM_LEVEL >= 8
  85. # define DEF_MEM_LEVEL 8
  86. # else
  87. # define DEF_MEM_LEVEL MAX_MEM_LEVEL
  88. # endif
  89. #endif
  90. const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
  91. typedef struct linkedlist_datablock_internal_s {
  92. struct linkedlist_datablock_internal_s *next_datablock;
  93. uLong avail_in_this_block;
  94. uLong filled_in_this_block;
  95. uLong unused; /* for future use and alignment */
  96. unsigned char data[SIZEDATA_INDATABLOCK];
  97. } linkedlist_datablock_internal;
  98. typedef struct linkedlist_data_s {
  99. linkedlist_datablock_internal *first_block;
  100. linkedlist_datablock_internal *last_block;
  101. } linkedlist_data;
  102. typedef struct {
  103. z_stream stream; /* zLib stream structure for inflate */
  104. #ifdef HAVE_BZIP2
  105. bz_stream bstream; /* bzLib stream structure for bziped */
  106. #endif
  107. #ifdef HAVE_AES
  108. fcrypt_ctx aes_ctx;
  109. prng_ctx aes_rng[1];
  110. #endif
  111. int stream_initialised; /* 1 is stream is initialized */
  112. uInt pos_in_buffered_data; /* last written byte in buffered_data */
  113. ZPOS64_T pos_local_header; /* offset of the local header of the file currently writing */
  114. char *central_header; /* central header data for the current file */
  115. uLong size_centralextra;
  116. uLong size_centralheader; /* size of the central header for cur file */
  117. uLong size_centralextrafree; /* Extra bytes allocated to the central header but that are not used */
  118. uLong size_comment;
  119. uLong flag; /* flag of the file currently writing */
  120. int method; /* compression method written to file.*/
  121. int compression_method; /* compression method to use */
  122. int raw; /* 1 for directly writing raw data */
  123. Byte buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/
  124. uLong dosDate;
  125. uLong crc32;
  126. int zip64; /* Add ZIP64 extended information in the extra field */
  127. uLong number_disk; /* number of current disk used for spanning ZIP */
  128. ZPOS64_T pos_zip64extrainfo;
  129. ZPOS64_T total_compressed;
  130. ZPOS64_T total_uncompressed;
  131. #ifndef NOCRYPT
  132. unsigned long keys[3]; /* keys defining the pseudo-random sequence */
  133. const unsigned long *pcrc_32_tab;
  134. int crypt_header_size;
  135. #endif
  136. } curfile64_info;
  137. typedef struct {
  138. zlib_filefunc64_32_def z_filefunc;
  139. voidpf filestream; /* io structure of the zipfile */
  140. voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */
  141. linkedlist_data central_dir; /* datablock with central dir in construction*/
  142. int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
  143. int append; /* append mode */
  144. curfile64_info ci; /* info on the file currently writing */
  145. ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
  146. ZPOS64_T add_position_when_writting_offset;
  147. ZPOS64_T number_entry;
  148. ZPOS64_T disk_size; /* size of each disk */
  149. uLong number_disk; /* number of the current disk, used for spanning ZIP */
  150. uLong number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
  151. #ifndef NO_ADDFILEINEXISTINGZIP
  152. char *globalcomment;
  153. #endif
  154. } zip64_internal;
  155. /* Allocate a new data block */
  156. local linkedlist_datablock_internal *allocate_new_datablock OF(());
  157. local linkedlist_datablock_internal *allocate_new_datablock()
  158. {
  159. linkedlist_datablock_internal *ldi;
  160. ldi = (linkedlist_datablock_internal *)ALLOC(sizeof(linkedlist_datablock_internal));
  161. if (ldi != NULL) {
  162. ldi->next_datablock = NULL;
  163. ldi->filled_in_this_block = 0;
  164. ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;
  165. }
  166. return ldi;
  167. }
  168. /* Free data block in linked list */
  169. local void free_datablock OF((linkedlist_datablock_internal * ldi));
  170. local void free_datablock(linkedlist_datablock_internal *ldi)
  171. {
  172. while (ldi != NULL) {
  173. linkedlist_datablock_internal *ldinext = ldi->next_datablock;
  174. TRYFREE(ldi);
  175. ldi = ldinext;
  176. }
  177. }
  178. /* Initialize linked list */
  179. local void init_linkedlist OF((linkedlist_data * ll));
  180. local void init_linkedlist(linkedlist_data *ll)
  181. {
  182. ll->first_block = ll->last_block = NULL;
  183. }
  184. /* Free entire linked list and all data blocks */
  185. local void free_linkedlist OF((linkedlist_data * ll));
  186. local void free_linkedlist(linkedlist_data *ll)
  187. {
  188. free_datablock(ll->first_block);
  189. ll->first_block = ll->last_block = NULL;
  190. }
  191. /* Add data to linked list data block */
  192. local int add_data_in_datablock OF((linkedlist_data * ll, const void *buf, uLong len));
  193. local int add_data_in_datablock(linkedlist_data *ll, const void *buf, uLong len)
  194. {
  195. linkedlist_datablock_internal *ldi;
  196. const unsigned char *from_copy;
  197. if (ll == NULL)
  198. return ZIP_INTERNALERROR;
  199. if (ll->last_block == NULL) {
  200. ll->first_block = ll->last_block = allocate_new_datablock();
  201. if (ll->first_block == NULL)
  202. return ZIP_INTERNALERROR;
  203. }
  204. ldi = ll->last_block;
  205. from_copy = (unsigned char *)buf;
  206. while (len > 0) {
  207. uInt copy_this;
  208. uInt i;
  209. unsigned char *to_copy;
  210. if (ldi->avail_in_this_block == 0) {
  211. ldi->next_datablock = allocate_new_datablock();
  212. if (ldi->next_datablock == NULL)
  213. return ZIP_INTERNALERROR;
  214. ldi = ldi->next_datablock;
  215. ll->last_block = ldi;
  216. }
  217. if (ldi->avail_in_this_block < len)
  218. copy_this = (uInt)ldi->avail_in_this_block;
  219. else
  220. copy_this = (uInt)len;
  221. to_copy = &(ldi->data[ldi->filled_in_this_block]);
  222. for (i = 0; i < copy_this; i++)
  223. *(to_copy + i) = *(from_copy + i);
  224. ldi->filled_in_this_block += copy_this;
  225. ldi->avail_in_this_block -= copy_this;
  226. from_copy += copy_this;
  227. len -= copy_this;
  228. }
  229. return ZIP_OK;
  230. }
  231. local uLong zip64local_TmzDateToDosDate OF((const tm_zip * ptm));
  232. local uLong zip64local_TmzDateToDosDate(const tm_zip *ptm)
  233. {
  234. uLong year;
  235. #define zip64local_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
  236. /* Years supported:
  237. * [00, 79] (assumed to be between 2000 and 2079)
  238. * [80, 207] (assumed to be between 1980 and 2107, typical output of old
  239. software that does 'year-1900' to get a double digit year)
  240. * [1980, 2107]
  241. Due to the date format limitations, only years between 1980 and 2107 can be stored.
  242. */
  243. if (!(zip64local_in_range(1980, 2107, ptm->tm_year) || zip64local_in_range(0, 207, ptm->tm_year)) ||
  244. !zip64local_in_range(0, 11, ptm->tm_mon) ||
  245. !zip64local_in_range(1, 31, ptm->tm_mday) ||
  246. !zip64local_in_range(0, 23, ptm->tm_hour) ||
  247. !zip64local_in_range(0, 59, ptm->tm_min) ||
  248. !zip64local_in_range(0, 59, ptm->tm_sec))
  249. return 0;
  250. #undef zip64local_in_range
  251. year = (uLong)ptm->tm_year;
  252. if (year >= 1980) /* range [1980, 2107] */
  253. year -= 1980;
  254. else if (year >= 80) /* range [80, 99] */
  255. year -= 80;
  256. else /* range [00, 79] */
  257. year += 20;
  258. return
  259. (uLong)(((ptm->tm_mday) + (32 * (ptm->tm_mon + 1)) + (512 * year)) << 16) |
  260. ((ptm->tm_sec / 2) + (32 * ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
  261. }
  262. /* Inputs a long in LSB order to the given file: nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */
  263. local int zip64local_putValue OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream,
  264. ZPOS64_T x, int nbByte));
  265. local int zip64local_putValue(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
  266. ZPOS64_T x, int nbByte)
  267. {
  268. unsigned char buf[8];
  269. int n;
  270. for (n = 0; n < nbByte; n++) {
  271. buf[n] = (unsigned char)(x & 0xff);
  272. x >>= 8;
  273. }
  274. if (x != 0) {
  275. /* data overflow - hack for ZIP64 (X Roche) */
  276. for (n = 0; n < nbByte; n++) {
  277. buf[n] = 0xff;
  278. }
  279. }
  280. if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, nbByte) != (uLong)nbByte)
  281. return ZIP_ERRNO;
  282. return ZIP_OK;
  283. }
  284. local void zip64local_putValue_inmemory OF((void *dest, ZPOS64_T x, int nbByte));
  285. local void zip64local_putValue_inmemory(void *dest, ZPOS64_T x, int nbByte)
  286. {
  287. unsigned char *buf = (unsigned char *)dest;
  288. int n;
  289. for (n = 0; n < nbByte; n++) {
  290. buf[n] = (unsigned char)(x & 0xff);
  291. x >>= 8;
  292. }
  293. if (x != 0) {
  294. /* data overflow - hack for ZIP64 */
  295. for (n = 0; n < nbByte; n++) {
  296. buf[n] = 0xff;
  297. }
  298. }
  299. }
  300. local int zip64local_getByte OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, int *pi));
  301. local int zip64local_getByte(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, int *pi)
  302. {
  303. unsigned char c;
  304. int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c, 1);
  305. if (err == 1) {
  306. *pi = (int)c;
  307. return ZIP_OK;
  308. }
  309. if (ZERROR64(*pzlib_filefunc_def, filestream))
  310. return ZIP_ERRNO;
  311. return ZIP_EOF;
  312. }
  313. local int zip64local_getShort OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));
  314. local int zip64local_getShort(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)
  315. {
  316. uLong x;
  317. int i = 0;
  318. int err;
  319. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  320. x = (uLong)i;
  321. if (err == ZIP_OK)
  322. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  323. x += ((uLong)i) << 8;
  324. if (err == ZIP_OK)
  325. *pX = x;
  326. else
  327. *pX = 0;
  328. return err;
  329. }
  330. local int zip64local_getLong OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));
  331. local int zip64local_getLong(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)
  332. {
  333. uLong x;
  334. int i = 0;
  335. int err;
  336. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  337. x = (uLong)i;
  338. if (err == ZIP_OK)
  339. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  340. x += ((uLong)i) << 8;
  341. if (err == ZIP_OK)
  342. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  343. x += ((uLong)i) << 16;
  344. if (err == ZIP_OK)
  345. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  346. x += ((uLong)i) << 24;
  347. if (err == ZIP_OK)
  348. *pX = x;
  349. else
  350. *pX = 0;
  351. return err;
  352. }
  353. local int zip64local_getLong64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, ZPOS64_T * pX));
  354. local int zip64local_getLong64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
  355. {
  356. ZPOS64_T x;
  357. int i = 0;
  358. int err;
  359. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  360. x = (ZPOS64_T)i;
  361. if (err == ZIP_OK)
  362. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  363. x += ((ZPOS64_T)i) << 8;
  364. if (err == ZIP_OK)
  365. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  366. x += ((ZPOS64_T)i) << 16;
  367. if (err == ZIP_OK)
  368. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  369. x += ((ZPOS64_T)i) << 24;
  370. if (err == ZIP_OK)
  371. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  372. x += ((ZPOS64_T)i) << 32;
  373. if (err == ZIP_OK)
  374. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  375. x += ((ZPOS64_T)i) << 40;
  376. if (err == ZIP_OK)
  377. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  378. x += ((ZPOS64_T)i) << 48;
  379. if (err == ZIP_OK)
  380. err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);
  381. x += ((ZPOS64_T)i) << 56;
  382. if (err == ZIP_OK)
  383. *pX = x;
  384. else
  385. *pX = 0;
  386. return err;
  387. }
  388. /* Gets the amount of bytes left to write to the current disk for spanning archives */
  389. local int zipGetDiskSizeAvailable OF((zipFile file, ZPOS64_T * size_available));
  390. local int zipGetDiskSizeAvailable(zipFile file, ZPOS64_T *size_available)
  391. {
  392. zip64_internal *zi;
  393. ZPOS64_T current_disk_size;
  394. zi = (zip64_internal *)file;
  395. ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
  396. current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);
  397. *size_available = zi->disk_size - current_disk_size;
  398. return ZIP_OK;
  399. }
  400. /* Goes to a specific disk number for spanning archives */
  401. local int zipGoToSpecificDisk OF((zipFile file, int number_disk, int open_existing));
  402. local int zipGoToSpecificDisk(zipFile file, int number_disk, int open_existing)
  403. {
  404. zip64_internal *zi;
  405. int err = ZIP_OK;
  406. zi = (zip64_internal *)file;
  407. if (zi->disk_size == 0)
  408. return err;
  409. if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))
  410. ZCLOSE64(zi->z_filefunc, zi->filestream);
  411. zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ?
  412. (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :
  413. (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));
  414. if (zi->filestream == NULL)
  415. err = ZIP_ERRNO;
  416. return err;
  417. }
  418. /* Goes to the first disk in a spanned archive */
  419. local int zipGoToFirstDisk OF((zipFile file));
  420. local int zipGoToFirstDisk(zipFile file)
  421. {
  422. zip64_internal *zi;
  423. int number_disk_next;
  424. int err = ZIP_OK;
  425. zi = (zip64_internal *)file;
  426. if (zi->disk_size == 0)
  427. return err;
  428. number_disk_next = 0;
  429. if (zi->number_disk_with_CD > 0)
  430. number_disk_next = (int)zi->number_disk_with_CD - 1;
  431. err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
  432. if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
  433. err = zipGoToSpecificDisk(file, number_disk_next, 0);
  434. if (err == ZIP_OK)
  435. zi->number_disk = number_disk_next;
  436. ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
  437. return err;
  438. }
  439. /* Goes to the next disk in a spanned archive */
  440. local int zipGoToNextDisk OF((zipFile file));
  441. local int zipGoToNextDisk(zipFile file)
  442. {
  443. zip64_internal *zi;
  444. ZPOS64_T size_available_in_disk;
  445. int err = ZIP_OK;
  446. int number_disk_next;
  447. zi = (zip64_internal *)file;
  448. if (zi->disk_size == 0)
  449. return err;
  450. number_disk_next = (int)zi->number_disk + 1;
  451. do {
  452. err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
  453. if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
  454. err = zipGoToSpecificDisk(file, number_disk_next, 0);
  455. if (err != ZIP_OK)
  456. break;
  457. err = zipGetDiskSizeAvailable(file, &size_available_in_disk);
  458. if (err != ZIP_OK)
  459. break;
  460. zi->number_disk = number_disk_next;
  461. zi->number_disk_with_CD = zi->number_disk + 1;
  462. number_disk_next += 1;
  463. } while (size_available_in_disk <= 0);
  464. return err;
  465. }
  466. /* Locate the Central directory of a zipfile (at the end, just before the global comment) */
  467. local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream));
  468. local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
  469. {
  470. unsigned char *buf;
  471. ZPOS64_T file_size;
  472. ZPOS64_T back_read = 4;
  473. ZPOS64_T max_back = 0xffff; /* maximum size of global comment */
  474. ZPOS64_T pos_found = 0;
  475. uLong read_size;
  476. ZPOS64_T read_pos;
  477. int i;
  478. buf = (unsigned char *)ALLOC(BUFREADCOMMENT + 4);
  479. if (buf == NULL)
  480. return 0;
  481. if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) {
  482. TRYFREE(buf);
  483. return 0;
  484. }
  485. file_size = ZTELL64(*pzlib_filefunc_def, filestream);
  486. if (max_back > file_size)
  487. max_back = file_size;
  488. while (back_read < max_back) {
  489. if (back_read + BUFREADCOMMENT > max_back)
  490. back_read = max_back;
  491. else
  492. back_read += BUFREADCOMMENT;
  493. read_pos = file_size - back_read;
  494. read_size = ((BUFREADCOMMENT + 4) < (file_size - read_pos)) ?
  495. (BUFREADCOMMENT + 4) : (uLong)(file_size - read_pos);
  496. if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
  497. break;
  498. if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)
  499. break;
  500. for (i = (int)read_size - 3; (i--) > 0; )
  501. if ((*(buf + i)) == (ENDHEADERMAGIC & 0xff) &&
  502. (*(buf + i + 1)) == (ENDHEADERMAGIC >> 8 & 0xff) &&
  503. (*(buf + i + 2)) == (ENDHEADERMAGIC >> 16 & 0xff) &&
  504. (*(buf + i + 3)) == (ENDHEADERMAGIC >> 24 & 0xff)) {
  505. pos_found = read_pos + i;
  506. break;
  507. }
  508. if (pos_found != 0)
  509. break;
  510. }
  511. TRYFREE(buf);
  512. return pos_found;
  513. }
  514. /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
  515. local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream,
  516. const ZPOS64_T endcentraloffset));
  517. local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
  518. const ZPOS64_T endcentraloffset)
  519. {
  520. ZPOS64_T offset;
  521. uLong uL;
  522. /* Zip64 end of central directory locator */
  523. if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
  524. return 0;
  525. /* read locator signature */
  526. if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)
  527. return 0;
  528. if (uL != ZIP64ENDLOCHEADERMAGIC)
  529. return 0;
  530. /* number of the disk with the start of the zip64 end of central directory */
  531. if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)
  532. return 0;
  533. /* relative offset of the zip64 end of central directory record */
  534. if (zip64local_getLong64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK)
  535. return 0;
  536. /* total number of disks */
  537. if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)
  538. return 0;
  539. /* Goto end of central directory record */
  540. if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
  541. return 0;
  542. /* the signature */
  543. if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)
  544. return 0;
  545. if (uL != ZIP64ENDHEADERMAGIC)
  546. return 0;
  547. return offset;
  548. }
  549. extern zipFile ZEXPORT zipOpen4(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,
  550. zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
  551. {
  552. zip64_internal ziinit;
  553. zip64_internal *zi;
  554. #ifndef NO_ADDFILEINEXISTINGZIP
  555. ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/
  556. ZPOS64_T size_central_dir = 0; /* size of the central directory */
  557. ZPOS64_T offset_central_dir = 0; /* offset of start of central directory */
  558. ZPOS64_T number_entry_CD = 0; /* total number of entries in the central dir */
  559. ZPOS64_T number_entry;
  560. ZPOS64_T central_pos;
  561. ZPOS64_T size_central_dir_to_read;
  562. uLong uL;
  563. uLong size_comment = 0;
  564. size_t buf_size = SIZEDATA_INDATABLOCK;
  565. void *buf_read;
  566. #endif
  567. int err = ZIP_OK;
  568. int mode;
  569. ziinit.z_filefunc.zseek32_file = NULL;
  570. ziinit.z_filefunc.ztell32_file = NULL;
  571. if (pzlib_filefunc64_32_def == NULL)
  572. fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
  573. else
  574. ziinit.z_filefunc = *pzlib_filefunc64_32_def;
  575. if (append == APPEND_STATUS_CREATE)
  576. mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE);
  577. else
  578. mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING);
  579. ziinit.filestream = ZOPEN64(ziinit.z_filefunc, pathname, mode);
  580. if (ziinit.filestream == NULL)
  581. return NULL;
  582. if (append == APPEND_STATUS_CREATEAFTER) {
  583. /* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */
  584. if (disk_size > 0)
  585. return NULL;
  586. ZSEEK64(ziinit.z_filefunc, ziinit.filestream, 0, SEEK_END);
  587. }
  588. ziinit.filestream_with_CD = ziinit.filestream;
  589. ziinit.append = append;
  590. ziinit.number_disk = 0;
  591. ziinit.number_disk_with_CD = 0;
  592. ziinit.disk_size = disk_size;
  593. ziinit.begin_pos = ZTELL64(ziinit.z_filefunc, ziinit.filestream);
  594. ziinit.in_opened_file_inzip = 0;
  595. ziinit.ci.stream_initialised = 0;
  596. ziinit.number_entry = 0;
  597. ziinit.add_position_when_writting_offset = 0;
  598. init_linkedlist(&(ziinit.central_dir));
  599. zi = (zip64_internal *)ALLOC(sizeof(zip64_internal));
  600. if (zi == NULL) {
  601. ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
  602. return NULL;
  603. }
  604. #ifndef NO_ADDFILEINEXISTINGZIP
  605. /* Add file in a zipfile */
  606. ziinit.globalcomment = NULL;
  607. if (append == APPEND_STATUS_ADDINZIP) {
  608. /* Read and Cache Central Directory Records */
  609. central_pos = zip64local_SearchCentralDir(&ziinit.z_filefunc, ziinit.filestream);
  610. /* disable to allow appending to empty ZIP archive (must be standard zip, not zip64)
  611. if (central_pos == 0)
  612. err = ZIP_ERRNO;
  613. */
  614. if (err == ZIP_OK) {
  615. /* read end of central directory info */
  616. if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
  617. err = ZIP_ERRNO;
  618. /* the signature, already checked */
  619. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  620. err = ZIP_ERRNO;
  621. /* number of this disk */
  622. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)
  623. err = ZIP_ERRNO;
  624. /* number of the disk with the start of the central directory */
  625. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)
  626. err = ZIP_ERRNO;
  627. /* total number of entries in the central dir on this disk */
  628. number_entry = 0;
  629. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  630. err = ZIP_ERRNO;
  631. else
  632. number_entry = uL;
  633. /* total number of entries in the central dir */
  634. number_entry_CD = 0;
  635. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  636. err = ZIP_ERRNO;
  637. else
  638. number_entry_CD = uL;
  639. if (number_entry_CD != number_entry)
  640. err = ZIP_BADZIPFILE;
  641. /* size of the central directory */
  642. size_central_dir = 0;
  643. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  644. err = ZIP_ERRNO;
  645. else
  646. size_central_dir = uL;
  647. /* offset of start of central directory with respect to the starting disk number */
  648. offset_central_dir = 0;
  649. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  650. err = ZIP_ERRNO;
  651. else
  652. offset_central_dir = uL;
  653. /* zipfile global comment length */
  654. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK)
  655. err = ZIP_ERRNO;
  656. if ((err == ZIP_OK) && ((number_entry_CD == 0xffff) || (offset_central_dir == 0xffffffff))) {
  657. /* Format should be Zip64, as the central directory or file size is too large */
  658. central_pos = zip64local_SearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos);
  659. if (central_pos) {
  660. ZPOS64_T sizeEndOfCentralDirectory;
  661. if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
  662. err = ZIP_ERRNO;
  663. /* the signature, already checked */
  664. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  665. err = ZIP_ERRNO;
  666. /* size of zip64 end of central directory record */
  667. if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK)
  668. err = ZIP_ERRNO;
  669. /* version made by */
  670. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  671. err = ZIP_ERRNO;
  672. /* version needed to extract */
  673. if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)
  674. err = ZIP_ERRNO;
  675. /* number of this disk */
  676. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)
  677. err = ZIP_ERRNO;
  678. /* number of the disk with the start of the central directory */
  679. if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)
  680. err = ZIP_ERRNO;
  681. /* total number of entries in the central directory on this disk */
  682. if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK)
  683. err = ZIP_ERRNO;
  684. /* total number of entries in the central directory */
  685. if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK)
  686. err = ZIP_ERRNO;
  687. if (number_entry_CD != number_entry)
  688. err = ZIP_BADZIPFILE;
  689. /* size of the central directory */
  690. if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK)
  691. err = ZIP_ERRNO;
  692. /* offset of start of central directory with respect to the starting disk number */
  693. if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK)
  694. err = ZIP_ERRNO;
  695. } else
  696. err = ZIP_BADZIPFILE;
  697. }
  698. }
  699. if ((err == ZIP_OK) && (central_pos < offset_central_dir + size_central_dir))
  700. err = ZIP_BADZIPFILE;
  701. if (err != ZIP_OK) {
  702. ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
  703. TRYFREE(zi);
  704. return NULL;
  705. }
  706. if (size_comment > 0) {
  707. ziinit.globalcomment = (char *)ALLOC(size_comment + 1);
  708. if (ziinit.globalcomment) {
  709. size_comment = ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment);
  710. ziinit.globalcomment[size_comment] = 0;
  711. }
  712. }
  713. byte_before_the_zipfile = central_pos - (offset_central_dir + size_central_dir);
  714. ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
  715. /* Store central directory in memory */
  716. size_central_dir_to_read = size_central_dir;
  717. buf_size = SIZEDATA_INDATABLOCK;
  718. buf_read = (void *)ALLOC(buf_size);
  719. if (buf_read == NULL)
  720. err = ZIP_INTERNALERROR;
  721. if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
  722. offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
  723. err = ZIP_ERRNO;
  724. while ((size_central_dir_to_read > 0) && (err == ZIP_OK)) {
  725. ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
  726. if (read_this > size_central_dir_to_read)
  727. read_this = size_central_dir_to_read;
  728. if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uLong)read_this) != read_this)
  729. err = ZIP_ERRNO;
  730. if (err == ZIP_OK)
  731. err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uLong)read_this);
  732. size_central_dir_to_read -= read_this;
  733. }
  734. TRYFREE(buf_read);
  735. ziinit.begin_pos = byte_before_the_zipfile;
  736. ziinit.number_entry = number_entry_CD;
  737. if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
  738. offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
  739. err = ZIP_ERRNO;
  740. }
  741. if (globalcomment)
  742. *globalcomment = ziinit.globalcomment;
  743. #endif
  744. if (err != ZIP_OK) {
  745. #ifndef NO_ADDFILEINEXISTINGZIP
  746. TRYFREE(ziinit.globalcomment);
  747. #endif
  748. TRYFREE(zi);
  749. return NULL;
  750. }
  751. *zi = ziinit;
  752. zipGoToFirstDisk((zipFile)zi);
  753. return (zipFile)zi;
  754. }
  755. extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc *globalcomment,
  756. zlib_filefunc_def *pzlib_filefunc32_def)
  757. {
  758. if (pzlib_filefunc32_def != NULL) {
  759. zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  760. fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
  761. return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
  762. }
  763. return zipOpen4(pathname, append, 0, globalcomment, NULL);
  764. }
  765. extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc *globalcomment,
  766. zlib_filefunc64_def *pzlib_filefunc_def)
  767. {
  768. if (pzlib_filefunc_def != NULL) {
  769. zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  770. zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
  771. zlib_filefunc64_32_def_fill.ztell32_file = NULL;
  772. zlib_filefunc64_32_def_fill.zseek32_file = NULL;
  773. return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
  774. }
  775. return zipOpen4(pathname, append, 0, globalcomment, NULL);
  776. }
  777. extern zipFile ZEXPORT zipOpen3(const char *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,
  778. zlib_filefunc_def *pzlib_filefunc32_def)
  779. {
  780. if (pzlib_filefunc32_def != NULL) {
  781. zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  782. fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
  783. return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
  784. }
  785. return zipOpen4(pathname, append, disk_size, globalcomment, NULL);
  786. }
  787. extern zipFile ZEXPORT zipOpen3_64(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,
  788. zlib_filefunc64_def *pzlib_filefunc_def)
  789. {
  790. if (pzlib_filefunc_def != NULL) {
  791. zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  792. zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
  793. zlib_filefunc64_32_def_fill.ztell32_file = NULL;
  794. zlib_filefunc64_32_def_fill.zseek32_file = NULL;
  795. return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
  796. }
  797. return zipOpen4(pathname, append, disk_size, globalcomment, NULL);
  798. }
  799. extern zipFile ZEXPORT zipOpen(const char *pathname, int append)
  800. {
  801. return zipOpen3((const void *)pathname, append, 0, NULL, NULL);
  802. }
  803. extern zipFile ZEXPORT zipOpen64(const void *pathname, int append)
  804. {
  805. return zipOpen3(pathname, append, 0, NULL, NULL);
  806. }
  807. extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  808. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  809. uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel,
  810. int strategy, const char *password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64)
  811. {
  812. zip64_internal *zi;
  813. uInt size_filename;
  814. uInt size_comment = 0;
  815. uInt i;
  816. int err = ZIP_OK;
  817. ZPOS64_T size_available;
  818. ZPOS64_T size_needed;
  819. #ifdef NOCRYPT
  820. (crcForCrypting);
  821. if (password != NULL)
  822. return ZIP_PARAMERROR;
  823. #endif
  824. if (file == NULL)
  825. return ZIP_PARAMERROR;
  826. if ((method != 0) &&
  827. #ifdef HAVE_BZIP2
  828. (method != Z_BZIP2ED) &&
  829. #endif
  830. (method != Z_DEFLATED))
  831. return ZIP_PARAMERROR;
  832. zi = (zip64_internal *)file;
  833. if (zi->in_opened_file_inzip == 1) {
  834. err = zipCloseFileInZip(file);
  835. if (err != ZIP_OK)
  836. return err;
  837. }
  838. if (filename == NULL)
  839. filename = "-";
  840. if (comment != NULL)
  841. size_comment = (uInt)strlen(comment);
  842. size_filename = (uInt)strlen(filename);
  843. if (zipfi == NULL)
  844. zi->ci.dosDate = 0;
  845. else {
  846. if (zipfi->dosDate != 0)
  847. zi->ci.dosDate = zipfi->dosDate;
  848. else
  849. zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
  850. }
  851. zi->ci.method = method;
  852. zi->ci.compression_method = method;
  853. zi->ci.crc32 = 0;
  854. zi->ci.stream_initialised = 0;
  855. zi->ci.pos_in_buffered_data = 0;
  856. zi->ci.raw = raw;
  857. zi->ci.flag = flagBase;
  858. if ((level == 8) || (level == 9))
  859. zi->ci.flag |= 2;
  860. if (level == 2)
  861. zi->ci.flag |= 4;
  862. if (level == 1)
  863. zi->ci.flag |= 6;
  864. if (password != NULL) {
  865. zi->ci.flag |= 1;
  866. #ifdef HAVE_AES
  867. zi->ci.method = AES_METHOD;
  868. #endif
  869. }
  870. if (zi->disk_size > 0) {
  871. if ((zi->number_disk == 0) && (zi->number_entry == 0))
  872. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)DISKHEADERMAGIC, 4);
  873. /* Make sure enough space available on current disk for local header */
  874. zipGetDiskSizeAvailable((zipFile)zi, &size_available);
  875. size_needed = 30 + size_filename + size_extrafield_local;
  876. if (zi->ci.zip64)
  877. size_needed += 20;
  878. #ifdef HAVE_AES
  879. if (zi->ci.method == AES_METHOD)
  880. size_needed += 11;
  881. #endif
  882. if (size_available < size_needed)
  883. zipGoToNextDisk((zipFile)zi);
  884. }
  885. zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream);
  886. zi->ci.size_comment = size_comment;
  887. zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global;
  888. zi->ci.size_centralextra = size_extrafield_global;
  889. zi->ci.size_centralextrafree = 32; /* Extra space reserved for ZIP64 extra info */
  890. #ifdef HAVE_AES
  891. if (zi->ci.method == AES_METHOD)
  892. zi->ci.size_centralextrafree += 11; /* Extra space reserved for AES extra info */
  893. #endif
  894. zi->ci.central_header = (char *)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralextrafree + size_comment);
  895. if (zi->ci.central_header == NULL)
  896. return ZIP_INTERNALERROR;
  897. zi->ci.number_disk = zi->number_disk;
  898. /* Write central directory header */
  899. zip64local_putValue_inmemory(zi->ci.central_header, (uLong)CENTRALHEADERMAGIC, 4);
  900. zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)versionMadeBy, 2);
  901. zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)20, 2);
  902. zip64local_putValue_inmemory(zi->ci.central_header + 8, (uLong)zi->ci.flag, 2);
  903. zip64local_putValue_inmemory(zi->ci.central_header + 10, (uLong)zi->ci.method, 2);
  904. zip64local_putValue_inmemory(zi->ci.central_header + 12, (uLong)zi->ci.dosDate, 4);
  905. zip64local_putValue_inmemory(zi->ci.central_header + 16, (uLong)0, 4); /*crc*/
  906. zip64local_putValue_inmemory(zi->ci.central_header + 20, (uLong)0, 4); /*compr size*/
  907. zip64local_putValue_inmemory(zi->ci.central_header + 24, (uLong)0, 4); /*uncompr size*/
  908. zip64local_putValue_inmemory(zi->ci.central_header + 28, (uLong)size_filename, 2);
  909. zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)size_extrafield_global, 2);
  910. zip64local_putValue_inmemory(zi->ci.central_header + 32, (uLong)size_comment, 2);
  911. zip64local_putValue_inmemory(zi->ci.central_header + 34, (uLong)zi->ci.number_disk, 2); /*disk nm start*/
  912. if (zipfi == NULL)
  913. zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)0, 2);
  914. else
  915. zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)zipfi->internal_fa, 2);
  916. if (zipfi == NULL)
  917. zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)0, 4);
  918. else
  919. zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)zipfi->external_fa, 4);
  920. if (zi->ci.pos_local_header >= 0xffffffff)
  921. zip64local_putValue_inmemory(zi->ci.central_header + 42, (uLong)0xffffffff, 4);
  922. else
  923. zip64local_putValue_inmemory(zi->ci.central_header + 42,
  924. (uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4);
  925. for (i = 0; i < size_filename; i++)
  926. zi->ci.central_header[SIZECENTRALHEADER + i] = filename[i];
  927. for (i = 0; i < size_extrafield_global; i++)
  928. zi->ci.central_header[SIZECENTRALHEADER + size_filename + i] =
  929. ((const char *)extrafield_global)[i];
  930. /* Store comment at the end for later repositioning */
  931. for (i = 0; i < size_comment; i++)
  932. zi->ci.central_header[zi->ci.size_centralheader +
  933. zi->ci.size_centralextrafree + i] = comment[i];
  934. if (zi->ci.central_header == NULL)
  935. return ZIP_INTERNALERROR;
  936. zi->ci.zip64 = zip64;
  937. zi->ci.total_compressed = 0;
  938. zi->ci.total_uncompressed = 0;
  939. zi->ci.pos_zip64extrainfo = 0;
  940. /* Write the local header */
  941. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)LOCALHEADERMAGIC, 4);
  942. if (err == ZIP_OK) {
  943. if (zi->ci.zip64)
  944. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); /* version needed to extract */
  945. else
  946. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)20, 2); /* version needed to extract */
  947. }
  948. if (err == ZIP_OK)
  949. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.flag, 2);
  950. if (err == ZIP_OK)
  951. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.method, 2);
  952. if (err == ZIP_OK)
  953. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.dosDate, 4);
  954. /* CRC & compressed size & uncompressed size will be filled in later and rewritten later */
  955. if (err == ZIP_OK)
  956. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* crc 32, unknown */
  957. if (err == ZIP_OK) {
  958. if (zi->ci.zip64)
  959. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); /* compressed size, unknown */
  960. else
  961. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* compressed size, unknown */
  962. }
  963. if (err == ZIP_OK) {
  964. if (zi->ci.zip64) /* uncompressed size, unknown */
  965. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4);
  966. else /* uncompressed size, unknown */
  967. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4);
  968. }
  969. if (err == ZIP_OK)
  970. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_filename, 2);
  971. if (err == ZIP_OK) {
  972. ZPOS64_T size_extrafield = size_extrafield_local;
  973. if (zi->ci.zip64)
  974. size_extrafield += 20;
  975. #ifdef HAVE_AES
  976. if (zi->ci.method == AES_METHOD)
  977. size_extrafield += 11;
  978. #endif
  979. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_extrafield, 2);
  980. }
  981. if ((err == ZIP_OK) && (size_filename > 0)) {
  982. if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename)
  983. err = ZIP_ERRNO;
  984. }
  985. if ((err == ZIP_OK) && (size_extrafield_local > 0)) {
  986. if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
  987. err = ZIP_ERRNO;
  988. }
  989. /* Write the Zip64 extended info */
  990. if ((err == ZIP_OK) && (zi->ci.zip64)) {
  991. short headerid = 1;
  992. short datasize = 16;
  993. ZPOS64_T compressed_size = 0;
  994. ZPOS64_T uncompressed_size = 0;
  995. /* Remember position of Zip64 extended info for the local file header.
  996. (needed when we update size after done with file) */
  997. zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc, zi->filestream);
  998. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)headerid, 2);
  999. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)datasize, 2);
  1000. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)uncompressed_size, 8);
  1001. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)compressed_size, 8);
  1002. }
  1003. #ifdef HAVE_AES
  1004. /* Write the AES extended info */
  1005. if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD)) {
  1006. int headerid = 0x9901;
  1007. short datasize = 7;
  1008. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, headerid, 2);
  1009. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, datasize, 2);
  1010. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2);
  1011. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'A', 1);
  1012. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'E', 1);
  1013. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1);
  1014. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2);
  1015. }
  1016. #endif
  1017. #ifdef HAVE_BZIP2
  1018. zi->ci.bstream.avail_in = (uInt)0;
  1019. zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1020. zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;
  1021. zi->ci.bstream.total_in_hi32 = 0;
  1022. zi->ci.bstream.total_in_lo32 = 0;
  1023. zi->ci.bstream.total_out_hi32 = 0;
  1024. zi->ci.bstream.total_out_lo32 = 0;
  1025. #endif
  1026. zi->ci.stream.avail_in = (uInt)0;
  1027. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1028. zi->ci.stream.next_out = zi->ci.buffered_data;
  1029. zi->ci.stream.total_in = 0;
  1030. zi->ci.stream.total_out = 0;
  1031. zi->ci.stream.data_type = Z_BINARY;
  1032. if ((err == ZIP_OK) && (!zi->ci.raw)) {
  1033. if (method == Z_DEFLATED) {
  1034. zi->ci.stream.zalloc = (alloc_func)0;
  1035. zi->ci.stream.zfree = (free_func)0;
  1036. zi->ci.stream.opaque = (voidpf)zi;
  1037. if (windowBits > 0)
  1038. windowBits = -windowBits;
  1039. err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
  1040. if (err == Z_OK)
  1041. zi->ci.stream_initialised = Z_DEFLATED;
  1042. } else if (method == Z_BZIP2ED) {
  1043. #ifdef HAVE_BZIP2
  1044. zi->ci.bstream.bzalloc = 0;
  1045. zi->ci.bstream.bzfree = 0;
  1046. zi->ci.bstream.opaque = (voidpf)0;
  1047. err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35);
  1048. if (err == BZ_OK)
  1049. zi->ci.stream_initialised = Z_BZIP2ED;
  1050. #endif
  1051. }
  1052. }
  1053. #ifndef NOCRYPT
  1054. zi->ci.crypt_header_size = 0;
  1055. if ((err == Z_OK) && ((zi->ci.flag & 1) != 0)) {
  1056. #ifdef HAVE_AES
  1057. if (zi->ci.method == AES_METHOD) {
  1058. unsigned char passverify[AES_PWVERIFYSIZE];
  1059. unsigned char saltvalue[AES_MAXSALTLENGTH];
  1060. uInt saltlength;
  1061. if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3))
  1062. return Z_ERRNO;
  1063. saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE);
  1064. prng_init(entropy_fun, zi->ci.aes_rng);
  1065. prng_rand(saltvalue, saltlength, zi->ci.aes_rng);
  1066. prng_end(zi->ci.aes_rng);
  1067. fcrypt_init(AES_ENCRYPTIONMODE, (unsigned char *)password, (unsigned int)strlen(password), saltvalue, passverify, &zi->ci.aes_ctx);
  1068. if (ZWRITE64(zi->z_filefunc, zi->filestream, saltvalue, saltlength) != saltlength)
  1069. err = ZIP_ERRNO;
  1070. if (ZWRITE64(zi->z_filefunc, zi->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)
  1071. err = ZIP_ERRNO;
  1072. zi->ci.crypt_header_size = saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE;
  1073. } else
  1074. #endif
  1075. {
  1076. unsigned char bufHead[RAND_HEAD_LEN];
  1077. unsigned int sizeHead;
  1078. zi->ci.pcrc_32_tab = (const unsigned long *)get_crc_table();
  1079. /*init_keys(password, zi->ci.keys, zi->ci.pcrc_32_tab);*/
  1080. sizeHead = crypthead(password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting);
  1081. zi->ci.crypt_header_size = sizeHead;
  1082. if (ZWRITE64(zi->z_filefunc, zi->filestream, bufHead, sizeHead) != sizeHead)
  1083. err = ZIP_ERRNO;
  1084. }
  1085. }
  1086. #endif
  1087. if (err == Z_OK)
  1088. zi->in_opened_file_inzip = 1;
  1089. return err;
  1090. }
  1091. extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1092. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1093. uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,
  1094. int memLevel, int strategy, const char *password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase)
  1095. {
  1096. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1097. extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
  1098. strategy, password, crcForCrypting, versionMadeBy, flagBase, 0);
  1099. }
  1100. extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1101. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1102. uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,
  1103. int memLevel, int strategy, const char *password, uLong crcForCrypting)
  1104. {
  1105. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1106. extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
  1107. strategy, password, crcForCrypting, VERSIONMADEBY, 0, 0);
  1108. }
  1109. extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1110. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1111. uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,
  1112. int memLevel, int strategy, const char *password, uLong crcForCrypting, int zip64)
  1113. {
  1114. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1115. extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy,
  1116. password, crcForCrypting, VERSIONMADEBY, 0, zip64);
  1117. }
  1118. extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1119. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1120. uInt size_extrafield_global, const char *comment, int method, int level, int raw)
  1121. {
  1122. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1123. extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
  1124. Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
  1125. }
  1126. extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1127. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1128. uInt size_extrafield_global, const char *comment, int method, int level, int raw, int zip64)
  1129. {
  1130. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1131. extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
  1132. Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
  1133. }
  1134. extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1135. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1136. uInt size_extrafield_global, const char *comment, int method, int level, int zip64)
  1137. {
  1138. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1139. extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
  1140. Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
  1141. }
  1142. extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
  1143. const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,
  1144. uInt size_extrafield_global, const char *comment, int method, int level)
  1145. {
  1146. return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
  1147. extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
  1148. Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
  1149. }
  1150. /* Flushes the write buffer to disk */
  1151. local int zip64FlushWriteBuffer OF((zip64_internal * zi));
  1152. local int zip64FlushWriteBuffer(zip64_internal *zi)
  1153. {
  1154. int err = ZIP_OK;
  1155. uInt written = 0;
  1156. uInt total_written = 0;
  1157. uInt write = 0;
  1158. uInt max_write = 0;
  1159. ZPOS64_T size_available = 0;
  1160. if ((zi->ci.flag & 1) != 0) {
  1161. #ifndef NOCRYPT
  1162. #ifdef HAVE_AES
  1163. if (zi->ci.method == AES_METHOD) {
  1164. fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx);
  1165. } else
  1166. #endif
  1167. {
  1168. uInt i;
  1169. int t;
  1170. for (i = 0; i < zi->ci.pos_in_buffered_data; i++)
  1171. zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t);
  1172. }
  1173. #endif
  1174. }
  1175. write = zi->ci.pos_in_buffered_data;
  1176. do {
  1177. max_write = write;
  1178. if (zi->disk_size > 0) {
  1179. err = zipGetDiskSizeAvailable((zipFile)zi, &size_available);
  1180. if (err != ZIP_OK)
  1181. return err;
  1182. if (size_available == 0) {
  1183. err = zipGoToNextDisk((zipFile)zi);
  1184. if (err != ZIP_OK)
  1185. return err;
  1186. }
  1187. if (size_available < (ZPOS64_T)max_write)
  1188. max_write = (uInt)size_available;
  1189. }
  1190. written = (unsigned int)ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write);
  1191. if (ZERROR64(zi->z_filefunc, zi->filestream)) {
  1192. err = ZIP_ERRNO;
  1193. break;
  1194. }
  1195. total_written += written;
  1196. write -= written;
  1197. } while (write > 0);
  1198. zi->ci.total_compressed += zi->ci.pos_in_buffered_data;
  1199. #ifdef HAVE_BZIP2
  1200. if (zi->ci.compression_method == Z_BZIP2ED) {
  1201. zi->ci.total_uncompressed += zi->ci.bstream.total_in_lo32;
  1202. zi->ci.bstream.total_in_lo32 = 0;
  1203. zi->ci.bstream.total_in_hi32 = 0;
  1204. } else
  1205. #endif
  1206. {
  1207. zi->ci.total_uncompressed += zi->ci.stream.total_in;
  1208. zi->ci.stream.total_in = 0;
  1209. }
  1210. zi->ci.pos_in_buffered_data = 0;
  1211. return err;
  1212. }
  1213. extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, unsigned int len)
  1214. {
  1215. zip64_internal *zi;
  1216. int err = ZIP_OK;
  1217. if (file == NULL)
  1218. return ZIP_PARAMERROR;
  1219. zi = (zip64_internal *)file;
  1220. if (zi->in_opened_file_inzip == 0)
  1221. return ZIP_PARAMERROR;
  1222. zi->ci.crc32 = crc32(zi->ci.crc32, buf, (uInt)len);
  1223. #ifdef HAVE_BZIP2
  1224. if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw)) {
  1225. zi->ci.bstream.next_in = (void *)buf;
  1226. zi->ci.bstream.avail_in = len;
  1227. err = BZ_RUN_OK;
  1228. while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0)) {
  1229. if (zi->ci.bstream.avail_out == 0) {
  1230. if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1231. err = ZIP_ERRNO;
  1232. zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1233. zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;
  1234. } else {
  1235. uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
  1236. uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
  1237. err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
  1238. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo);
  1239. }
  1240. }
  1241. if (err == BZ_RUN_OK)
  1242. err = ZIP_OK;
  1243. } else
  1244. #endif
  1245. {
  1246. zi->ci.stream.next_in = (Bytef *)buf;
  1247. zi->ci.stream.avail_in = len;
  1248. while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0)) {
  1249. if (zi->ci.stream.avail_out == 0) {
  1250. if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1251. err = ZIP_ERRNO;
  1252. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1253. zi->ci.stream.next_out = zi->ci.buffered_data;
  1254. }
  1255. if (err != ZIP_OK)
  1256. break;
  1257. if ((zi->ci.compression_method == Z_DEFLATED) && (!zi->ci.raw)) {
  1258. uLong total_out_before = zi->ci.stream.total_out;
  1259. err = deflate(&zi->ci.stream, Z_NO_FLUSH);
  1260. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before);
  1261. } else {
  1262. uInt copy_this, i;
  1263. if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
  1264. copy_this = zi->ci.stream.avail_in;
  1265. else
  1266. copy_this = zi->ci.stream.avail_out;
  1267. for (i = 0; i < copy_this; i++)
  1268. *(((char *)zi->ci.stream.next_out) + i) =
  1269. *(((const char *)zi->ci.stream.next_in) + i);
  1270. zi->ci.stream.avail_in -= copy_this;
  1271. zi->ci.stream.avail_out -= copy_this;
  1272. zi->ci.stream.next_in += copy_this;
  1273. zi->ci.stream.next_out += copy_this;
  1274. zi->ci.stream.total_in += copy_this;
  1275. zi->ci.stream.total_out += copy_this;
  1276. zi->ci.pos_in_buffered_data += copy_this;
  1277. }
  1278. }
  1279. }
  1280. return err;
  1281. }
  1282. extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32)
  1283. {
  1284. return zipCloseFileInZipRaw64(file, uncompressed_size, crc32);
  1285. }
  1286. extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
  1287. {
  1288. zip64_internal *zi;
  1289. ZPOS64_T compressed_size;
  1290. uLong invalidValue = 0xffffffff;
  1291. uLong i = 0;
  1292. short datasize = 0;
  1293. int err = ZIP_OK;
  1294. if (file == NULL)
  1295. return ZIP_PARAMERROR;
  1296. zi = (zip64_internal *)file;
  1297. if (zi->in_opened_file_inzip == 0)
  1298. return ZIP_PARAMERROR;
  1299. zi->ci.stream.avail_in = 0;
  1300. if (!zi->ci.raw) {
  1301. if (zi->ci.compression_method == Z_DEFLATED) {
  1302. while (err == ZIP_OK) {
  1303. uLong total_out_before;
  1304. if (zi->ci.stream.avail_out == 0) {
  1305. if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1306. err = ZIP_ERRNO;
  1307. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1308. zi->ci.stream.next_out = zi->ci.buffered_data;
  1309. }
  1310. total_out_before = zi->ci.stream.total_out;
  1311. err = deflate(&zi->ci.stream, Z_FINISH);
  1312. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before);
  1313. }
  1314. } else if (zi->ci.compression_method == Z_BZIP2ED) {
  1315. #ifdef HAVE_BZIP2
  1316. err = BZ_FINISH_OK;
  1317. while (err == BZ_FINISH_OK) {
  1318. uLong total_out_before;
  1319. if (zi->ci.bstream.avail_out == 0) {
  1320. if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1321. err = ZIP_ERRNO;
  1322. zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1323. zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;
  1324. }
  1325. total_out_before = zi->ci.bstream.total_out_lo32;
  1326. err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
  1327. if (err == BZ_STREAM_END)
  1328. err = Z_STREAM_END;
  1329. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - total_out_before);
  1330. }
  1331. if (err == BZ_FINISH_OK)
  1332. err = ZIP_OK;
  1333. #endif
  1334. }
  1335. }
  1336. if (err == Z_STREAM_END)
  1337. err = ZIP_OK; /* this is normal */
  1338. if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK)) {
  1339. if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1340. err = ZIP_ERRNO;
  1341. }
  1342. #ifdef HAVE_AES
  1343. if (zi->ci.method == AES_METHOD) {
  1344. unsigned char authcode[AES_AUTHCODESIZE];
  1345. fcrypt_end(authcode, &zi->ci.aes_ctx);
  1346. if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)
  1347. err = ZIP_ERRNO;
  1348. }
  1349. #endif
  1350. if (!zi->ci.raw) {
  1351. if (zi->ci.compression_method == Z_DEFLATED) {
  1352. int tmp_err = deflateEnd(&zi->ci.stream);
  1353. if (err == ZIP_OK)
  1354. err = tmp_err;
  1355. zi->ci.stream_initialised = 0;
  1356. }
  1357. #ifdef HAVE_BZIP2
  1358. else if (zi->ci.compression_method == Z_BZIP2ED) {
  1359. int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
  1360. if (err == ZIP_OK)
  1361. err = tmperr;
  1362. zi->ci.stream_initialised = 0;
  1363. }
  1364. #endif
  1365. crc32 = (uLong)zi->ci.crc32;
  1366. uncompressed_size = zi->ci.total_uncompressed;
  1367. }
  1368. compressed_size = zi->ci.total_compressed;
  1369. #ifndef NOCRYPT
  1370. compressed_size += zi->ci.crypt_header_size;
  1371. #endif
  1372. /* Update current item crc and sizes */
  1373. if (compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) {
  1374. zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)45, 2); /* version made by */
  1375. zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)45, 2); /* version needed */
  1376. }
  1377. zip64local_putValue_inmemory(zi->ci.central_header + 16, crc32, 4); /* crc */
  1378. if (compressed_size >= 0xffffffff)
  1379. zip64local_putValue_inmemory(zi->ci.central_header + 20, invalidValue, 4); /* compr size */
  1380. else
  1381. zip64local_putValue_inmemory(zi->ci.central_header + 20, compressed_size, 4); /* compr size */
  1382. if (zi->ci.stream.data_type == Z_ASCII)
  1383. zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)Z_ASCII, 2); /* internal file attrib */
  1384. if (uncompressed_size >= 0xffffffff)
  1385. zip64local_putValue_inmemory(zi->ci.central_header + 24, invalidValue, 4); /* uncompr size */
  1386. else
  1387. zip64local_putValue_inmemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */
  1388. /* Add ZIP64 extra info field for uncompressed size */
  1389. if (uncompressed_size >= 0xffffffff)
  1390. datasize += 8;
  1391. /* Add ZIP64 extra info field for compressed size */
  1392. if (compressed_size >= 0xffffffff)
  1393. datasize += 8;
  1394. /* Add ZIP64 extra info field for relative offset to local file header of current file */
  1395. if (zi->ci.pos_local_header >= 0xffffffff)
  1396. datasize += 8;
  1397. /* Add Extra Information Header for 'ZIP64 information' */
  1398. if (datasize > 0) {
  1399. char *p = zi->ci.central_header + zi->ci.size_centralheader;
  1400. if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)
  1401. return ZIP_BADZIPFILE;
  1402. zip64local_putValue_inmemory(p, 0x0001, 2);
  1403. p += 2;
  1404. zip64local_putValue_inmemory(p, datasize, 2);
  1405. p += 2;
  1406. if (uncompressed_size >= 0xffffffff) {
  1407. zip64local_putValue_inmemory(p, uncompressed_size, 8);
  1408. p += 8;
  1409. }
  1410. if (compressed_size >= 0xffffffff) {
  1411. zip64local_putValue_inmemory(p, compressed_size, 8);
  1412. p += 8;
  1413. }
  1414. if (zi->ci.pos_local_header >= 0xffffffff) {
  1415. zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
  1416. p += 8;
  1417. }
  1418. zi->ci.size_centralextrafree -= datasize + 4;
  1419. zi->ci.size_centralheader += datasize + 4;
  1420. zi->ci.size_centralextra += datasize + 4;
  1421. zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);
  1422. }
  1423. #ifdef HAVE_AES
  1424. /* Write the AES extended info */
  1425. if (zi->ci.method == AES_METHOD) {
  1426. char *p = zi->ci.central_header + zi->ci.size_centralheader;
  1427. datasize = 7;
  1428. if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)
  1429. return ZIP_BADZIPFILE;
  1430. zip64local_putValue_inmemory(p, 0x9901, 2);
  1431. p += 2;
  1432. zip64local_putValue_inmemory(p, datasize, 2);
  1433. p += 2;
  1434. zip64local_putValue_inmemory(p, AES_VERSION, 2);
  1435. p += 2;
  1436. zip64local_putValue_inmemory(p, 'A', 1);
  1437. p += 1;
  1438. zip64local_putValue_inmemory(p, 'E', 1);
  1439. p += 1;
  1440. zip64local_putValue_inmemory(p, AES_ENCRYPTIONMODE, 1);
  1441. p += 1;
  1442. zip64local_putValue_inmemory(p, zi->ci.compression_method, 2);
  1443. p += 2;
  1444. zi->ci.size_centralextrafree -= datasize + 4;
  1445. zi->ci.size_centralheader += datasize + 4;
  1446. zi->ci.size_centralextra += datasize + 4;
  1447. zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);
  1448. }
  1449. #endif
  1450. /* Restore comment to correct position */
  1451. for (i = 0; i < zi->ci.size_comment; i++)
  1452. zi->ci.central_header[zi->ci.size_centralheader + i] =
  1453. zi->ci.central_header[zi->ci.size_centralheader + zi->ci.size_centralextrafree + i];
  1454. zi->ci.size_centralheader += zi->ci.size_comment;
  1455. if (err == ZIP_OK)
  1456. err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
  1457. free(zi->ci.central_header);
  1458. if (err == ZIP_OK) {
  1459. /* Update the LocalFileHeader with the new values. */
  1460. ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
  1461. uLong cur_number_disk = zi->number_disk;
  1462. /* Local file header is stored on previous disk, switch to make edits */
  1463. if (zi->ci.number_disk != cur_number_disk)
  1464. err = zipGoToSpecificDisk(file, (int)zi->ci.number_disk, 1);
  1465. if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_local_header + 14, ZLIB_FILEFUNC_SEEK_SET) != 0)
  1466. err = ZIP_ERRNO;
  1467. if (err == ZIP_OK)
  1468. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, crc32, 4); /* crc 32, unknown */
  1469. if (uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) {
  1470. if (zi->ci.pos_zip64extrainfo > 0) {
  1471. /* Update the size in the ZIP64 extended field. */
  1472. if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_zip64extrainfo + 4, ZLIB_FILEFUNC_SEEK_SET) != 0)
  1473. err = ZIP_ERRNO;
  1474. if (err == ZIP_OK) /* compressed size, unknown */
  1475. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
  1476. if (err == ZIP_OK) /* uncompressed size, unknown */
  1477. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
  1478. } else
  1479. err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */
  1480. } else {
  1481. if (err == ZIP_OK) /* compressed size, unknown */
  1482. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 4);
  1483. if (err == ZIP_OK) /* uncompressed size, unknown */
  1484. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 4);
  1485. }
  1486. /* Now switch back again to the disk we were on before */
  1487. if (zi->ci.number_disk != cur_number_disk)
  1488. err = zipGoToSpecificDisk(file, (int)cur_number_disk, 1);
  1489. if (ZSEEK64(zi->z_filefunc, zi->filestream, cur_pos_inzip, ZLIB_FILEFUNC_SEEK_SET) != 0)
  1490. err = ZIP_ERRNO;
  1491. }
  1492. zi->number_entry++;
  1493. zi->in_opened_file_inzip = 0;
  1494. return err;
  1495. }
  1496. extern int ZEXPORT zipCloseFileInZip(zipFile file)
  1497. {
  1498. return zipCloseFileInZipRaw(file, 0, 0);
  1499. }
  1500. extern int ZEXPORT zipClose(zipFile file, const char *global_comment)
  1501. {
  1502. zip64_internal *zi;
  1503. int err = 0;
  1504. uLong size_centraldir = 0;
  1505. uInt size_global_comment = 0;
  1506. ZPOS64_T centraldir_pos_inzip;
  1507. ZPOS64_T pos = 0;
  1508. uLong write = 0;
  1509. if (file == NULL)
  1510. return ZIP_PARAMERROR;
  1511. zi = (zip64_internal *)file;
  1512. if (zi->in_opened_file_inzip == 1)
  1513. err = zipCloseFileInZip(file);
  1514. #ifndef NO_ADDFILEINEXISTINGZIP
  1515. if (global_comment == NULL)
  1516. global_comment = zi->globalcomment;
  1517. #endif
  1518. if (zi->filestream != zi->filestream_with_CD) {
  1519. if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)
  1520. if (err == ZIP_OK)
  1521. err = ZIP_ERRNO;
  1522. if (zi->disk_size > 0)
  1523. zi->number_disk_with_CD = zi->number_disk + 1;
  1524. zi->filestream = zi->filestream_with_CD;
  1525. }
  1526. centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
  1527. if (err == ZIP_OK) {
  1528. linkedlist_datablock_internal *ldi = zi->central_dir.first_block;
  1529. while (ldi != NULL) {
  1530. if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0)) {
  1531. write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block);
  1532. if (write != ldi->filled_in_this_block)
  1533. err = ZIP_ERRNO;
  1534. }
  1535. size_centraldir += ldi->filled_in_this_block;
  1536. ldi = ldi->next_datablock;
  1537. }
  1538. }
  1539. free_linkedlist(&(zi->central_dir));
  1540. pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1541. /* Write the ZIP64 central directory header */
  1542. if (pos >= 0xffffffff || zi->number_entry > 0xffff) {
  1543. ZPOS64_T zip64eocd_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
  1544. uLong zip64datasize = 44;
  1545. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDHEADERMAGIC, 4);
  1546. /* size of this 'zip64 end of central directory' */
  1547. if (err == ZIP_OK)
  1548. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)zip64datasize, 8);
  1549. /* version made by */
  1550. if (err == ZIP_OK)
  1551. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2);
  1552. /* version needed */
  1553. if (err == ZIP_OK)
  1554. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2);
  1555. /* number of this disk */
  1556. if (err == ZIP_OK)
  1557. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);
  1558. /* number of the disk with the start of the central directory */
  1559. if (err == ZIP_OK)
  1560. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);
  1561. /* total number of entries in the central dir on this disk */
  1562. if (err == ZIP_OK)
  1563. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  1564. /* total number of entries in the central dir */
  1565. if (err == ZIP_OK)
  1566. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  1567. /* size of the central directory */
  1568. if (err == ZIP_OK)
  1569. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)size_centraldir, 8);
  1570. if (err == ZIP_OK) {
  1571. /* offset of start of central directory with respect to the starting disk number */
  1572. ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1573. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)pos, 8);
  1574. }
  1575. if (err == ZIP_OK)
  1576. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDLOCHEADERMAGIC, 4);
  1577. /* number of the disk with the start of the central directory */
  1578. if (err == ZIP_OK)
  1579. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);
  1580. /*relative offset to the Zip64EndOfCentralDirectory */
  1581. if (err == ZIP_OK) {
  1582. ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
  1583. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, pos, 8);
  1584. }
  1585. /* number of the disk with the start of the central directory */
  1586. if (err == ZIP_OK)
  1587. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD + 1, 4);
  1588. }
  1589. /* Write the central directory header */
  1590. /* signature */
  1591. if (err == ZIP_OK)
  1592. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ENDHEADERMAGIC, 4);
  1593. /* number of this disk */
  1594. if (err == ZIP_OK)
  1595. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2);
  1596. /* number of the disk with the start of the central directory */
  1597. if (err == ZIP_OK)
  1598. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2);
  1599. /* total number of entries in the central dir on this disk */
  1600. if (err == ZIP_OK) {
  1601. if (zi->number_entry >= 0xffff)
  1602. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); /* use value in ZIP64 record */
  1603. else
  1604. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2);
  1605. }
  1606. /* total number of entries in the central dir */
  1607. if (err == ZIP_OK) {
  1608. if (zi->number_entry >= 0xffff)
  1609. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); /* use value in ZIP64 record */
  1610. else
  1611. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2);
  1612. }
  1613. /* size of the central directory */
  1614. if (err == ZIP_OK)
  1615. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_centraldir, 4);
  1616. /* offset of start of central directory with respect to the starting disk number */
  1617. if (err == ZIP_OK) {
  1618. ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1619. if (pos >= 0xffffffff)
  1620. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffffffff, 4);
  1621. else
  1622. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)pos, 4);
  1623. }
  1624. /* Write global comment */
  1625. if (global_comment != NULL)
  1626. size_global_comment = (uInt)strlen(global_comment);
  1627. if (err == ZIP_OK)
  1628. err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_global_comment, 2);
  1629. if (err == ZIP_OK && size_global_comment > 0) {
  1630. if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment)
  1631. err = ZIP_ERRNO;
  1632. }
  1633. if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK))
  1634. err = ZIP_ERRNO;
  1635. #ifndef NO_ADDFILEINEXISTINGZIP
  1636. TRYFREE(zi->globalcomment);
  1637. #endif
  1638. TRYFREE(zi);
  1639. return err;
  1640. }