cordova-plugin-mserviceinterface-2.0 1.0.26 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -28
- package/plugin.xml +153 -153
- package/src/android/CallbackProgressDialog.java +53 -53
- package/src/android/FileProvider.java +7 -7
- package/src/android/backgroundNotification.java +120 -120
- package/src/android/doubleogradle.gradle +5 -5
- package/src/android/mInterface.java +2123 -2087
- package/src/android/mInterfaceReceiver.java +59 -59
- package/src/android/mInterfaceService.java +749 -749
- package/src/android/mInterfaceUtil.java +1686 -1686
- package/src/android/res/xml/network_security_config.xml +8 -8
- package/src/android/res/xml/opener_paths.xml +16 -16
- package/src/ios/InternetConnection.h +64 -64
- package/src/ios/InternetConnection.m +242 -242
- package/src/ios/SSZipArchive.h +146 -146
- package/src/ios/SSZipArchive.m +1180 -1180
- package/src/ios/SSZipCommon.h +66 -66
- package/src/ios/UICKeyChainStore.h +64 -64
- package/src/ios/UICKeyChainStore.m +434 -434
- package/src/ios/XMLConverter.h +61 -61
- package/src/ios/XMLConverter.m +243 -243
- package/src/ios/ZipArchive.h +19 -19
- package/src/ios/aes/aes.h +270 -270
- package/src/ios/aes/aes_ni.c +687 -687
- package/src/ios/aes/aes_ni.h +59 -59
- package/src/ios/aes/aescrypt.c +301 -301
- package/src/ios/aes/aeskey.c +554 -554
- package/src/ios/aes/aesopt.h +776 -776
- package/src/ios/aes/aestab.c +418 -418
- package/src/ios/aes/aestab.h +173 -173
- package/src/ios/aes/brg_endian.h +127 -127
- package/src/ios/aes/brg_types.h +191 -191
- package/src/ios/aes/fileenc.c +145 -145
- package/src/ios/aes/fileenc.h +121 -121
- package/src/ios/aes/hmac.c +209 -209
- package/src/ios/aes/hmac.h +119 -119
- package/src/ios/aes/prng.c +155 -155
- package/src/ios/aes/prng.h +82 -82
- package/src/ios/aes/pwd2key.c +181 -181
- package/src/ios/aes/pwd2key.h +45 -45
- package/src/ios/aes/sha1.c +283 -283
- package/src/ios/aes/sha1.h +72 -72
- package/src/ios/minizip/crypt.c +146 -146
- package/src/ios/minizip/crypt.h +66 -66
- package/src/ios/minizip/ioapi.c +353 -353
- package/src/ios/minizip/ioapi.h +154 -154
- package/src/ios/minizip/ioapi_buf.c +452 -452
- package/src/ios/minizip/ioapi_buf.h +52 -52
- package/src/ios/minizip/ioapi_mem.c +167 -167
- package/src/ios/minizip/ioapi_mem.h +52 -52
- package/src/ios/minizip/minishared.c +292 -292
- package/src/ios/minizip/minishared.h +50 -50
- package/src/ios/minizip/unzip.c +2007 -2007
- package/src/ios/minizip/unzip.h +254 -254
- package/src/ios/minizip/zip.c +2007 -2007
- package/src/ios/minizip/zip.h +215 -215
- package/www/mInterface.js +3 -3
package/src/ios/minizip/zip.c
CHANGED
|
@@ -1,2007 +1,2007 @@
|
|
|
1
|
-
/* zip.c -- IO on .zip files using zlib
|
|
2
|
-
Version 1.2.0, September 16th, 2017
|
|
3
|
-
part of the MiniZip project
|
|
4
|
-
|
|
5
|
-
Copyright (C) 2010-2017 Nathan Moinvaziri
|
|
6
|
-
Modifications for AES, PKWARE disk spanning
|
|
7
|
-
https://github.com/nmoinvaz/minizip
|
|
8
|
-
Copyright (C) 2009-2010 Mathias Svensson
|
|
9
|
-
Modifications for Zip64 support
|
|
10
|
-
http://result42.com
|
|
11
|
-
Copyright (C) 1998-2010 Gilles Vollant
|
|
12
|
-
http://www.winimage.com/zLibDll/minizip.html
|
|
13
|
-
|
|
14
|
-
This program is distributed under the terms of the same license as zlib.
|
|
15
|
-
See the accompanying LICENSE file for the full text of the license.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
#include <stdio.h>
|
|
19
|
-
#include <stdlib.h>
|
|
20
|
-
#include <stdint.h>
|
|
21
|
-
#include <string.h>
|
|
22
|
-
#include <errno.h>
|
|
23
|
-
#include <assert.h>
|
|
24
|
-
|
|
25
|
-
#include "zlib.h"
|
|
26
|
-
#include "zip.h"
|
|
27
|
-
|
|
28
|
-
#ifdef HAVE_AES
|
|
29
|
-
# define AES_METHOD (99)
|
|
30
|
-
# define AES_PWVERIFYSIZE (2)
|
|
31
|
-
# define AES_AUTHCODESIZE (10)
|
|
32
|
-
# define AES_MAXSALTLENGTH (16)
|
|
33
|
-
# define AES_VERSION (0x0001)
|
|
34
|
-
# define AES_ENCRYPTIONMODE (0x03)
|
|
35
|
-
|
|
36
|
-
# include "aes.h"
|
|
37
|
-
# include "fileenc.h"
|
|
38
|
-
# include "prng.h"
|
|
39
|
-
#endif
|
|
40
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
41
|
-
# include <compression.h>
|
|
42
|
-
#endif
|
|
43
|
-
|
|
44
|
-
#ifndef NOCRYPT
|
|
45
|
-
# include "crypt.h"
|
|
46
|
-
#endif
|
|
47
|
-
|
|
48
|
-
#define SIZEDATA_INDATABLOCK (4096-(4*4))
|
|
49
|
-
|
|
50
|
-
#define DISKHEADERMAGIC (0x08074b50)
|
|
51
|
-
#define LOCALHEADERMAGIC (0x04034b50)
|
|
52
|
-
#define CENTRALHEADERMAGIC (0x02014b50)
|
|
53
|
-
#define ENDHEADERMAGIC (0x06054b50)
|
|
54
|
-
#define ZIP64ENDHEADERMAGIC (0x06064b50)
|
|
55
|
-
#define ZIP64ENDLOCHEADERMAGIC (0x07064b50)
|
|
56
|
-
#define DATADESCRIPTORMAGIC (0x08074b50)
|
|
57
|
-
|
|
58
|
-
#define FLAG_LOCALHEADER_OFFSET (0x06)
|
|
59
|
-
#define CRC_LOCALHEADER_OFFSET (0x0e)
|
|
60
|
-
|
|
61
|
-
#define SIZECENTRALHEADER (0x2e) /* 46 */
|
|
62
|
-
#define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */
|
|
63
|
-
#define SIZECENTRALDIRITEM (0x2e)
|
|
64
|
-
#define SIZEZIPLOCALHEADER (0x1e)
|
|
65
|
-
|
|
66
|
-
#ifndef BUFREADCOMMENT
|
|
67
|
-
# define BUFREADCOMMENT (0x400)
|
|
68
|
-
#endif
|
|
69
|
-
#ifndef VERSIONMADEBY
|
|
70
|
-
# define VERSIONMADEBY (0x0) /* platform dependent */
|
|
71
|
-
#endif
|
|
72
|
-
|
|
73
|
-
#ifndef Z_BUFSIZE
|
|
74
|
-
# define Z_BUFSIZE (UINT16_MAX)
|
|
75
|
-
#endif
|
|
76
|
-
|
|
77
|
-
#ifndef ALLOC
|
|
78
|
-
# define ALLOC(size) (malloc(size))
|
|
79
|
-
#endif
|
|
80
|
-
#ifndef TRYFREE
|
|
81
|
-
# define TRYFREE(p) {if (p) free(p);}
|
|
82
|
-
#endif
|
|
83
|
-
|
|
84
|
-
/* NOT sure that this work on ALL platform */
|
|
85
|
-
#define MAKEULONG64(a, b) ((uint64_t)(((unsigned long)(a)) | ((uint64_t)((unsigned long)(b))) << 32))
|
|
86
|
-
|
|
87
|
-
#ifndef DEF_MEM_LEVEL
|
|
88
|
-
# if MAX_MEM_LEVEL >= 8
|
|
89
|
-
# define DEF_MEM_LEVEL 8
|
|
90
|
-
# else
|
|
91
|
-
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
|
92
|
-
# endif
|
|
93
|
-
#endif
|
|
94
|
-
|
|
95
|
-
const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
|
96
|
-
|
|
97
|
-
typedef struct linkedlist_datablock_internal_s
|
|
98
|
-
{
|
|
99
|
-
struct linkedlist_datablock_internal_s *next_datablock;
|
|
100
|
-
uint32_t avail_in_this_block;
|
|
101
|
-
uint32_t filled_in_this_block;
|
|
102
|
-
uint32_t unused; /* for future use and alignment */
|
|
103
|
-
uint8_t data[SIZEDATA_INDATABLOCK];
|
|
104
|
-
} linkedlist_datablock_internal;
|
|
105
|
-
|
|
106
|
-
typedef struct linkedlist_data_s
|
|
107
|
-
{
|
|
108
|
-
linkedlist_datablock_internal *first_block;
|
|
109
|
-
linkedlist_datablock_internal *last_block;
|
|
110
|
-
} linkedlist_data;
|
|
111
|
-
|
|
112
|
-
typedef struct
|
|
113
|
-
{
|
|
114
|
-
z_stream stream; /* zLib stream structure for inflate */
|
|
115
|
-
#ifdef HAVE_BZIP2
|
|
116
|
-
bz_stream bstream; /* bzLib stream structure for bziped */
|
|
117
|
-
#endif
|
|
118
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
119
|
-
compression_stream astream; /* libcompression stream structure */
|
|
120
|
-
#endif
|
|
121
|
-
#ifdef HAVE_AES
|
|
122
|
-
fcrypt_ctx aes_ctx;
|
|
123
|
-
prng_ctx aes_rng[1];
|
|
124
|
-
#endif
|
|
125
|
-
int stream_initialised; /* 1 is stream is initialized */
|
|
126
|
-
uint32_t pos_in_buffered_data; /* last written byte in buffered_data */
|
|
127
|
-
|
|
128
|
-
uint64_t pos_local_header; /* offset of the local header of the file currently writing */
|
|
129
|
-
char *central_header; /* central header data for the current file */
|
|
130
|
-
uint16_t size_centralextra;
|
|
131
|
-
uint16_t size_centralheader; /* size of the central header for cur file */
|
|
132
|
-
uint16_t size_centralextrafree; /* Extra bytes allocated to the central header but that are not used */
|
|
133
|
-
uint16_t size_comment;
|
|
134
|
-
uint16_t flag; /* flag of the file currently writing */
|
|
135
|
-
|
|
136
|
-
uint16_t method; /* compression method written to file.*/
|
|
137
|
-
uint16_t compression_method; /* compression method to use */
|
|
138
|
-
int raw; /* 1 for directly writing raw data */
|
|
139
|
-
uint8_t buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/
|
|
140
|
-
uint32_t dos_date;
|
|
141
|
-
uint32_t crc32;
|
|
142
|
-
int zip64; /* add ZIP64 extended information in the extra field */
|
|
143
|
-
uint32_t number_disk; /* number of current disk used for spanning ZIP */
|
|
144
|
-
uint64_t total_compressed;
|
|
145
|
-
uint64_t total_uncompressed;
|
|
146
|
-
#ifndef NOCRYPT
|
|
147
|
-
uint32_t keys[3]; /* keys defining the pseudo-random sequence */
|
|
148
|
-
const z_crc_t *pcrc_32_tab;
|
|
149
|
-
#endif
|
|
150
|
-
} curfile64_info;
|
|
151
|
-
|
|
152
|
-
typedef struct
|
|
153
|
-
{
|
|
154
|
-
zlib_filefunc64_32_def z_filefunc;
|
|
155
|
-
voidpf filestream; /* io structure of the zipfile */
|
|
156
|
-
voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */
|
|
157
|
-
linkedlist_data central_dir; /* datablock with central dir in construction*/
|
|
158
|
-
int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
|
|
159
|
-
int append; /* append mode */
|
|
160
|
-
curfile64_info ci; /* info on the file currently writing */
|
|
161
|
-
|
|
162
|
-
uint64_t add_position_when_writting_offset;
|
|
163
|
-
uint64_t number_entry;
|
|
164
|
-
uint64_t disk_size; /* size of each disk */
|
|
165
|
-
uint32_t number_disk; /* number of the current disk, used for spanning ZIP */
|
|
166
|
-
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
|
|
167
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
168
|
-
char *globalcomment;
|
|
169
|
-
#endif
|
|
170
|
-
} zip64_internal;
|
|
171
|
-
|
|
172
|
-
/* Allocate a new data block */
|
|
173
|
-
static linkedlist_datablock_internal *allocate_new_datablock(void)
|
|
174
|
-
{
|
|
175
|
-
linkedlist_datablock_internal *ldi = NULL;
|
|
176
|
-
|
|
177
|
-
ldi = (linkedlist_datablock_internal*)ALLOC(sizeof(linkedlist_datablock_internal));
|
|
178
|
-
|
|
179
|
-
if (ldi != NULL)
|
|
180
|
-
{
|
|
181
|
-
ldi->next_datablock = NULL;
|
|
182
|
-
ldi->filled_in_this_block = 0;
|
|
183
|
-
ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;
|
|
184
|
-
}
|
|
185
|
-
return ldi;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/* Free data block in linked list */
|
|
189
|
-
static void free_datablock(linkedlist_datablock_internal *ldi)
|
|
190
|
-
{
|
|
191
|
-
while (ldi != NULL)
|
|
192
|
-
{
|
|
193
|
-
linkedlist_datablock_internal *ldinext = ldi->next_datablock;
|
|
194
|
-
TRYFREE(ldi);
|
|
195
|
-
ldi = ldinext;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/* Initialize linked list */
|
|
200
|
-
static void init_linkedlist(linkedlist_data *ll)
|
|
201
|
-
{
|
|
202
|
-
ll->first_block = ll->last_block = NULL;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/* Free entire linked list and all data blocks */
|
|
206
|
-
static void free_linkedlist(linkedlist_data *ll)
|
|
207
|
-
{
|
|
208
|
-
free_datablock(ll->first_block);
|
|
209
|
-
ll->first_block = ll->last_block = NULL;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/* Add data to linked list data block */
|
|
213
|
-
static int add_data_in_datablock(linkedlist_data *ll, const void *buf, uint32_t len)
|
|
214
|
-
{
|
|
215
|
-
linkedlist_datablock_internal *ldi = NULL;
|
|
216
|
-
const unsigned char *from_copy = NULL;
|
|
217
|
-
|
|
218
|
-
if (ll == NULL)
|
|
219
|
-
return ZIP_INTERNALERROR;
|
|
220
|
-
|
|
221
|
-
if (ll->last_block == NULL)
|
|
222
|
-
{
|
|
223
|
-
ll->first_block = ll->last_block = allocate_new_datablock();
|
|
224
|
-
if (ll->first_block == NULL)
|
|
225
|
-
return ZIP_INTERNALERROR;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
ldi = ll->last_block;
|
|
229
|
-
from_copy = (unsigned char*)buf;
|
|
230
|
-
|
|
231
|
-
while (len > 0)
|
|
232
|
-
{
|
|
233
|
-
uint32_t copy_this = 0;
|
|
234
|
-
uint32_t i = 0;
|
|
235
|
-
unsigned char *to_copy = NULL;
|
|
236
|
-
|
|
237
|
-
if (ldi->avail_in_this_block == 0)
|
|
238
|
-
{
|
|
239
|
-
ldi->next_datablock = allocate_new_datablock();
|
|
240
|
-
if (ldi->next_datablock == NULL)
|
|
241
|
-
return ZIP_INTERNALERROR;
|
|
242
|
-
ldi = ldi->next_datablock ;
|
|
243
|
-
ll->last_block = ldi;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (ldi->avail_in_this_block < len)
|
|
247
|
-
copy_this = ldi->avail_in_this_block;
|
|
248
|
-
else
|
|
249
|
-
copy_this = len;
|
|
250
|
-
|
|
251
|
-
to_copy = &(ldi->data[ldi->filled_in_this_block]);
|
|
252
|
-
|
|
253
|
-
for (i = 0; i < copy_this; i++)
|
|
254
|
-
*(to_copy+i) = *(from_copy+i);
|
|
255
|
-
|
|
256
|
-
ldi->filled_in_this_block += copy_this;
|
|
257
|
-
ldi->avail_in_this_block -= copy_this;
|
|
258
|
-
from_copy += copy_this;
|
|
259
|
-
len -= copy_this;
|
|
260
|
-
}
|
|
261
|
-
return ZIP_OK;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/* Inputs a long in LSB order to the given file: nbByte == 1, 2, 4 or 8 (byte, short or long, uint64_t) */
|
|
265
|
-
static int zipWriteValue(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
|
266
|
-
uint64_t x, uint32_t len)
|
|
267
|
-
{
|
|
268
|
-
unsigned char buf[8];
|
|
269
|
-
uint32_t n = 0;
|
|
270
|
-
|
|
271
|
-
for (n = 0; n < len; n++)
|
|
272
|
-
{
|
|
273
|
-
buf[n] = (unsigned char)(x & 0xff);
|
|
274
|
-
x >>= 8;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
if (x != 0)
|
|
278
|
-
{
|
|
279
|
-
/* Data overflow - hack for ZIP64 (X Roche) */
|
|
280
|
-
for (n = 0; n < len; n++)
|
|
281
|
-
{
|
|
282
|
-
buf[n] = 0xff;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, len) != len)
|
|
287
|
-
return ZIP_ERRNO;
|
|
288
|
-
|
|
289
|
-
return ZIP_OK;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
static void zipWriteValueToMemory(void* dest, uint64_t x, uint32_t len)
|
|
293
|
-
{
|
|
294
|
-
unsigned char *buf = (unsigned char*)dest;
|
|
295
|
-
uint32_t n = 0;
|
|
296
|
-
|
|
297
|
-
for (n = 0; n < len; n++)
|
|
298
|
-
{
|
|
299
|
-
buf[n] = (unsigned char)(x & 0xff);
|
|
300
|
-
x >>= 8;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (x != 0)
|
|
304
|
-
{
|
|
305
|
-
/* data overflow - hack for ZIP64 */
|
|
306
|
-
for (n = 0; n < len; n++)
|
|
307
|
-
{
|
|
308
|
-
buf[n] = 0xff;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
static void zipWriteValueToMemoryAndMove(unsigned char **dest_ptr, uint64_t x, uint32_t len)
|
|
314
|
-
{
|
|
315
|
-
zipWriteValueToMemory(*dest_ptr, x, len);
|
|
316
|
-
*dest_ptr += len;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
static int zipReadUInt8(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint8_t *value)
|
|
320
|
-
{
|
|
321
|
-
uint8_t c = 0;
|
|
322
|
-
if (ZREAD64(*pzlib_filefunc_def, filestream, &c, 1) == 1)
|
|
323
|
-
{
|
|
324
|
-
*value = (uint8_t)c;
|
|
325
|
-
return ZIP_OK;
|
|
326
|
-
}
|
|
327
|
-
if (ZERROR64(*pzlib_filefunc_def, filestream))
|
|
328
|
-
return ZIP_ERRNO;
|
|
329
|
-
return ZIP_EOF;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
static int zipReadUInt16(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint16_t *value)
|
|
333
|
-
{
|
|
334
|
-
uint16_t x = 0;
|
|
335
|
-
uint8_t c = 0;
|
|
336
|
-
int err = ZIP_OK;
|
|
337
|
-
|
|
338
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
339
|
-
x = (uint16_t)c;
|
|
340
|
-
if (err == ZIP_OK)
|
|
341
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
342
|
-
x += ((uint16_t)c) << 8;
|
|
343
|
-
|
|
344
|
-
if (err == ZIP_OK)
|
|
345
|
-
*value = x;
|
|
346
|
-
else
|
|
347
|
-
*value = 0;
|
|
348
|
-
return err;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
static int zipReadUInt32(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint32_t *value)
|
|
352
|
-
{
|
|
353
|
-
uint32_t x = 0;
|
|
354
|
-
uint8_t c = 0;
|
|
355
|
-
int err = ZIP_OK;
|
|
356
|
-
|
|
357
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
358
|
-
x = (uint32_t)c;
|
|
359
|
-
if (err == ZIP_OK)
|
|
360
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
361
|
-
x += ((uint32_t)c) << 8;
|
|
362
|
-
if (err == ZIP_OK)
|
|
363
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
364
|
-
x += ((uint32_t)c) << 16;
|
|
365
|
-
if (err == ZIP_OK)
|
|
366
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
367
|
-
x += ((uint32_t)c) << 24;
|
|
368
|
-
|
|
369
|
-
if (err == ZIP_OK)
|
|
370
|
-
*value = x;
|
|
371
|
-
else
|
|
372
|
-
*value = 0;
|
|
373
|
-
return err;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
static int zipReadUInt64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint64_t *value)
|
|
377
|
-
{
|
|
378
|
-
uint64_t x = 0;
|
|
379
|
-
uint8_t c = 0;
|
|
380
|
-
int err = ZIP_OK;
|
|
381
|
-
|
|
382
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
383
|
-
x = (uint64_t)c;
|
|
384
|
-
if (err == ZIP_OK)
|
|
385
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
386
|
-
x += ((uint64_t)c) << 8;
|
|
387
|
-
if (err == ZIP_OK)
|
|
388
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
389
|
-
x += ((uint64_t)c) << 16;
|
|
390
|
-
if (err == ZIP_OK)
|
|
391
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
392
|
-
x += ((uint64_t)c) << 24;
|
|
393
|
-
if (err == ZIP_OK)
|
|
394
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
395
|
-
x += ((uint64_t)c) << 32;
|
|
396
|
-
if (err == ZIP_OK)
|
|
397
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
398
|
-
x += ((uint64_t)c) << 40;
|
|
399
|
-
if (err == ZIP_OK)
|
|
400
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
401
|
-
x += ((uint64_t)c) << 48;
|
|
402
|
-
if (err == ZIP_OK)
|
|
403
|
-
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
404
|
-
x += ((uint64_t)c) << 56;
|
|
405
|
-
|
|
406
|
-
if (err == ZIP_OK)
|
|
407
|
-
*value = x;
|
|
408
|
-
else
|
|
409
|
-
*value = 0;
|
|
410
|
-
|
|
411
|
-
return err;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/* Gets the amount of bytes left to write to the current disk for spanning archives */
|
|
415
|
-
static void zipGetDiskSizeAvailable(zipFile file, uint64_t *size_available)
|
|
416
|
-
{
|
|
417
|
-
zip64_internal *zi = NULL;
|
|
418
|
-
uint64_t current_disk_size = 0;
|
|
419
|
-
|
|
420
|
-
zi = (zip64_internal*)file;
|
|
421
|
-
ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
|
|
422
|
-
current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
423
|
-
*size_available = zi->disk_size - current_disk_size;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/* Goes to a specific disk number for spanning archives */
|
|
427
|
-
static int zipGoToSpecificDisk(zipFile file, uint32_t number_disk, int open_existing)
|
|
428
|
-
{
|
|
429
|
-
zip64_internal *zi = NULL;
|
|
430
|
-
int err = ZIP_OK;
|
|
431
|
-
|
|
432
|
-
zi = (zip64_internal*)file;
|
|
433
|
-
if (zi->disk_size == 0)
|
|
434
|
-
return err;
|
|
435
|
-
|
|
436
|
-
if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))
|
|
437
|
-
ZCLOSE64(zi->z_filefunc, zi->filestream);
|
|
438
|
-
|
|
439
|
-
zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ?
|
|
440
|
-
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :
|
|
441
|
-
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));
|
|
442
|
-
|
|
443
|
-
if (zi->filestream == NULL)
|
|
444
|
-
err = ZIP_ERRNO;
|
|
445
|
-
|
|
446
|
-
return err;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/* Goes to the first disk in a spanned archive */
|
|
450
|
-
static int zipGoToFirstDisk(zipFile file)
|
|
451
|
-
{
|
|
452
|
-
zip64_internal *zi = NULL;
|
|
453
|
-
uint32_t number_disk_next = 0;
|
|
454
|
-
int err = ZIP_OK;
|
|
455
|
-
|
|
456
|
-
zi = (zip64_internal*)file;
|
|
457
|
-
|
|
458
|
-
if (zi->disk_size == 0)
|
|
459
|
-
return err;
|
|
460
|
-
number_disk_next = 0;
|
|
461
|
-
if (zi->number_disk_with_CD > 0)
|
|
462
|
-
number_disk_next = zi->number_disk_with_CD - 1;
|
|
463
|
-
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
|
464
|
-
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
|
465
|
-
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
|
466
|
-
if (err == ZIP_OK)
|
|
467
|
-
zi->number_disk = number_disk_next;
|
|
468
|
-
ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
|
|
469
|
-
return err;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/* Goes to the next disk in a spanned archive */
|
|
473
|
-
static int zipGoToNextDisk(zipFile file)
|
|
474
|
-
{
|
|
475
|
-
zip64_internal *zi = NULL;
|
|
476
|
-
uint64_t size_available_in_disk = 0;
|
|
477
|
-
uint32_t number_disk_next = 0;
|
|
478
|
-
int err = ZIP_OK;
|
|
479
|
-
|
|
480
|
-
zi = (zip64_internal*)file;
|
|
481
|
-
if (zi->disk_size == 0)
|
|
482
|
-
return err;
|
|
483
|
-
|
|
484
|
-
number_disk_next = zi->number_disk + 1;
|
|
485
|
-
|
|
486
|
-
do
|
|
487
|
-
{
|
|
488
|
-
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
|
489
|
-
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
|
490
|
-
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
|
491
|
-
if (err != ZIP_OK)
|
|
492
|
-
break;
|
|
493
|
-
zipGetDiskSizeAvailable(file, &size_available_in_disk);
|
|
494
|
-
zi->number_disk = number_disk_next;
|
|
495
|
-
zi->number_disk_with_CD = zi->number_disk + 1;
|
|
496
|
-
|
|
497
|
-
number_disk_next += 1;
|
|
498
|
-
}
|
|
499
|
-
while (size_available_in_disk <= 0);
|
|
500
|
-
|
|
501
|
-
return err;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/* Locate the Central directory of a zipfile (at the end, just before the global comment) */
|
|
505
|
-
static uint64_t zipSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
|
|
506
|
-
{
|
|
507
|
-
unsigned char *buf = NULL;
|
|
508
|
-
uint64_t file_size = 0;
|
|
509
|
-
uint64_t back_read = 4;
|
|
510
|
-
uint64_t max_back = UINT16_MAX; /* maximum size of global comment */
|
|
511
|
-
uint64_t pos_found = 0;
|
|
512
|
-
uint32_t read_size = 0;
|
|
513
|
-
uint64_t read_pos = 0;
|
|
514
|
-
uint32_t i = 0;
|
|
515
|
-
|
|
516
|
-
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
|
|
517
|
-
if (buf == NULL)
|
|
518
|
-
return 0;
|
|
519
|
-
|
|
520
|
-
if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
|
|
521
|
-
{
|
|
522
|
-
TRYFREE(buf);
|
|
523
|
-
return 0;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
file_size = ZTELL64(*pzlib_filefunc_def, filestream);
|
|
527
|
-
|
|
528
|
-
if (max_back > file_size)
|
|
529
|
-
max_back = file_size;
|
|
530
|
-
|
|
531
|
-
while (back_read < max_back)
|
|
532
|
-
{
|
|
533
|
-
if (back_read + BUFREADCOMMENT > max_back)
|
|
534
|
-
back_read = max_back;
|
|
535
|
-
else
|
|
536
|
-
back_read += BUFREADCOMMENT;
|
|
537
|
-
|
|
538
|
-
read_pos = file_size-back_read;
|
|
539
|
-
read_size = ((BUFREADCOMMENT+4) < (file_size - read_pos)) ?
|
|
540
|
-
(BUFREADCOMMENT+4) : (uint32_t)(file_size - read_pos);
|
|
541
|
-
|
|
542
|
-
if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
543
|
-
break;
|
|
544
|
-
if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)
|
|
545
|
-
break;
|
|
546
|
-
|
|
547
|
-
for (i = read_size-3; (i--) > 0;)
|
|
548
|
-
if ((*(buf+i)) == (ENDHEADERMAGIC & 0xff) &&
|
|
549
|
-
(*(buf+i+1)) == (ENDHEADERMAGIC >> 8 & 0xff) &&
|
|
550
|
-
(*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff) &&
|
|
551
|
-
(*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff))
|
|
552
|
-
{
|
|
553
|
-
pos_found = read_pos+i;
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
if (pos_found != 0)
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
TRYFREE(buf);
|
|
561
|
-
return pos_found;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
|
|
565
|
-
static uint64_t zipSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
|
566
|
-
const uint64_t endcentraloffset)
|
|
567
|
-
{
|
|
568
|
-
uint64_t offset = 0;
|
|
569
|
-
uint32_t value32 = 0;
|
|
570
|
-
|
|
571
|
-
/* Zip64 end of central directory locator */
|
|
572
|
-
if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
573
|
-
return 0;
|
|
574
|
-
|
|
575
|
-
/* Read locator signature */
|
|
576
|
-
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
577
|
-
return 0;
|
|
578
|
-
if (value32 != ZIP64ENDLOCHEADERMAGIC)
|
|
579
|
-
return 0;
|
|
580
|
-
/* Number of the disk with the start of the zip64 end of central directory */
|
|
581
|
-
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
582
|
-
return 0;
|
|
583
|
-
/* Relative offset of the zip64 end of central directory record */
|
|
584
|
-
if (zipReadUInt64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK)
|
|
585
|
-
return 0;
|
|
586
|
-
/* Total number of disks */
|
|
587
|
-
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
588
|
-
return 0;
|
|
589
|
-
/* Goto end of central directory record */
|
|
590
|
-
if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
591
|
-
return 0;
|
|
592
|
-
/* The signature */
|
|
593
|
-
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
594
|
-
return 0;
|
|
595
|
-
if (value32 != ZIP64ENDHEADERMAGIC)
|
|
596
|
-
return 0;
|
|
597
|
-
|
|
598
|
-
return offset;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
extern zipFile ZEXPORT zipOpen4(const void *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
602
|
-
zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
|
|
603
|
-
{
|
|
604
|
-
zip64_internal ziinit = { 0 };
|
|
605
|
-
zip64_internal *zi = NULL;
|
|
606
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
607
|
-
uint64_t byte_before_the_zipfile = 0; /* byte before the zipfile, (>0 for sfx)*/
|
|
608
|
-
uint64_t size_central_dir = 0; /* size of the central directory */
|
|
609
|
-
uint64_t offset_central_dir = 0; /* offset of start of central directory */
|
|
610
|
-
uint64_t number_entry_CD = 0; /* total number of entries in the central dir */
|
|
611
|
-
uint64_t number_entry = 0;
|
|
612
|
-
uint64_t central_pos = 0;
|
|
613
|
-
uint64_t size_central_dir_to_read = 0;
|
|
614
|
-
uint16_t value16 = 0;
|
|
615
|
-
uint32_t value32 = 0;
|
|
616
|
-
uint16_t size_comment = 0;
|
|
617
|
-
size_t buf_size = SIZEDATA_INDATABLOCK;
|
|
618
|
-
void *buf_read = NULL;
|
|
619
|
-
#endif
|
|
620
|
-
int err = ZIP_OK;
|
|
621
|
-
int mode = 0;
|
|
622
|
-
|
|
623
|
-
if (pzlib_filefunc64_32_def == NULL)
|
|
624
|
-
fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
|
|
625
|
-
else
|
|
626
|
-
{
|
|
627
|
-
assert((pzlib_filefunc64_32_def->zopen32_file || pzlib_filefunc64_32_def->zfile_func64.zopen64_file) &&
|
|
628
|
-
(pzlib_filefunc64_32_def->zopendisk32_file || pzlib_filefunc64_32_def->zfile_func64.zopendisk64_file) &&
|
|
629
|
-
(pzlib_filefunc64_32_def->ztell32_file || pzlib_filefunc64_32_def->zfile_func64.ztell64_file) &&
|
|
630
|
-
(pzlib_filefunc64_32_def->zseek32_file || pzlib_filefunc64_32_def->zfile_func64.zseek64_file));
|
|
631
|
-
ziinit.z_filefunc = *pzlib_filefunc64_32_def;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
if (append == APPEND_STATUS_CREATE)
|
|
635
|
-
mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE);
|
|
636
|
-
else
|
|
637
|
-
mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING);
|
|
638
|
-
|
|
639
|
-
ziinit.filestream = ZOPEN64(ziinit.z_filefunc, path, mode);
|
|
640
|
-
if (ziinit.filestream == NULL)
|
|
641
|
-
return NULL;
|
|
642
|
-
|
|
643
|
-
if (append == APPEND_STATUS_CREATEAFTER)
|
|
644
|
-
{
|
|
645
|
-
/* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */
|
|
646
|
-
if (disk_size > 0)
|
|
647
|
-
return NULL;
|
|
648
|
-
|
|
649
|
-
ZSEEK64(ziinit.z_filefunc, ziinit.filestream, 0, SEEK_END);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
ziinit.filestream_with_CD = ziinit.filestream;
|
|
653
|
-
ziinit.append = append;
|
|
654
|
-
ziinit.disk_size = disk_size;
|
|
655
|
-
init_linkedlist(&(ziinit.central_dir));
|
|
656
|
-
|
|
657
|
-
zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
|
|
658
|
-
if (zi == NULL)
|
|
659
|
-
{
|
|
660
|
-
ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
|
|
661
|
-
return NULL;
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
665
|
-
/* Add file in a zipfile */
|
|
666
|
-
ziinit.globalcomment = NULL;
|
|
667
|
-
if (append == APPEND_STATUS_ADDINZIP)
|
|
668
|
-
{
|
|
669
|
-
/* Read and Cache Central Directory Records */
|
|
670
|
-
central_pos = zipSearchCentralDir(&ziinit.z_filefunc, ziinit.filestream);
|
|
671
|
-
/* Disable to allow appending to empty ZIP archive (must be standard zip, not zip64)
|
|
672
|
-
if (central_pos == 0)
|
|
673
|
-
err = ZIP_ERRNO;
|
|
674
|
-
*/
|
|
675
|
-
|
|
676
|
-
if (err == ZIP_OK)
|
|
677
|
-
{
|
|
678
|
-
/* Read end of central directory info */
|
|
679
|
-
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
680
|
-
err = ZIP_ERRNO;
|
|
681
|
-
|
|
682
|
-
/* The signature, already checked */
|
|
683
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
684
|
-
err = ZIP_ERRNO;
|
|
685
|
-
/* Number of this disk */
|
|
686
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
687
|
-
err = ZIP_ERRNO;
|
|
688
|
-
ziinit.number_disk = value16;
|
|
689
|
-
/* Number of the disk with the start of the central directory */
|
|
690
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
691
|
-
err = ZIP_ERRNO;
|
|
692
|
-
ziinit.number_disk_with_CD = value16;
|
|
693
|
-
/* Total number of entries in the central dir on this disk */
|
|
694
|
-
number_entry = 0;
|
|
695
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
696
|
-
err = ZIP_ERRNO;
|
|
697
|
-
else
|
|
698
|
-
number_entry = value16;
|
|
699
|
-
/* Total number of entries in the central dir */
|
|
700
|
-
number_entry_CD = 0;
|
|
701
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
702
|
-
err = ZIP_ERRNO;
|
|
703
|
-
else
|
|
704
|
-
number_entry_CD = value16;
|
|
705
|
-
if (number_entry_CD!=number_entry)
|
|
706
|
-
err = ZIP_BADZIPFILE;
|
|
707
|
-
/* Size of the central directory */
|
|
708
|
-
size_central_dir = 0;
|
|
709
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
710
|
-
err = ZIP_ERRNO;
|
|
711
|
-
else
|
|
712
|
-
size_central_dir = value32;
|
|
713
|
-
/* Offset of start of central directory with respect to the starting disk number */
|
|
714
|
-
offset_central_dir = 0;
|
|
715
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
716
|
-
err = ZIP_ERRNO;
|
|
717
|
-
else
|
|
718
|
-
offset_central_dir = value32;
|
|
719
|
-
/* Zipfile global comment length */
|
|
720
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK)
|
|
721
|
-
err = ZIP_ERRNO;
|
|
722
|
-
|
|
723
|
-
if ((err == ZIP_OK) && ((number_entry_CD == UINT16_MAX) || (offset_central_dir == UINT32_MAX)))
|
|
724
|
-
{
|
|
725
|
-
/* Format should be Zip64, as the central directory or file size is too large */
|
|
726
|
-
central_pos = zipSearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos);
|
|
727
|
-
|
|
728
|
-
if (central_pos)
|
|
729
|
-
{
|
|
730
|
-
uint64_t sizeEndOfCentralDirectory;
|
|
731
|
-
|
|
732
|
-
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
733
|
-
err = ZIP_ERRNO;
|
|
734
|
-
|
|
735
|
-
/* The signature, already checked */
|
|
736
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
737
|
-
err = ZIP_ERRNO;
|
|
738
|
-
/* Size of zip64 end of central directory record */
|
|
739
|
-
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK)
|
|
740
|
-
err = ZIP_ERRNO;
|
|
741
|
-
/* Version made by */
|
|
742
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
743
|
-
err = ZIP_ERRNO;
|
|
744
|
-
/* Version needed to extract */
|
|
745
|
-
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
746
|
-
err = ZIP_ERRNO;
|
|
747
|
-
/* Number of this disk */
|
|
748
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)
|
|
749
|
-
err = ZIP_ERRNO;
|
|
750
|
-
/* Number of the disk with the start of the central directory */
|
|
751
|
-
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)
|
|
752
|
-
err = ZIP_ERRNO;
|
|
753
|
-
/* Total number of entries in the central directory on this disk */
|
|
754
|
-
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK)
|
|
755
|
-
err = ZIP_ERRNO;
|
|
756
|
-
/* Total number of entries in the central directory */
|
|
757
|
-
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK)
|
|
758
|
-
err = ZIP_ERRNO;
|
|
759
|
-
if (number_entry_CD!=number_entry)
|
|
760
|
-
err = ZIP_BADZIPFILE;
|
|
761
|
-
/* Size of the central directory */
|
|
762
|
-
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK)
|
|
763
|
-
err = ZIP_ERRNO;
|
|
764
|
-
/* Offset of start of central directory with respect to the starting disk number */
|
|
765
|
-
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK)
|
|
766
|
-
err = ZIP_ERRNO;
|
|
767
|
-
}
|
|
768
|
-
else
|
|
769
|
-
err = ZIP_BADZIPFILE;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
if ((err == ZIP_OK) && (central_pos < offset_central_dir + size_central_dir))
|
|
774
|
-
err = ZIP_BADZIPFILE;
|
|
775
|
-
|
|
776
|
-
if ((err == ZIP_OK) && (size_comment > 0))
|
|
777
|
-
{
|
|
778
|
-
ziinit.globalcomment = (char*)ALLOC(size_comment+1);
|
|
779
|
-
if (ziinit.globalcomment)
|
|
780
|
-
{
|
|
781
|
-
if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment) != size_comment)
|
|
782
|
-
err = ZIP_ERRNO;
|
|
783
|
-
else
|
|
784
|
-
ziinit.globalcomment[size_comment] = 0;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
if (err != ZIP_OK)
|
|
789
|
-
{
|
|
790
|
-
ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
|
|
791
|
-
TRYFREE(ziinit.globalcomment);
|
|
792
|
-
TRYFREE(zi);
|
|
793
|
-
return NULL;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
|
|
797
|
-
ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
|
|
798
|
-
|
|
799
|
-
/* Store central directory in memory */
|
|
800
|
-
size_central_dir_to_read = size_central_dir;
|
|
801
|
-
buf_size = SIZEDATA_INDATABLOCK;
|
|
802
|
-
buf_read = (void*)ALLOC(buf_size);
|
|
803
|
-
|
|
804
|
-
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
|
|
805
|
-
offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
806
|
-
err = ZIP_ERRNO;
|
|
807
|
-
|
|
808
|
-
while ((size_central_dir_to_read > 0) && (err == ZIP_OK))
|
|
809
|
-
{
|
|
810
|
-
uint64_t read_this = SIZEDATA_INDATABLOCK;
|
|
811
|
-
if (read_this > size_central_dir_to_read)
|
|
812
|
-
read_this = size_central_dir_to_read;
|
|
813
|
-
|
|
814
|
-
if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uint32_t)read_this) != read_this)
|
|
815
|
-
err = ZIP_ERRNO;
|
|
816
|
-
|
|
817
|
-
if (err == ZIP_OK)
|
|
818
|
-
err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uint32_t)read_this);
|
|
819
|
-
|
|
820
|
-
size_central_dir_to_read -= read_this;
|
|
821
|
-
}
|
|
822
|
-
TRYFREE(buf_read);
|
|
823
|
-
|
|
824
|
-
ziinit.number_entry = number_entry_CD;
|
|
825
|
-
|
|
826
|
-
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
|
|
827
|
-
offset_central_dir+byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
828
|
-
err = ZIP_ERRNO;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
if (globalcomment)
|
|
832
|
-
*globalcomment = ziinit.globalcomment;
|
|
833
|
-
#endif
|
|
834
|
-
|
|
835
|
-
if (err != ZIP_OK)
|
|
836
|
-
{
|
|
837
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
838
|
-
TRYFREE(ziinit.globalcomment);
|
|
839
|
-
#endif
|
|
840
|
-
TRYFREE(zi);
|
|
841
|
-
return NULL;
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
*zi = ziinit;
|
|
845
|
-
zipGoToFirstDisk((zipFile)zi);
|
|
846
|
-
return(zipFile)zi;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment,
|
|
850
|
-
zlib_filefunc_def *pzlib_filefunc32_def)
|
|
851
|
-
{
|
|
852
|
-
if (pzlib_filefunc32_def != NULL)
|
|
853
|
-
{
|
|
854
|
-
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
855
|
-
fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
|
|
856
|
-
return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
857
|
-
}
|
|
858
|
-
return zipOpen4(path, append, 0, globalcomment, NULL);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment,
|
|
862
|
-
zlib_filefunc64_def *pzlib_filefunc_def)
|
|
863
|
-
{
|
|
864
|
-
if (pzlib_filefunc_def != NULL)
|
|
865
|
-
{
|
|
866
|
-
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
867
|
-
zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
|
|
868
|
-
return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
869
|
-
}
|
|
870
|
-
return zipOpen4(path, append, 0, globalcomment, NULL);
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
extern zipFile ZEXPORT zipOpen3(const char *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
874
|
-
zlib_filefunc_def *pzlib_filefunc32_def)
|
|
875
|
-
{
|
|
876
|
-
if (pzlib_filefunc32_def != NULL)
|
|
877
|
-
{
|
|
878
|
-
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
879
|
-
fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
|
|
880
|
-
return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
881
|
-
}
|
|
882
|
-
return zipOpen4(path, append, disk_size, globalcomment, NULL);
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
extern zipFile ZEXPORT zipOpen3_64(const void *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
886
|
-
zlib_filefunc64_def *pzlib_filefunc_def)
|
|
887
|
-
{
|
|
888
|
-
if (pzlib_filefunc_def != NULL)
|
|
889
|
-
{
|
|
890
|
-
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
891
|
-
zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
|
|
892
|
-
return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
893
|
-
}
|
|
894
|
-
return zipOpen4(path, append, disk_size, globalcomment, NULL);
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
extern zipFile ZEXPORT zipOpen(const char *path, int append)
|
|
898
|
-
{
|
|
899
|
-
return zipOpen3((const void*)path, append, 0, NULL, NULL);
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
extern zipFile ZEXPORT zipOpen64(const void *path, int append)
|
|
903
|
-
{
|
|
904
|
-
return zipOpen3(path, append, 0, NULL, NULL);
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file,
|
|
908
|
-
const char *filename,
|
|
909
|
-
const zip_fileinfo *zipfi,
|
|
910
|
-
const void *extrafield_local,
|
|
911
|
-
uint16_t size_extrafield_local,
|
|
912
|
-
const void *extrafield_global,
|
|
913
|
-
uint16_t size_extrafield_global,
|
|
914
|
-
const char *comment,
|
|
915
|
-
uint16_t flag_base,
|
|
916
|
-
int zip64,
|
|
917
|
-
uint16_t method,
|
|
918
|
-
int level,
|
|
919
|
-
int raw,
|
|
920
|
-
int windowBits,
|
|
921
|
-
int memLevel,
|
|
922
|
-
int strategy,
|
|
923
|
-
const char *password,
|
|
924
|
-
int aes,
|
|
925
|
-
uint16_t version_madeby)
|
|
926
|
-
{
|
|
927
|
-
zip64_internal *zi = NULL;
|
|
928
|
-
uint64_t size_available = 0;
|
|
929
|
-
uint64_t size_needed = 0;
|
|
930
|
-
uint16_t size_filename = 0;
|
|
931
|
-
uint16_t size_comment = 0;
|
|
932
|
-
uint16_t i = 0;
|
|
933
|
-
unsigned char *central_dir = NULL;
|
|
934
|
-
int err = ZIP_OK;
|
|
935
|
-
|
|
936
|
-
#ifdef NOCRYPT
|
|
937
|
-
if (password != NULL)
|
|
938
|
-
return ZIP_PARAMERROR;
|
|
939
|
-
#endif
|
|
940
|
-
|
|
941
|
-
if (file == NULL)
|
|
942
|
-
return ZIP_PARAMERROR;
|
|
943
|
-
|
|
944
|
-
if ((method != 0) &&
|
|
945
|
-
#ifdef HAVE_BZIP2
|
|
946
|
-
(method != Z_BZIP2ED) &&
|
|
947
|
-
#endif
|
|
948
|
-
(method != Z_DEFLATED))
|
|
949
|
-
return ZIP_PARAMERROR;
|
|
950
|
-
|
|
951
|
-
zi = (zip64_internal*)file;
|
|
952
|
-
|
|
953
|
-
if (zi->in_opened_file_inzip == 1)
|
|
954
|
-
{
|
|
955
|
-
err = zipCloseFileInZip (file);
|
|
956
|
-
if (err != ZIP_OK)
|
|
957
|
-
return err;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
if (filename == NULL)
|
|
961
|
-
filename = "-";
|
|
962
|
-
if (comment != NULL)
|
|
963
|
-
size_comment = (uint16_t)strlen(comment);
|
|
964
|
-
|
|
965
|
-
size_filename = (uint16_t)strlen(filename);
|
|
966
|
-
|
|
967
|
-
if (zipfi == NULL)
|
|
968
|
-
zi->ci.dos_date = 0;
|
|
969
|
-
else
|
|
970
|
-
{
|
|
971
|
-
if (zipfi->dos_date != 0)
|
|
972
|
-
zi->ci.dos_date = zipfi->dos_date;
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
zi->ci.method = method;
|
|
976
|
-
zi->ci.compression_method = method;
|
|
977
|
-
zi->ci.raw = raw;
|
|
978
|
-
zi->ci.flag = flag_base | 8;
|
|
979
|
-
if ((level == 8) || (level == 9))
|
|
980
|
-
zi->ci.flag |= 2;
|
|
981
|
-
if (level == 2)
|
|
982
|
-
zi->ci.flag |= 4;
|
|
983
|
-
if (level == 1)
|
|
984
|
-
zi->ci.flag |= 6;
|
|
985
|
-
|
|
986
|
-
if (password != NULL)
|
|
987
|
-
{
|
|
988
|
-
zi->ci.flag |= 1;
|
|
989
|
-
#ifdef HAVE_AES
|
|
990
|
-
if (aes)
|
|
991
|
-
zi->ci.method = AES_METHOD;
|
|
992
|
-
#endif
|
|
993
|
-
}
|
|
994
|
-
else
|
|
995
|
-
{
|
|
996
|
-
zi->ci.flag &= ~1;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
if (zi->disk_size > 0)
|
|
1000
|
-
{
|
|
1001
|
-
if ((zi->number_disk == 0) && (zi->number_entry == 0))
|
|
1002
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DISKHEADERMAGIC, 4);
|
|
1003
|
-
|
|
1004
|
-
/* Make sure enough space available on current disk for local header */
|
|
1005
|
-
zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
|
1006
|
-
size_needed = 30 + size_filename + size_extrafield_local;
|
|
1007
|
-
#ifdef HAVE_AES
|
|
1008
|
-
if (zi->ci.method == AES_METHOD)
|
|
1009
|
-
size_needed += 11;
|
|
1010
|
-
#endif
|
|
1011
|
-
if (size_available < size_needed)
|
|
1012
|
-
zipGoToNextDisk((zipFile)zi);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
zi->ci.zip64 = zip64;
|
|
1016
|
-
|
|
1017
|
-
zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1018
|
-
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1019
|
-
zi->ci.zip64 = 1;
|
|
1020
|
-
|
|
1021
|
-
zi->ci.size_comment = size_comment;
|
|
1022
|
-
zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global;
|
|
1023
|
-
zi->ci.size_centralextra = size_extrafield_global;
|
|
1024
|
-
zi->ci.size_centralextrafree = 32; /* Extra space reserved for ZIP64 extra info */
|
|
1025
|
-
#ifdef HAVE_AES
|
|
1026
|
-
if (zi->ci.method == AES_METHOD)
|
|
1027
|
-
zi->ci.size_centralextrafree += 11; /* Extra space reserved for AES extra info */
|
|
1028
|
-
#endif
|
|
1029
|
-
zi->ci.central_header = (char*)ALLOC((uint32_t)zi->ci.size_centralheader + zi->ci.size_centralextrafree + size_comment);
|
|
1030
|
-
zi->ci.number_disk = zi->number_disk;
|
|
1031
|
-
|
|
1032
|
-
/* Write central directory header */
|
|
1033
|
-
/* https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT */
|
|
1034
|
-
central_dir = (unsigned char*)zi->ci.central_header;
|
|
1035
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)CENTRALHEADERMAGIC, 4);
|
|
1036
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, version_madeby, 2);
|
|
1037
|
-
if (zi->ci.zip64)
|
|
1038
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)45, 2);
|
|
1039
|
-
else
|
|
1040
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)20, 2);
|
|
1041
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.flag, 2);
|
|
1042
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.method, 2);
|
|
1043
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.dos_date, 4);
|
|
1044
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*crc*/
|
|
1045
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*compr size*/
|
|
1046
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*uncompr size*/
|
|
1047
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, size_filename, 2);
|
|
1048
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, size_extrafield_global, 2);
|
|
1049
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, size_comment, 2);
|
|
1050
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)zi->ci.number_disk, 2); /*disk nm start*/
|
|
1051
|
-
|
|
1052
|
-
if (zipfi == NULL)
|
|
1053
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)0, 2);
|
|
1054
|
-
else
|
|
1055
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->internal_fa, 2);
|
|
1056
|
-
if (zipfi == NULL)
|
|
1057
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4);
|
|
1058
|
-
else
|
|
1059
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->external_fa, 4);
|
|
1060
|
-
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1061
|
-
zipWriteValueToMemoryAndMove(¢ral_dir, UINT32_MAX, 4);
|
|
1062
|
-
else
|
|
1063
|
-
zipWriteValueToMemoryAndMove(¢ral_dir,
|
|
1064
|
-
(uint32_t)(zi->ci.pos_local_header - zi->add_position_when_writting_offset), 4);
|
|
1065
|
-
|
|
1066
|
-
for (i = 0; i < size_filename; i++)
|
|
1067
|
-
zi->ci.central_header[SIZECENTRALHEADER+i] = filename[i];
|
|
1068
|
-
for (i = 0; i < size_extrafield_global; i++)
|
|
1069
|
-
zi->ci.central_header[SIZECENTRALHEADER+size_filename+i] =
|
|
1070
|
-
((const char*)extrafield_global)[i];
|
|
1071
|
-
|
|
1072
|
-
/* Store comment at the end for later repositioning */
|
|
1073
|
-
for (i = 0; i < size_comment; i++)
|
|
1074
|
-
zi->ci.central_header[zi->ci.size_centralheader+
|
|
1075
|
-
zi->ci.size_centralextrafree+i] = comment[i];
|
|
1076
|
-
|
|
1077
|
-
if (zi->ci.central_header == NULL)
|
|
1078
|
-
return ZIP_INTERNALERROR;
|
|
1079
|
-
|
|
1080
|
-
/* Write the local header */
|
|
1081
|
-
if (err == ZIP_OK)
|
|
1082
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)LOCALHEADERMAGIC, 4);
|
|
1083
|
-
|
|
1084
|
-
if (err == ZIP_OK)
|
|
1085
|
-
{
|
|
1086
|
-
if (zi->ci.zip64)
|
|
1087
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2); /* version needed to extract */
|
|
1088
|
-
else
|
|
1089
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)20, 2); /* version needed to extract */
|
|
1090
|
-
}
|
|
1091
|
-
if (err == ZIP_OK)
|
|
1092
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.flag, 2);
|
|
1093
|
-
if (err == ZIP_OK)
|
|
1094
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.method, 2);
|
|
1095
|
-
if (err == ZIP_OK)
|
|
1096
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.dos_date, 4);
|
|
1097
|
-
|
|
1098
|
-
/* CRC & compressed size & uncompressed size is in data descriptor */
|
|
1099
|
-
if (err == ZIP_OK)
|
|
1100
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* crc 32, unknown */
|
|
1101
|
-
if (err == ZIP_OK)
|
|
1102
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* compressed size, unknown */
|
|
1103
|
-
if (err == ZIP_OK)
|
|
1104
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* uncompressed size, unknown */
|
|
1105
|
-
if (err == ZIP_OK)
|
|
1106
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_filename, 2);
|
|
1107
|
-
if (err == ZIP_OK)
|
|
1108
|
-
{
|
|
1109
|
-
uint64_t size_extrafield = size_extrafield_local;
|
|
1110
|
-
#ifdef HAVE_AES
|
|
1111
|
-
if (zi->ci.method == AES_METHOD)
|
|
1112
|
-
size_extrafield += 11;
|
|
1113
|
-
#endif
|
|
1114
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)size_extrafield, 2);
|
|
1115
|
-
}
|
|
1116
|
-
if ((err == ZIP_OK) && (size_filename > 0))
|
|
1117
|
-
{
|
|
1118
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename)
|
|
1119
|
-
err = ZIP_ERRNO;
|
|
1120
|
-
}
|
|
1121
|
-
if ((err == ZIP_OK) && (size_extrafield_local > 0))
|
|
1122
|
-
{
|
|
1123
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
|
|
1124
|
-
err = ZIP_ERRNO;
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
#ifdef HAVE_AES
|
|
1128
|
-
/* Write the AES extended info */
|
|
1129
|
-
if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD))
|
|
1130
|
-
{
|
|
1131
|
-
int headerid = 0x9901;
|
|
1132
|
-
short datasize = 7;
|
|
1133
|
-
|
|
1134
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, headerid, 2);
|
|
1135
|
-
if (err == ZIP_OK)
|
|
1136
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, datasize, 2);
|
|
1137
|
-
if (err == ZIP_OK)
|
|
1138
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2);
|
|
1139
|
-
if (err == ZIP_OK)
|
|
1140
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'A', 1);
|
|
1141
|
-
if (err == ZIP_OK)
|
|
1142
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'E', 1);
|
|
1143
|
-
if (err == ZIP_OK)
|
|
1144
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1);
|
|
1145
|
-
if (err == ZIP_OK)
|
|
1146
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2);
|
|
1147
|
-
}
|
|
1148
|
-
#endif
|
|
1149
|
-
|
|
1150
|
-
zi->ci.crc32 = 0;
|
|
1151
|
-
zi->ci.stream_initialised = 0;
|
|
1152
|
-
zi->ci.pos_in_buffered_data = 0;
|
|
1153
|
-
zi->ci.total_compressed = 0;
|
|
1154
|
-
zi->ci.total_uncompressed = 0;
|
|
1155
|
-
|
|
1156
|
-
#ifdef HAVE_BZIP2
|
|
1157
|
-
zi->ci.bstream.avail_in = (uint16_t)0;
|
|
1158
|
-
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1159
|
-
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1160
|
-
zi->ci.bstream.total_in_hi32 = 0;
|
|
1161
|
-
zi->ci.bstream.total_in_lo32 = 0;
|
|
1162
|
-
zi->ci.bstream.total_out_hi32 = 0;
|
|
1163
|
-
zi->ci.bstream.total_out_lo32 = 0;
|
|
1164
|
-
#endif
|
|
1165
|
-
|
|
1166
|
-
zi->ci.stream.avail_in = (uint16_t)0;
|
|
1167
|
-
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1168
|
-
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1169
|
-
zi->ci.stream.total_in = 0;
|
|
1170
|
-
zi->ci.stream.total_out = 0;
|
|
1171
|
-
zi->ci.stream.data_type = Z_BINARY;
|
|
1172
|
-
|
|
1173
|
-
if ((err == ZIP_OK) && (!zi->ci.raw))
|
|
1174
|
-
{
|
|
1175
|
-
if (method == Z_DEFLATED)
|
|
1176
|
-
{
|
|
1177
|
-
zi->ci.stream.zalloc = (alloc_func)0;
|
|
1178
|
-
zi->ci.stream.zfree = (free_func)0;
|
|
1179
|
-
zi->ci.stream.opaque = (voidpf)zi;
|
|
1180
|
-
|
|
1181
|
-
if (windowBits > 0)
|
|
1182
|
-
windowBits = -windowBits;
|
|
1183
|
-
|
|
1184
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
1185
|
-
err = compression_stream_init(&zi->ci.astream, COMPRESSION_STREAM_ENCODE, COMPRESSION_ZLIB);
|
|
1186
|
-
if (err == COMPRESSION_STATUS_ERROR)
|
|
1187
|
-
err = Z_ERRNO;
|
|
1188
|
-
else
|
|
1189
|
-
err = Z_OK;
|
|
1190
|
-
#else
|
|
1191
|
-
err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
|
|
1192
|
-
#endif
|
|
1193
|
-
if (err == Z_OK)
|
|
1194
|
-
zi->ci.stream_initialised = Z_DEFLATED;
|
|
1195
|
-
}
|
|
1196
|
-
else if (method == Z_BZIP2ED)
|
|
1197
|
-
{
|
|
1198
|
-
#ifdef HAVE_BZIP2
|
|
1199
|
-
zi->ci.bstream.bzalloc = 0;
|
|
1200
|
-
zi->ci.bstream.bzfree = 0;
|
|
1201
|
-
zi->ci.bstream.opaque = (voidpf)0;
|
|
1202
|
-
|
|
1203
|
-
err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35);
|
|
1204
|
-
if (err == BZ_OK)
|
|
1205
|
-
zi->ci.stream_initialised = Z_BZIP2ED;
|
|
1206
|
-
#endif
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
#ifndef NOCRYPT
|
|
1211
|
-
if ((err == Z_OK) && (password != NULL))
|
|
1212
|
-
{
|
|
1213
|
-
#ifdef HAVE_AES
|
|
1214
|
-
if (zi->ci.method == AES_METHOD)
|
|
1215
|
-
{
|
|
1216
|
-
unsigned char passverify[AES_PWVERIFYSIZE];
|
|
1217
|
-
unsigned char saltvalue[AES_MAXSALTLENGTH];
|
|
1218
|
-
uint16_t saltlength = 0;
|
|
1219
|
-
|
|
1220
|
-
if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3))
|
|
1221
|
-
return Z_ERRNO;
|
|
1222
|
-
|
|
1223
|
-
saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE);
|
|
1224
|
-
|
|
1225
|
-
prng_init(cryptrand, zi->ci.aes_rng);
|
|
1226
|
-
prng_rand(saltvalue, saltlength, zi->ci.aes_rng);
|
|
1227
|
-
prng_end(zi->ci.aes_rng);
|
|
1228
|
-
|
|
1229
|
-
fcrypt_init(AES_ENCRYPTIONMODE, (uint8_t *)password, (uint32_t)strlen(password), saltvalue, passverify, &zi->ci.aes_ctx);
|
|
1230
|
-
|
|
1231
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, saltvalue, saltlength) != saltlength)
|
|
1232
|
-
err = ZIP_ERRNO;
|
|
1233
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)
|
|
1234
|
-
err = ZIP_ERRNO;
|
|
1235
|
-
|
|
1236
|
-
zi->ci.total_compressed += saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE;
|
|
1237
|
-
}
|
|
1238
|
-
else
|
|
1239
|
-
#endif
|
|
1240
|
-
{
|
|
1241
|
-
unsigned char buf_head[RAND_HEAD_LEN];
|
|
1242
|
-
uint32_t size_head = 0;
|
|
1243
|
-
uint8_t verify1 = 0;
|
|
1244
|
-
uint8_t verify2 = 0;
|
|
1245
|
-
|
|
1246
|
-
zi->ci.pcrc_32_tab = get_crc_table();
|
|
1247
|
-
|
|
1248
|
-
/*
|
|
1249
|
-
Info-ZIP modification to ZipCrypto format:
|
|
1250
|
-
If bit 3 of the general purpose bit flag is set, it uses high byte of 16-bit File Time.
|
|
1251
|
-
*/
|
|
1252
|
-
verify1 = (uint8_t)((zi->ci.dos_date >> 16) & 0xff);
|
|
1253
|
-
verify2 = (uint8_t)((zi->ci.dos_date >> 8) & 0xff);
|
|
1254
|
-
|
|
1255
|
-
size_head = crypthead(password, buf_head, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, verify1, verify2);
|
|
1256
|
-
zi->ci.total_compressed += size_head;
|
|
1257
|
-
|
|
1258
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, buf_head, size_head) != size_head)
|
|
1259
|
-
err = ZIP_ERRNO;
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
#endif
|
|
1263
|
-
|
|
1264
|
-
if (err == Z_OK)
|
|
1265
|
-
zi->in_opened_file_inzip = 1;
|
|
1266
|
-
return err;
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1270
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1271
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
|
1272
|
-
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
|
|
1273
|
-
{
|
|
1274
|
-
uint8_t aes = 0;
|
|
1275
|
-
#ifdef HAVE_AES
|
|
1276
|
-
aes = 1;
|
|
1277
|
-
#endif
|
|
1278
|
-
return zipOpenNewFileInZip5(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
|
|
1279
|
-
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
|
|
1280
|
-
version_madeby);
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1284
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1285
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1286
|
-
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base)
|
|
1287
|
-
{
|
|
1288
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1289
|
-
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
|
|
1290
|
-
strategy, password, crc_for_crypting, version_madeby, flag_base, 0);
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1294
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1295
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1296
|
-
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting)
|
|
1297
|
-
{
|
|
1298
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1299
|
-
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
|
|
1300
|
-
strategy, password, crc_for_crypting, VERSIONMADEBY, 0, 0);
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1304
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1305
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1306
|
-
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, int zip64)
|
|
1307
|
-
{
|
|
1308
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1309
|
-
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy,
|
|
1310
|
-
password, crc_for_crypting, VERSIONMADEBY, 0, zip64);
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1314
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1315
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw)
|
|
1316
|
-
{
|
|
1317
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1318
|
-
extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1319
|
-
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1323
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1324
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int zip64)
|
|
1325
|
-
{
|
|
1326
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1327
|
-
extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1328
|
-
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1332
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1333
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int zip64)
|
|
1334
|
-
{
|
|
1335
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1336
|
-
extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1337
|
-
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1341
|
-
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1342
|
-
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level)
|
|
1343
|
-
{
|
|
1344
|
-
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1345
|
-
extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1346
|
-
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
/* Flushes the write buffer to disk */
|
|
1350
|
-
static int zipFlushWriteBuffer(zip64_internal *zi)
|
|
1351
|
-
{
|
|
1352
|
-
uint64_t size_available = 0;
|
|
1353
|
-
uint32_t written = 0;
|
|
1354
|
-
uint32_t total_written = 0;
|
|
1355
|
-
uint32_t write = 0;
|
|
1356
|
-
uint32_t max_write = 0;
|
|
1357
|
-
int err = ZIP_OK;
|
|
1358
|
-
|
|
1359
|
-
if ((zi->ci.flag & 1) != 0)
|
|
1360
|
-
{
|
|
1361
|
-
#ifndef NOCRYPT
|
|
1362
|
-
#ifdef HAVE_AES
|
|
1363
|
-
if (zi->ci.method == AES_METHOD)
|
|
1364
|
-
{
|
|
1365
|
-
fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx);
|
|
1366
|
-
}
|
|
1367
|
-
else
|
|
1368
|
-
#endif
|
|
1369
|
-
{
|
|
1370
|
-
uint32_t i = 0;
|
|
1371
|
-
uint8_t t = 0;
|
|
1372
|
-
|
|
1373
|
-
for (i = 0; i < zi->ci.pos_in_buffered_data; i++)
|
|
1374
|
-
zi->ci.buffered_data[i] = (uint8_t)zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t);
|
|
1375
|
-
}
|
|
1376
|
-
#endif
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
write = zi->ci.pos_in_buffered_data;
|
|
1380
|
-
|
|
1381
|
-
do
|
|
1382
|
-
{
|
|
1383
|
-
max_write = write;
|
|
1384
|
-
|
|
1385
|
-
if (zi->disk_size > 0)
|
|
1386
|
-
{
|
|
1387
|
-
zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
|
1388
|
-
|
|
1389
|
-
if (size_available == 0)
|
|
1390
|
-
{
|
|
1391
|
-
err = zipGoToNextDisk((zipFile)zi);
|
|
1392
|
-
if (err != ZIP_OK)
|
|
1393
|
-
return err;
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
if (size_available < (uint64_t)max_write)
|
|
1397
|
-
max_write = (uint32_t)size_available;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
written = ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write);
|
|
1401
|
-
if (written != max_write)
|
|
1402
|
-
{
|
|
1403
|
-
err = ZIP_ERRNO;
|
|
1404
|
-
break;
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
total_written += written;
|
|
1408
|
-
write -= written;
|
|
1409
|
-
}
|
|
1410
|
-
while (write > 0);
|
|
1411
|
-
|
|
1412
|
-
zi->ci.total_compressed += zi->ci.pos_in_buffered_data;
|
|
1413
|
-
|
|
1414
|
-
#ifdef HAVE_BZIP2
|
|
1415
|
-
if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1416
|
-
{
|
|
1417
|
-
zi->ci.total_uncompressed += zi->ci.bstream.total_in_lo32;
|
|
1418
|
-
zi->ci.bstream.total_in_lo32 = 0;
|
|
1419
|
-
zi->ci.bstream.total_in_hi32 = 0;
|
|
1420
|
-
}
|
|
1421
|
-
else
|
|
1422
|
-
#endif
|
|
1423
|
-
{
|
|
1424
|
-
zi->ci.total_uncompressed += zi->ci.stream.total_in;
|
|
1425
|
-
zi->ci.stream.total_in = 0;
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
zi->ci.pos_in_buffered_data = 0;
|
|
1429
|
-
|
|
1430
|
-
return err;
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len)
|
|
1434
|
-
{
|
|
1435
|
-
zip64_internal *zi = NULL;
|
|
1436
|
-
int err = ZIP_OK;
|
|
1437
|
-
|
|
1438
|
-
if (file == NULL)
|
|
1439
|
-
return ZIP_PARAMERROR;
|
|
1440
|
-
zi = (zip64_internal*)file;
|
|
1441
|
-
|
|
1442
|
-
if (zi->in_opened_file_inzip == 0)
|
|
1443
|
-
return ZIP_PARAMERROR;
|
|
1444
|
-
|
|
1445
|
-
zi->ci.crc32 = (uint32_t)crc32(zi->ci.crc32, buf, len);
|
|
1446
|
-
|
|
1447
|
-
#ifdef HAVE_BZIP2
|
|
1448
|
-
if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw))
|
|
1449
|
-
{
|
|
1450
|
-
zi->ci.bstream.next_in = (void*)buf;
|
|
1451
|
-
zi->ci.bstream.avail_in = len;
|
|
1452
|
-
err = BZ_RUN_OK;
|
|
1453
|
-
|
|
1454
|
-
while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0))
|
|
1455
|
-
{
|
|
1456
|
-
if (zi->ci.bstream.avail_out == 0)
|
|
1457
|
-
{
|
|
1458
|
-
err = zipFlushWriteBuffer(zi);
|
|
1459
|
-
|
|
1460
|
-
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1461
|
-
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1462
|
-
}
|
|
1463
|
-
else
|
|
1464
|
-
{
|
|
1465
|
-
uint32_t total_out_before_lo = zi->ci.bstream.total_out_lo32;
|
|
1466
|
-
uint32_t total_out_before_hi = zi->ci.bstream.total_out_hi32;
|
|
1467
|
-
|
|
1468
|
-
err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
|
|
1469
|
-
|
|
1470
|
-
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before_lo);
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
if (err == BZ_RUN_OK)
|
|
1475
|
-
err = ZIP_OK;
|
|
1476
|
-
}
|
|
1477
|
-
else
|
|
1478
|
-
#endif
|
|
1479
|
-
{
|
|
1480
|
-
zi->ci.stream.next_in = (uint8_t*)buf;
|
|
1481
|
-
zi->ci.stream.avail_in = len;
|
|
1482
|
-
|
|
1483
|
-
while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0))
|
|
1484
|
-
{
|
|
1485
|
-
if (zi->ci.stream.avail_out == 0)
|
|
1486
|
-
{
|
|
1487
|
-
err = zipFlushWriteBuffer(zi);
|
|
1488
|
-
|
|
1489
|
-
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1490
|
-
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
if (err != ZIP_OK)
|
|
1494
|
-
break;
|
|
1495
|
-
|
|
1496
|
-
if ((zi->ci.compression_method == Z_DEFLATED) && (!zi->ci.raw))
|
|
1497
|
-
{
|
|
1498
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
1499
|
-
uLong total_out_before = zi->ci.stream.total_out;
|
|
1500
|
-
|
|
1501
|
-
zi->ci.astream.src_ptr = zi->ci.stream.next_in;
|
|
1502
|
-
zi->ci.astream.src_size = zi->ci.stream.avail_in;
|
|
1503
|
-
zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
|
|
1504
|
-
zi->ci.astream.dst_size = zi->ci.stream.avail_out;
|
|
1505
|
-
|
|
1506
|
-
compression_status status = 0;
|
|
1507
|
-
compression_stream_flags flags = 0;
|
|
1508
|
-
|
|
1509
|
-
status = compression_stream_process(&zi->ci.astream, flags);
|
|
1510
|
-
|
|
1511
|
-
uLong total_out_after = len - zi->ci.astream.src_size;
|
|
1512
|
-
|
|
1513
|
-
zi->ci.stream.next_in = zi->ci.astream.src_ptr;
|
|
1514
|
-
zi->ci.stream.avail_in = zi->ci.astream.src_size;
|
|
1515
|
-
zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
|
|
1516
|
-
zi->ci.stream.avail_out = zi->ci.astream.dst_size;
|
|
1517
|
-
zi->ci.stream.total_in += total_out_after;
|
|
1518
|
-
//zi->ci.stream.total_out += copy_this;
|
|
1519
|
-
zi->ci.pos_in_buffered_data += total_out_after;
|
|
1520
|
-
|
|
1521
|
-
if (status == COMPRESSION_STATUS_ERROR)
|
|
1522
|
-
err = ZIP_INTERNALERROR;
|
|
1523
|
-
#else
|
|
1524
|
-
uint32_t total_out_before = (uint32_t)zi->ci.stream.total_out;
|
|
1525
|
-
err = deflate(&zi->ci.stream, Z_NO_FLUSH);
|
|
1526
|
-
zi->ci.pos_in_buffered_data += (uint32_t)(zi->ci.stream.total_out - total_out_before);
|
|
1527
|
-
#endif
|
|
1528
|
-
}
|
|
1529
|
-
else
|
|
1530
|
-
{
|
|
1531
|
-
uint32_t copy_this = 0;
|
|
1532
|
-
uint32_t i = 0;
|
|
1533
|
-
if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
|
|
1534
|
-
copy_this = zi->ci.stream.avail_in;
|
|
1535
|
-
else
|
|
1536
|
-
copy_this = zi->ci.stream.avail_out;
|
|
1537
|
-
|
|
1538
|
-
for (i = 0; i < copy_this; i++)
|
|
1539
|
-
*(((char*)zi->ci.stream.next_out)+i) =
|
|
1540
|
-
*(((const char*)zi->ci.stream.next_in)+i);
|
|
1541
|
-
|
|
1542
|
-
zi->ci.stream.avail_in -= copy_this;
|
|
1543
|
-
zi->ci.stream.avail_out -= copy_this;
|
|
1544
|
-
zi->ci.stream.next_in += copy_this;
|
|
1545
|
-
zi->ci.stream.next_out += copy_this;
|
|
1546
|
-
zi->ci.stream.total_in += copy_this;
|
|
1547
|
-
zi->ci.stream.total_out += copy_this;
|
|
1548
|
-
zi->ci.pos_in_buffered_data += copy_this;
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
return err;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32)
|
|
1557
|
-
{
|
|
1558
|
-
zip64_internal *zi = NULL;
|
|
1559
|
-
uint16_t extra_data_size = 0;
|
|
1560
|
-
uint32_t i = 0;
|
|
1561
|
-
unsigned char *extra_info = NULL;
|
|
1562
|
-
int err = ZIP_OK;
|
|
1563
|
-
|
|
1564
|
-
if (file == NULL)
|
|
1565
|
-
return ZIP_PARAMERROR;
|
|
1566
|
-
zi = (zip64_internal*)file;
|
|
1567
|
-
|
|
1568
|
-
if (zi->in_opened_file_inzip == 0)
|
|
1569
|
-
return ZIP_PARAMERROR;
|
|
1570
|
-
zi->ci.stream.avail_in = 0;
|
|
1571
|
-
|
|
1572
|
-
if (!zi->ci.raw)
|
|
1573
|
-
{
|
|
1574
|
-
if (zi->ci.compression_method == Z_DEFLATED)
|
|
1575
|
-
{
|
|
1576
|
-
while (err == ZIP_OK)
|
|
1577
|
-
{
|
|
1578
|
-
uint32_t total_out_before = 0;
|
|
1579
|
-
|
|
1580
|
-
if (zi->ci.stream.avail_out == 0)
|
|
1581
|
-
{
|
|
1582
|
-
err = zipFlushWriteBuffer(zi);
|
|
1583
|
-
|
|
1584
|
-
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1585
|
-
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
if (err != ZIP_OK)
|
|
1589
|
-
break;
|
|
1590
|
-
|
|
1591
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
1592
|
-
total_out_before = zi->ci.stream.total_out;
|
|
1593
|
-
|
|
1594
|
-
zi->ci.astream.src_ptr = zi->ci.stream.next_in;
|
|
1595
|
-
zi->ci.astream.src_size = zi->ci.stream.avail_in;
|
|
1596
|
-
zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
|
|
1597
|
-
zi->ci.astream.dst_size = zi->ci.stream.avail_out;
|
|
1598
|
-
|
|
1599
|
-
compression_status status = 0;
|
|
1600
|
-
status = compression_stream_process(&zi->ci.astream, COMPRESSION_STREAM_FINALIZE);
|
|
1601
|
-
|
|
1602
|
-
uint32_t total_out_after = Z_BUFSIZE - zi->ci.astream.dst_size;
|
|
1603
|
-
|
|
1604
|
-
zi->ci.stream.next_in = zi->ci.astream.src_ptr;
|
|
1605
|
-
zi->ci.stream.avail_in = zi->ci.astream.src_size;
|
|
1606
|
-
zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
|
|
1607
|
-
zi->ci.stream.avail_out = zi->ci.astream.dst_size;
|
|
1608
|
-
//zi->ci.stream.total_in += total_out_after;
|
|
1609
|
-
//zi->ci.stream.total_out += copy_this;
|
|
1610
|
-
zi->ci.pos_in_buffered_data += total_out_after;
|
|
1611
|
-
|
|
1612
|
-
if (status == COMPRESSION_STATUS_ERROR)
|
|
1613
|
-
{
|
|
1614
|
-
err = ZIP_INTERNALERROR;
|
|
1615
|
-
}
|
|
1616
|
-
else if (status == COMPRESSION_STATUS_END)
|
|
1617
|
-
{
|
|
1618
|
-
err = Z_STREAM_END;
|
|
1619
|
-
}
|
|
1620
|
-
#else
|
|
1621
|
-
total_out_before = (uint32_t)zi->ci.stream.total_out;
|
|
1622
|
-
err = deflate(&zi->ci.stream, Z_FINISH);
|
|
1623
|
-
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.stream.total_out - total_out_before);
|
|
1624
|
-
#endif
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
else if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1628
|
-
{
|
|
1629
|
-
#ifdef HAVE_BZIP2
|
|
1630
|
-
err = BZ_FINISH_OK;
|
|
1631
|
-
while (err == BZ_FINISH_OK)
|
|
1632
|
-
{
|
|
1633
|
-
uint32_t total_out_before = 0;
|
|
1634
|
-
|
|
1635
|
-
if (zi->ci.bstream.avail_out == 0)
|
|
1636
|
-
{
|
|
1637
|
-
err = zipFlushWriteBuffer(zi);
|
|
1638
|
-
|
|
1639
|
-
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1640
|
-
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
total_out_before = zi->ci.bstream.total_out_lo32;
|
|
1644
|
-
err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
|
|
1645
|
-
if (err == BZ_STREAM_END)
|
|
1646
|
-
err = Z_STREAM_END;
|
|
1647
|
-
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before);
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
if (err == BZ_FINISH_OK)
|
|
1651
|
-
err = ZIP_OK;
|
|
1652
|
-
#endif
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
if (err == Z_STREAM_END)
|
|
1657
|
-
err = ZIP_OK; /* this is normal */
|
|
1658
|
-
|
|
1659
|
-
if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK))
|
|
1660
|
-
{
|
|
1661
|
-
err = zipFlushWriteBuffer(zi);
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
#ifdef HAVE_AES
|
|
1665
|
-
if (zi->ci.method == AES_METHOD)
|
|
1666
|
-
{
|
|
1667
|
-
unsigned char authcode[AES_AUTHCODESIZE];
|
|
1668
|
-
|
|
1669
|
-
fcrypt_end(authcode, &zi->ci.aes_ctx);
|
|
1670
|
-
|
|
1671
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)
|
|
1672
|
-
err = ZIP_ERRNO;
|
|
1673
|
-
}
|
|
1674
|
-
#endif
|
|
1675
|
-
|
|
1676
|
-
if (!zi->ci.raw)
|
|
1677
|
-
{
|
|
1678
|
-
if (zi->ci.compression_method == Z_DEFLATED)
|
|
1679
|
-
{
|
|
1680
|
-
int tmp_err = 0;
|
|
1681
|
-
#ifdef HAVE_APPLE_COMPRESSION
|
|
1682
|
-
tmp_err = compression_stream_destroy(&zi->ci.astream);
|
|
1683
|
-
#else
|
|
1684
|
-
tmp_err = deflateEnd(&zi->ci.stream);
|
|
1685
|
-
#endif
|
|
1686
|
-
if (err == ZIP_OK)
|
|
1687
|
-
err = tmp_err;
|
|
1688
|
-
zi->ci.stream_initialised = 0;
|
|
1689
|
-
}
|
|
1690
|
-
#ifdef HAVE_BZIP2
|
|
1691
|
-
else if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1692
|
-
{
|
|
1693
|
-
int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
|
|
1694
|
-
if (err == ZIP_OK)
|
|
1695
|
-
err = tmperr;
|
|
1696
|
-
zi->ci.stream_initialised = 0;
|
|
1697
|
-
}
|
|
1698
|
-
#endif
|
|
1699
|
-
|
|
1700
|
-
crc32 = zi->ci.crc32;
|
|
1701
|
-
uncompressed_size = zi->ci.total_uncompressed;
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
/* Write data descriptor */
|
|
1705
|
-
if (err == ZIP_OK)
|
|
1706
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DATADESCRIPTORMAGIC, 4);
|
|
1707
|
-
if (err == ZIP_OK)
|
|
1708
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, crc32, 4);
|
|
1709
|
-
if (err == ZIP_OK)
|
|
1710
|
-
{
|
|
1711
|
-
if (zi->ci.zip64)
|
|
1712
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.total_compressed, 8);
|
|
1713
|
-
else
|
|
1714
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)zi->ci.total_compressed, 4);
|
|
1715
|
-
}
|
|
1716
|
-
if (err == ZIP_OK)
|
|
1717
|
-
{
|
|
1718
|
-
if (zi->ci.zip64)
|
|
1719
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
|
|
1720
|
-
else
|
|
1721
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)uncompressed_size, 4);
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
/* Update crc and sizes to central directory */
|
|
1725
|
-
zipWriteValueToMemory(zi->ci.central_header + 16, crc32, 4); /* crc */
|
|
1726
|
-
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1727
|
-
zipWriteValueToMemory(zi->ci.central_header + 20, UINT32_MAX, 4); /* compr size */
|
|
1728
|
-
else
|
|
1729
|
-
zipWriteValueToMemory(zi->ci.central_header + 20, zi->ci.total_compressed, 4); /* compr size */
|
|
1730
|
-
if (uncompressed_size >= UINT32_MAX)
|
|
1731
|
-
zipWriteValueToMemory(zi->ci.central_header + 24, UINT32_MAX, 4); /* uncompr size */
|
|
1732
|
-
else
|
|
1733
|
-
zipWriteValueToMemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */
|
|
1734
|
-
if (zi->ci.stream.data_type == Z_ASCII)
|
|
1735
|
-
zipWriteValueToMemory(zi->ci.central_header + 36, (uint16_t)Z_ASCII, 2); /* internal file attrib */
|
|
1736
|
-
|
|
1737
|
-
/* Add ZIP64 extra info field for uncompressed size */
|
|
1738
|
-
if (uncompressed_size >= UINT32_MAX)
|
|
1739
|
-
extra_data_size += 8;
|
|
1740
|
-
/* Add ZIP64 extra info field for compressed size */
|
|
1741
|
-
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1742
|
-
extra_data_size += 8;
|
|
1743
|
-
/* Add ZIP64 extra info field for relative offset to local file header of current file */
|
|
1744
|
-
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1745
|
-
extra_data_size += 8;
|
|
1746
|
-
|
|
1747
|
-
/* Add ZIP64 extra info header to central directory */
|
|
1748
|
-
if (extra_data_size > 0)
|
|
1749
|
-
{
|
|
1750
|
-
if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
|
|
1751
|
-
return ZIP_BADZIPFILE;
|
|
1752
|
-
|
|
1753
|
-
extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
|
|
1754
|
-
|
|
1755
|
-
zipWriteValueToMemoryAndMove(&extra_info, 0x0001, 2);
|
|
1756
|
-
zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
|
|
1757
|
-
|
|
1758
|
-
if (uncompressed_size >= UINT32_MAX)
|
|
1759
|
-
zipWriteValueToMemoryAndMove(&extra_info, uncompressed_size, 8);
|
|
1760
|
-
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1761
|
-
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.total_compressed, 8);
|
|
1762
|
-
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1763
|
-
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.pos_local_header, 8);
|
|
1764
|
-
|
|
1765
|
-
zi->ci.size_centralextrafree -= extra_data_size + 4;
|
|
1766
|
-
zi->ci.size_centralheader += extra_data_size + 4;
|
|
1767
|
-
zi->ci.size_centralextra += extra_data_size + 4;
|
|
1768
|
-
|
|
1769
|
-
zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
#ifdef HAVE_AES
|
|
1773
|
-
/* Write AES extra info header to central directory */
|
|
1774
|
-
if (zi->ci.method == AES_METHOD)
|
|
1775
|
-
{
|
|
1776
|
-
extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
|
|
1777
|
-
extra_data_size = 7;
|
|
1778
|
-
|
|
1779
|
-
if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
|
|
1780
|
-
return ZIP_BADZIPFILE;
|
|
1781
|
-
|
|
1782
|
-
zipWriteValueToMemoryAndMove(&extra_info, 0x9901, 2);
|
|
1783
|
-
zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
|
|
1784
|
-
zipWriteValueToMemoryAndMove(&extra_info, AES_VERSION, 2);
|
|
1785
|
-
zipWriteValueToMemoryAndMove(&extra_info, 'A', 1);
|
|
1786
|
-
zipWriteValueToMemoryAndMove(&extra_info, 'E', 1);
|
|
1787
|
-
zipWriteValueToMemoryAndMove(&extra_info, AES_ENCRYPTIONMODE, 1);
|
|
1788
|
-
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.compression_method, 2);
|
|
1789
|
-
|
|
1790
|
-
zi->ci.size_centralextrafree -= extra_data_size + 4;
|
|
1791
|
-
zi->ci.size_centralheader += extra_data_size + 4;
|
|
1792
|
-
zi->ci.size_centralextra += extra_data_size + 4;
|
|
1793
|
-
|
|
1794
|
-
zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
|
|
1795
|
-
}
|
|
1796
|
-
#endif
|
|
1797
|
-
/* Restore comment to correct position */
|
|
1798
|
-
for (i = 0; i < zi->ci.size_comment; i++)
|
|
1799
|
-
zi->ci.central_header[zi->ci.size_centralheader+i] =
|
|
1800
|
-
zi->ci.central_header[zi->ci.size_centralheader+zi->ci.size_centralextrafree+i];
|
|
1801
|
-
zi->ci.size_centralheader += zi->ci.size_comment;
|
|
1802
|
-
|
|
1803
|
-
if (err == ZIP_OK)
|
|
1804
|
-
err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, zi->ci.size_centralheader);
|
|
1805
|
-
|
|
1806
|
-
free(zi->ci.central_header);
|
|
1807
|
-
|
|
1808
|
-
zi->number_entry++;
|
|
1809
|
-
zi->in_opened_file_inzip = 0;
|
|
1810
|
-
|
|
1811
|
-
return err;
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
|
-
extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32)
|
|
1815
|
-
{
|
|
1816
|
-
return zipCloseFileInZipRaw64(file, uncompressed_size, crc32);
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
extern int ZEXPORT zipCloseFileInZip(zipFile file)
|
|
1820
|
-
{
|
|
1821
|
-
return zipCloseFileInZipRaw(file, 0, 0);
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
|
-
extern int ZEXPORT zipClose(zipFile file, const char *global_comment)
|
|
1825
|
-
{
|
|
1826
|
-
return zipClose_64(file, global_comment);
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment)
|
|
1830
|
-
{
|
|
1831
|
-
return zipClose2_64(file, global_comment, VERSIONMADEBY);
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby)
|
|
1835
|
-
{
|
|
1836
|
-
zip64_internal *zi = NULL;
|
|
1837
|
-
uint32_t size_centraldir = 0;
|
|
1838
|
-
uint16_t size_global_comment = 0;
|
|
1839
|
-
uint64_t centraldir_pos_inzip = 0;
|
|
1840
|
-
uint64_t pos = 0;
|
|
1841
|
-
uint64_t cd_pos = 0;
|
|
1842
|
-
uint32_t write = 0;
|
|
1843
|
-
int err = ZIP_OK;
|
|
1844
|
-
|
|
1845
|
-
if (file == NULL)
|
|
1846
|
-
return ZIP_PARAMERROR;
|
|
1847
|
-
zi = (zip64_internal*)file;
|
|
1848
|
-
|
|
1849
|
-
if (zi->in_opened_file_inzip == 1)
|
|
1850
|
-
err = zipCloseFileInZip(file);
|
|
1851
|
-
|
|
1852
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
1853
|
-
if (global_comment == NULL)
|
|
1854
|
-
global_comment = zi->globalcomment;
|
|
1855
|
-
#endif
|
|
1856
|
-
|
|
1857
|
-
if (zi->filestream != zi->filestream_with_CD)
|
|
1858
|
-
{
|
|
1859
|
-
if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)
|
|
1860
|
-
if (err == ZIP_OK)
|
|
1861
|
-
err = ZIP_ERRNO;
|
|
1862
|
-
if (zi->disk_size > 0)
|
|
1863
|
-
zi->number_disk_with_CD = zi->number_disk + 1;
|
|
1864
|
-
zi->filestream = zi->filestream_with_CD;
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1868
|
-
|
|
1869
|
-
if (err == ZIP_OK)
|
|
1870
|
-
{
|
|
1871
|
-
linkedlist_datablock_internal *ldi = zi->central_dir.first_block;
|
|
1872
|
-
while (ldi != NULL)
|
|
1873
|
-
{
|
|
1874
|
-
if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0))
|
|
1875
|
-
{
|
|
1876
|
-
write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block);
|
|
1877
|
-
if (write != ldi->filled_in_this_block)
|
|
1878
|
-
err = ZIP_ERRNO;
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
|
-
size_centraldir += ldi->filled_in_this_block;
|
|
1882
|
-
ldi = ldi->next_datablock;
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
|
|
1886
|
-
free_linkedlist(&(zi->central_dir));
|
|
1887
|
-
|
|
1888
|
-
pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1889
|
-
|
|
1890
|
-
/* Write the ZIP64 central directory header */
|
|
1891
|
-
if (pos >= UINT32_MAX || zi->number_entry > UINT32_MAX)
|
|
1892
|
-
{
|
|
1893
|
-
uint64_t zip64_eocd_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1894
|
-
uint32_t zip64_datasize = 44;
|
|
1895
|
-
|
|
1896
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDHEADERMAGIC, 4);
|
|
1897
|
-
|
|
1898
|
-
/* Size of this 'zip64 end of central directory' */
|
|
1899
|
-
if (err == ZIP_OK)
|
|
1900
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)zip64_datasize, 8);
|
|
1901
|
-
/* Version made by */
|
|
1902
|
-
if (err == ZIP_OK)
|
|
1903
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, version_madeby, 2);
|
|
1904
|
-
/* version needed */
|
|
1905
|
-
if (err == ZIP_OK)
|
|
1906
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2);
|
|
1907
|
-
/* Number of this disk */
|
|
1908
|
-
if (err == ZIP_OK)
|
|
1909
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1910
|
-
/* Number of the disk with the start of the central directory */
|
|
1911
|
-
if (err == ZIP_OK)
|
|
1912
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1913
|
-
/* Total number of entries in the central dir on this disk */
|
|
1914
|
-
if (err == ZIP_OK)
|
|
1915
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
|
|
1916
|
-
/* Total number of entries in the central dir */
|
|
1917
|
-
if (err == ZIP_OK)
|
|
1918
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
|
|
1919
|
-
/* Size of the central directory */
|
|
1920
|
-
if (err == ZIP_OK)
|
|
1921
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)size_centraldir, 8);
|
|
1922
|
-
|
|
1923
|
-
if (err == ZIP_OK)
|
|
1924
|
-
{
|
|
1925
|
-
/* Offset of start of central directory with respect to the starting disk number */
|
|
1926
|
-
cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1927
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
|
|
1928
|
-
}
|
|
1929
|
-
if (err == ZIP_OK)
|
|
1930
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDLOCHEADERMAGIC, 4);
|
|
1931
|
-
|
|
1932
|
-
/* Number of the disk with the start of the central directory */
|
|
1933
|
-
if (err == ZIP_OK)
|
|
1934
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1935
|
-
/* Relative offset to the Zip64EndOfCentralDirectory */
|
|
1936
|
-
if (err == ZIP_OK)
|
|
1937
|
-
{
|
|
1938
|
-
cd_pos = zip64_eocd_pos_inzip - zi->add_position_when_writting_offset;
|
|
1939
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
|
|
1940
|
-
}
|
|
1941
|
-
/* Number of the disk with the start of the central directory */
|
|
1942
|
-
if (err == ZIP_OK)
|
|
1943
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD + 1, 4);
|
|
1944
|
-
}
|
|
1945
|
-
|
|
1946
|
-
/* Write the central directory header */
|
|
1947
|
-
|
|
1948
|
-
/* Signature */
|
|
1949
|
-
if (err == ZIP_OK)
|
|
1950
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ENDHEADERMAGIC, 4);
|
|
1951
|
-
/* Number of this disk */
|
|
1952
|
-
if (err == ZIP_OK)
|
|
1953
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
|
|
1954
|
-
/* Number of the disk with the start of the central directory */
|
|
1955
|
-
if (err == ZIP_OK)
|
|
1956
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
|
|
1957
|
-
/* Total number of entries in the central dir on this disk */
|
|
1958
|
-
if (err == ZIP_OK)
|
|
1959
|
-
{
|
|
1960
|
-
if (zi->number_entry >= UINT16_MAX)
|
|
1961
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
|
|
1962
|
-
else
|
|
1963
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
|
|
1964
|
-
}
|
|
1965
|
-
/* Total number of entries in the central dir */
|
|
1966
|
-
if (err == ZIP_OK)
|
|
1967
|
-
{
|
|
1968
|
-
if (zi->number_entry >= UINT16_MAX)
|
|
1969
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
|
|
1970
|
-
else
|
|
1971
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
|
|
1972
|
-
}
|
|
1973
|
-
/* Size of the central directory */
|
|
1974
|
-
if (err == ZIP_OK)
|
|
1975
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_centraldir, 4);
|
|
1976
|
-
/* Offset of start of central directory with respect to the starting disk number */
|
|
1977
|
-
if (err == ZIP_OK)
|
|
1978
|
-
{
|
|
1979
|
-
cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1980
|
-
if (pos >= UINT32_MAX)
|
|
1981
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT32_MAX, 4);
|
|
1982
|
-
else
|
|
1983
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)cd_pos, 4);
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
/* Write global comment */
|
|
1987
|
-
|
|
1988
|
-
if (global_comment != NULL)
|
|
1989
|
-
size_global_comment = (uint16_t)strlen(global_comment);
|
|
1990
|
-
if (err == ZIP_OK)
|
|
1991
|
-
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_global_comment, 2);
|
|
1992
|
-
if (err == ZIP_OK && size_global_comment > 0)
|
|
1993
|
-
{
|
|
1994
|
-
if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment)
|
|
1995
|
-
err = ZIP_ERRNO;
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK))
|
|
1999
|
-
err = ZIP_ERRNO;
|
|
2000
|
-
|
|
2001
|
-
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
2002
|
-
TRYFREE(zi->globalcomment);
|
|
2003
|
-
#endif
|
|
2004
|
-
TRYFREE(zi);
|
|
2005
|
-
|
|
2006
|
-
return err;
|
|
2007
|
-
}
|
|
1
|
+
/* zip.c -- IO on .zip files using zlib
|
|
2
|
+
Version 1.2.0, September 16th, 2017
|
|
3
|
+
part of the MiniZip project
|
|
4
|
+
|
|
5
|
+
Copyright (C) 2010-2017 Nathan Moinvaziri
|
|
6
|
+
Modifications for AES, PKWARE disk spanning
|
|
7
|
+
https://github.com/nmoinvaz/minizip
|
|
8
|
+
Copyright (C) 2009-2010 Mathias Svensson
|
|
9
|
+
Modifications for Zip64 support
|
|
10
|
+
http://result42.com
|
|
11
|
+
Copyright (C) 1998-2010 Gilles Vollant
|
|
12
|
+
http://www.winimage.com/zLibDll/minizip.html
|
|
13
|
+
|
|
14
|
+
This program is distributed under the terms of the same license as zlib.
|
|
15
|
+
See the accompanying LICENSE file for the full text of the license.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
#include <stdlib.h>
|
|
20
|
+
#include <stdint.h>
|
|
21
|
+
#include <string.h>
|
|
22
|
+
#include <errno.h>
|
|
23
|
+
#include <assert.h>
|
|
24
|
+
|
|
25
|
+
#include "zlib.h"
|
|
26
|
+
#include "zip.h"
|
|
27
|
+
|
|
28
|
+
#ifdef HAVE_AES
|
|
29
|
+
# define AES_METHOD (99)
|
|
30
|
+
# define AES_PWVERIFYSIZE (2)
|
|
31
|
+
# define AES_AUTHCODESIZE (10)
|
|
32
|
+
# define AES_MAXSALTLENGTH (16)
|
|
33
|
+
# define AES_VERSION (0x0001)
|
|
34
|
+
# define AES_ENCRYPTIONMODE (0x03)
|
|
35
|
+
|
|
36
|
+
# include "aes.h"
|
|
37
|
+
# include "fileenc.h"
|
|
38
|
+
# include "prng.h"
|
|
39
|
+
#endif
|
|
40
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
41
|
+
# include <compression.h>
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
#ifndef NOCRYPT
|
|
45
|
+
# include "crypt.h"
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#define SIZEDATA_INDATABLOCK (4096-(4*4))
|
|
49
|
+
|
|
50
|
+
#define DISKHEADERMAGIC (0x08074b50)
|
|
51
|
+
#define LOCALHEADERMAGIC (0x04034b50)
|
|
52
|
+
#define CENTRALHEADERMAGIC (0x02014b50)
|
|
53
|
+
#define ENDHEADERMAGIC (0x06054b50)
|
|
54
|
+
#define ZIP64ENDHEADERMAGIC (0x06064b50)
|
|
55
|
+
#define ZIP64ENDLOCHEADERMAGIC (0x07064b50)
|
|
56
|
+
#define DATADESCRIPTORMAGIC (0x08074b50)
|
|
57
|
+
|
|
58
|
+
#define FLAG_LOCALHEADER_OFFSET (0x06)
|
|
59
|
+
#define CRC_LOCALHEADER_OFFSET (0x0e)
|
|
60
|
+
|
|
61
|
+
#define SIZECENTRALHEADER (0x2e) /* 46 */
|
|
62
|
+
#define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */
|
|
63
|
+
#define SIZECENTRALDIRITEM (0x2e)
|
|
64
|
+
#define SIZEZIPLOCALHEADER (0x1e)
|
|
65
|
+
|
|
66
|
+
#ifndef BUFREADCOMMENT
|
|
67
|
+
# define BUFREADCOMMENT (0x400)
|
|
68
|
+
#endif
|
|
69
|
+
#ifndef VERSIONMADEBY
|
|
70
|
+
# define VERSIONMADEBY (0x0) /* platform dependent */
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
#ifndef Z_BUFSIZE
|
|
74
|
+
# define Z_BUFSIZE (UINT16_MAX)
|
|
75
|
+
#endif
|
|
76
|
+
|
|
77
|
+
#ifndef ALLOC
|
|
78
|
+
# define ALLOC(size) (malloc(size))
|
|
79
|
+
#endif
|
|
80
|
+
#ifndef TRYFREE
|
|
81
|
+
# define TRYFREE(p) {if (p) free(p);}
|
|
82
|
+
#endif
|
|
83
|
+
|
|
84
|
+
/* NOT sure that this work on ALL platform */
|
|
85
|
+
#define MAKEULONG64(a, b) ((uint64_t)(((unsigned long)(a)) | ((uint64_t)((unsigned long)(b))) << 32))
|
|
86
|
+
|
|
87
|
+
#ifndef DEF_MEM_LEVEL
|
|
88
|
+
# if MAX_MEM_LEVEL >= 8
|
|
89
|
+
# define DEF_MEM_LEVEL 8
|
|
90
|
+
# else
|
|
91
|
+
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
|
92
|
+
# endif
|
|
93
|
+
#endif
|
|
94
|
+
|
|
95
|
+
const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
|
96
|
+
|
|
97
|
+
typedef struct linkedlist_datablock_internal_s
|
|
98
|
+
{
|
|
99
|
+
struct linkedlist_datablock_internal_s *next_datablock;
|
|
100
|
+
uint32_t avail_in_this_block;
|
|
101
|
+
uint32_t filled_in_this_block;
|
|
102
|
+
uint32_t unused; /* for future use and alignment */
|
|
103
|
+
uint8_t data[SIZEDATA_INDATABLOCK];
|
|
104
|
+
} linkedlist_datablock_internal;
|
|
105
|
+
|
|
106
|
+
typedef struct linkedlist_data_s
|
|
107
|
+
{
|
|
108
|
+
linkedlist_datablock_internal *first_block;
|
|
109
|
+
linkedlist_datablock_internal *last_block;
|
|
110
|
+
} linkedlist_data;
|
|
111
|
+
|
|
112
|
+
typedef struct
|
|
113
|
+
{
|
|
114
|
+
z_stream stream; /* zLib stream structure for inflate */
|
|
115
|
+
#ifdef HAVE_BZIP2
|
|
116
|
+
bz_stream bstream; /* bzLib stream structure for bziped */
|
|
117
|
+
#endif
|
|
118
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
119
|
+
compression_stream astream; /* libcompression stream structure */
|
|
120
|
+
#endif
|
|
121
|
+
#ifdef HAVE_AES
|
|
122
|
+
fcrypt_ctx aes_ctx;
|
|
123
|
+
prng_ctx aes_rng[1];
|
|
124
|
+
#endif
|
|
125
|
+
int stream_initialised; /* 1 is stream is initialized */
|
|
126
|
+
uint32_t pos_in_buffered_data; /* last written byte in buffered_data */
|
|
127
|
+
|
|
128
|
+
uint64_t pos_local_header; /* offset of the local header of the file currently writing */
|
|
129
|
+
char *central_header; /* central header data for the current file */
|
|
130
|
+
uint16_t size_centralextra;
|
|
131
|
+
uint16_t size_centralheader; /* size of the central header for cur file */
|
|
132
|
+
uint16_t size_centralextrafree; /* Extra bytes allocated to the central header but that are not used */
|
|
133
|
+
uint16_t size_comment;
|
|
134
|
+
uint16_t flag; /* flag of the file currently writing */
|
|
135
|
+
|
|
136
|
+
uint16_t method; /* compression method written to file.*/
|
|
137
|
+
uint16_t compression_method; /* compression method to use */
|
|
138
|
+
int raw; /* 1 for directly writing raw data */
|
|
139
|
+
uint8_t buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/
|
|
140
|
+
uint32_t dos_date;
|
|
141
|
+
uint32_t crc32;
|
|
142
|
+
int zip64; /* add ZIP64 extended information in the extra field */
|
|
143
|
+
uint32_t number_disk; /* number of current disk used for spanning ZIP */
|
|
144
|
+
uint64_t total_compressed;
|
|
145
|
+
uint64_t total_uncompressed;
|
|
146
|
+
#ifndef NOCRYPT
|
|
147
|
+
uint32_t keys[3]; /* keys defining the pseudo-random sequence */
|
|
148
|
+
const z_crc_t *pcrc_32_tab;
|
|
149
|
+
#endif
|
|
150
|
+
} curfile64_info;
|
|
151
|
+
|
|
152
|
+
typedef struct
|
|
153
|
+
{
|
|
154
|
+
zlib_filefunc64_32_def z_filefunc;
|
|
155
|
+
voidpf filestream; /* io structure of the zipfile */
|
|
156
|
+
voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */
|
|
157
|
+
linkedlist_data central_dir; /* datablock with central dir in construction*/
|
|
158
|
+
int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
|
|
159
|
+
int append; /* append mode */
|
|
160
|
+
curfile64_info ci; /* info on the file currently writing */
|
|
161
|
+
|
|
162
|
+
uint64_t add_position_when_writting_offset;
|
|
163
|
+
uint64_t number_entry;
|
|
164
|
+
uint64_t disk_size; /* size of each disk */
|
|
165
|
+
uint32_t number_disk; /* number of the current disk, used for spanning ZIP */
|
|
166
|
+
uint32_t number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP */
|
|
167
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
168
|
+
char *globalcomment;
|
|
169
|
+
#endif
|
|
170
|
+
} zip64_internal;
|
|
171
|
+
|
|
172
|
+
/* Allocate a new data block */
|
|
173
|
+
static linkedlist_datablock_internal *allocate_new_datablock(void)
|
|
174
|
+
{
|
|
175
|
+
linkedlist_datablock_internal *ldi = NULL;
|
|
176
|
+
|
|
177
|
+
ldi = (linkedlist_datablock_internal*)ALLOC(sizeof(linkedlist_datablock_internal));
|
|
178
|
+
|
|
179
|
+
if (ldi != NULL)
|
|
180
|
+
{
|
|
181
|
+
ldi->next_datablock = NULL;
|
|
182
|
+
ldi->filled_in_this_block = 0;
|
|
183
|
+
ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;
|
|
184
|
+
}
|
|
185
|
+
return ldi;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Free data block in linked list */
|
|
189
|
+
static void free_datablock(linkedlist_datablock_internal *ldi)
|
|
190
|
+
{
|
|
191
|
+
while (ldi != NULL)
|
|
192
|
+
{
|
|
193
|
+
linkedlist_datablock_internal *ldinext = ldi->next_datablock;
|
|
194
|
+
TRYFREE(ldi);
|
|
195
|
+
ldi = ldinext;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Initialize linked list */
|
|
200
|
+
static void init_linkedlist(linkedlist_data *ll)
|
|
201
|
+
{
|
|
202
|
+
ll->first_block = ll->last_block = NULL;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* Free entire linked list and all data blocks */
|
|
206
|
+
static void free_linkedlist(linkedlist_data *ll)
|
|
207
|
+
{
|
|
208
|
+
free_datablock(ll->first_block);
|
|
209
|
+
ll->first_block = ll->last_block = NULL;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Add data to linked list data block */
|
|
213
|
+
static int add_data_in_datablock(linkedlist_data *ll, const void *buf, uint32_t len)
|
|
214
|
+
{
|
|
215
|
+
linkedlist_datablock_internal *ldi = NULL;
|
|
216
|
+
const unsigned char *from_copy = NULL;
|
|
217
|
+
|
|
218
|
+
if (ll == NULL)
|
|
219
|
+
return ZIP_INTERNALERROR;
|
|
220
|
+
|
|
221
|
+
if (ll->last_block == NULL)
|
|
222
|
+
{
|
|
223
|
+
ll->first_block = ll->last_block = allocate_new_datablock();
|
|
224
|
+
if (ll->first_block == NULL)
|
|
225
|
+
return ZIP_INTERNALERROR;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
ldi = ll->last_block;
|
|
229
|
+
from_copy = (unsigned char*)buf;
|
|
230
|
+
|
|
231
|
+
while (len > 0)
|
|
232
|
+
{
|
|
233
|
+
uint32_t copy_this = 0;
|
|
234
|
+
uint32_t i = 0;
|
|
235
|
+
unsigned char *to_copy = NULL;
|
|
236
|
+
|
|
237
|
+
if (ldi->avail_in_this_block == 0)
|
|
238
|
+
{
|
|
239
|
+
ldi->next_datablock = allocate_new_datablock();
|
|
240
|
+
if (ldi->next_datablock == NULL)
|
|
241
|
+
return ZIP_INTERNALERROR;
|
|
242
|
+
ldi = ldi->next_datablock ;
|
|
243
|
+
ll->last_block = ldi;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (ldi->avail_in_this_block < len)
|
|
247
|
+
copy_this = ldi->avail_in_this_block;
|
|
248
|
+
else
|
|
249
|
+
copy_this = len;
|
|
250
|
+
|
|
251
|
+
to_copy = &(ldi->data[ldi->filled_in_this_block]);
|
|
252
|
+
|
|
253
|
+
for (i = 0; i < copy_this; i++)
|
|
254
|
+
*(to_copy+i) = *(from_copy+i);
|
|
255
|
+
|
|
256
|
+
ldi->filled_in_this_block += copy_this;
|
|
257
|
+
ldi->avail_in_this_block -= copy_this;
|
|
258
|
+
from_copy += copy_this;
|
|
259
|
+
len -= copy_this;
|
|
260
|
+
}
|
|
261
|
+
return ZIP_OK;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Inputs a long in LSB order to the given file: nbByte == 1, 2, 4 or 8 (byte, short or long, uint64_t) */
|
|
265
|
+
static int zipWriteValue(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
|
266
|
+
uint64_t x, uint32_t len)
|
|
267
|
+
{
|
|
268
|
+
unsigned char buf[8];
|
|
269
|
+
uint32_t n = 0;
|
|
270
|
+
|
|
271
|
+
for (n = 0; n < len; n++)
|
|
272
|
+
{
|
|
273
|
+
buf[n] = (unsigned char)(x & 0xff);
|
|
274
|
+
x >>= 8;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (x != 0)
|
|
278
|
+
{
|
|
279
|
+
/* Data overflow - hack for ZIP64 (X Roche) */
|
|
280
|
+
for (n = 0; n < len; n++)
|
|
281
|
+
{
|
|
282
|
+
buf[n] = 0xff;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, len) != len)
|
|
287
|
+
return ZIP_ERRNO;
|
|
288
|
+
|
|
289
|
+
return ZIP_OK;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static void zipWriteValueToMemory(void* dest, uint64_t x, uint32_t len)
|
|
293
|
+
{
|
|
294
|
+
unsigned char *buf = (unsigned char*)dest;
|
|
295
|
+
uint32_t n = 0;
|
|
296
|
+
|
|
297
|
+
for (n = 0; n < len; n++)
|
|
298
|
+
{
|
|
299
|
+
buf[n] = (unsigned char)(x & 0xff);
|
|
300
|
+
x >>= 8;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (x != 0)
|
|
304
|
+
{
|
|
305
|
+
/* data overflow - hack for ZIP64 */
|
|
306
|
+
for (n = 0; n < len; n++)
|
|
307
|
+
{
|
|
308
|
+
buf[n] = 0xff;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static void zipWriteValueToMemoryAndMove(unsigned char **dest_ptr, uint64_t x, uint32_t len)
|
|
314
|
+
{
|
|
315
|
+
zipWriteValueToMemory(*dest_ptr, x, len);
|
|
316
|
+
*dest_ptr += len;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
static int zipReadUInt8(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint8_t *value)
|
|
320
|
+
{
|
|
321
|
+
uint8_t c = 0;
|
|
322
|
+
if (ZREAD64(*pzlib_filefunc_def, filestream, &c, 1) == 1)
|
|
323
|
+
{
|
|
324
|
+
*value = (uint8_t)c;
|
|
325
|
+
return ZIP_OK;
|
|
326
|
+
}
|
|
327
|
+
if (ZERROR64(*pzlib_filefunc_def, filestream))
|
|
328
|
+
return ZIP_ERRNO;
|
|
329
|
+
return ZIP_EOF;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
static int zipReadUInt16(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint16_t *value)
|
|
333
|
+
{
|
|
334
|
+
uint16_t x = 0;
|
|
335
|
+
uint8_t c = 0;
|
|
336
|
+
int err = ZIP_OK;
|
|
337
|
+
|
|
338
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
339
|
+
x = (uint16_t)c;
|
|
340
|
+
if (err == ZIP_OK)
|
|
341
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
342
|
+
x += ((uint16_t)c) << 8;
|
|
343
|
+
|
|
344
|
+
if (err == ZIP_OK)
|
|
345
|
+
*value = x;
|
|
346
|
+
else
|
|
347
|
+
*value = 0;
|
|
348
|
+
return err;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
static int zipReadUInt32(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint32_t *value)
|
|
352
|
+
{
|
|
353
|
+
uint32_t x = 0;
|
|
354
|
+
uint8_t c = 0;
|
|
355
|
+
int err = ZIP_OK;
|
|
356
|
+
|
|
357
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
358
|
+
x = (uint32_t)c;
|
|
359
|
+
if (err == ZIP_OK)
|
|
360
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
361
|
+
x += ((uint32_t)c) << 8;
|
|
362
|
+
if (err == ZIP_OK)
|
|
363
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
364
|
+
x += ((uint32_t)c) << 16;
|
|
365
|
+
if (err == ZIP_OK)
|
|
366
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
367
|
+
x += ((uint32_t)c) << 24;
|
|
368
|
+
|
|
369
|
+
if (err == ZIP_OK)
|
|
370
|
+
*value = x;
|
|
371
|
+
else
|
|
372
|
+
*value = 0;
|
|
373
|
+
return err;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static int zipReadUInt64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uint64_t *value)
|
|
377
|
+
{
|
|
378
|
+
uint64_t x = 0;
|
|
379
|
+
uint8_t c = 0;
|
|
380
|
+
int err = ZIP_OK;
|
|
381
|
+
|
|
382
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
383
|
+
x = (uint64_t)c;
|
|
384
|
+
if (err == ZIP_OK)
|
|
385
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
386
|
+
x += ((uint64_t)c) << 8;
|
|
387
|
+
if (err == ZIP_OK)
|
|
388
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
389
|
+
x += ((uint64_t)c) << 16;
|
|
390
|
+
if (err == ZIP_OK)
|
|
391
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
392
|
+
x += ((uint64_t)c) << 24;
|
|
393
|
+
if (err == ZIP_OK)
|
|
394
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
395
|
+
x += ((uint64_t)c) << 32;
|
|
396
|
+
if (err == ZIP_OK)
|
|
397
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
398
|
+
x += ((uint64_t)c) << 40;
|
|
399
|
+
if (err == ZIP_OK)
|
|
400
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
401
|
+
x += ((uint64_t)c) << 48;
|
|
402
|
+
if (err == ZIP_OK)
|
|
403
|
+
err = zipReadUInt8(pzlib_filefunc_def, filestream, &c);
|
|
404
|
+
x += ((uint64_t)c) << 56;
|
|
405
|
+
|
|
406
|
+
if (err == ZIP_OK)
|
|
407
|
+
*value = x;
|
|
408
|
+
else
|
|
409
|
+
*value = 0;
|
|
410
|
+
|
|
411
|
+
return err;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* Gets the amount of bytes left to write to the current disk for spanning archives */
|
|
415
|
+
static void zipGetDiskSizeAvailable(zipFile file, uint64_t *size_available)
|
|
416
|
+
{
|
|
417
|
+
zip64_internal *zi = NULL;
|
|
418
|
+
uint64_t current_disk_size = 0;
|
|
419
|
+
|
|
420
|
+
zi = (zip64_internal*)file;
|
|
421
|
+
ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
|
|
422
|
+
current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
423
|
+
*size_available = zi->disk_size - current_disk_size;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* Goes to a specific disk number for spanning archives */
|
|
427
|
+
static int zipGoToSpecificDisk(zipFile file, uint32_t number_disk, int open_existing)
|
|
428
|
+
{
|
|
429
|
+
zip64_internal *zi = NULL;
|
|
430
|
+
int err = ZIP_OK;
|
|
431
|
+
|
|
432
|
+
zi = (zip64_internal*)file;
|
|
433
|
+
if (zi->disk_size == 0)
|
|
434
|
+
return err;
|
|
435
|
+
|
|
436
|
+
if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))
|
|
437
|
+
ZCLOSE64(zi->z_filefunc, zi->filestream);
|
|
438
|
+
|
|
439
|
+
zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ?
|
|
440
|
+
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :
|
|
441
|
+
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));
|
|
442
|
+
|
|
443
|
+
if (zi->filestream == NULL)
|
|
444
|
+
err = ZIP_ERRNO;
|
|
445
|
+
|
|
446
|
+
return err;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* Goes to the first disk in a spanned archive */
|
|
450
|
+
static int zipGoToFirstDisk(zipFile file)
|
|
451
|
+
{
|
|
452
|
+
zip64_internal *zi = NULL;
|
|
453
|
+
uint32_t number_disk_next = 0;
|
|
454
|
+
int err = ZIP_OK;
|
|
455
|
+
|
|
456
|
+
zi = (zip64_internal*)file;
|
|
457
|
+
|
|
458
|
+
if (zi->disk_size == 0)
|
|
459
|
+
return err;
|
|
460
|
+
number_disk_next = 0;
|
|
461
|
+
if (zi->number_disk_with_CD > 0)
|
|
462
|
+
number_disk_next = zi->number_disk_with_CD - 1;
|
|
463
|
+
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
|
464
|
+
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
|
465
|
+
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
|
466
|
+
if (err == ZIP_OK)
|
|
467
|
+
zi->number_disk = number_disk_next;
|
|
468
|
+
ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
|
|
469
|
+
return err;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/* Goes to the next disk in a spanned archive */
|
|
473
|
+
static int zipGoToNextDisk(zipFile file)
|
|
474
|
+
{
|
|
475
|
+
zip64_internal *zi = NULL;
|
|
476
|
+
uint64_t size_available_in_disk = 0;
|
|
477
|
+
uint32_t number_disk_next = 0;
|
|
478
|
+
int err = ZIP_OK;
|
|
479
|
+
|
|
480
|
+
zi = (zip64_internal*)file;
|
|
481
|
+
if (zi->disk_size == 0)
|
|
482
|
+
return err;
|
|
483
|
+
|
|
484
|
+
number_disk_next = zi->number_disk + 1;
|
|
485
|
+
|
|
486
|
+
do
|
|
487
|
+
{
|
|
488
|
+
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
|
489
|
+
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
|
490
|
+
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
|
491
|
+
if (err != ZIP_OK)
|
|
492
|
+
break;
|
|
493
|
+
zipGetDiskSizeAvailable(file, &size_available_in_disk);
|
|
494
|
+
zi->number_disk = number_disk_next;
|
|
495
|
+
zi->number_disk_with_CD = zi->number_disk + 1;
|
|
496
|
+
|
|
497
|
+
number_disk_next += 1;
|
|
498
|
+
}
|
|
499
|
+
while (size_available_in_disk <= 0);
|
|
500
|
+
|
|
501
|
+
return err;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/* Locate the Central directory of a zipfile (at the end, just before the global comment) */
|
|
505
|
+
static uint64_t zipSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
|
|
506
|
+
{
|
|
507
|
+
unsigned char *buf = NULL;
|
|
508
|
+
uint64_t file_size = 0;
|
|
509
|
+
uint64_t back_read = 4;
|
|
510
|
+
uint64_t max_back = UINT16_MAX; /* maximum size of global comment */
|
|
511
|
+
uint64_t pos_found = 0;
|
|
512
|
+
uint32_t read_size = 0;
|
|
513
|
+
uint64_t read_pos = 0;
|
|
514
|
+
uint32_t i = 0;
|
|
515
|
+
|
|
516
|
+
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
|
|
517
|
+
if (buf == NULL)
|
|
518
|
+
return 0;
|
|
519
|
+
|
|
520
|
+
if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
|
|
521
|
+
{
|
|
522
|
+
TRYFREE(buf);
|
|
523
|
+
return 0;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
file_size = ZTELL64(*pzlib_filefunc_def, filestream);
|
|
527
|
+
|
|
528
|
+
if (max_back > file_size)
|
|
529
|
+
max_back = file_size;
|
|
530
|
+
|
|
531
|
+
while (back_read < max_back)
|
|
532
|
+
{
|
|
533
|
+
if (back_read + BUFREADCOMMENT > max_back)
|
|
534
|
+
back_read = max_back;
|
|
535
|
+
else
|
|
536
|
+
back_read += BUFREADCOMMENT;
|
|
537
|
+
|
|
538
|
+
read_pos = file_size-back_read;
|
|
539
|
+
read_size = ((BUFREADCOMMENT+4) < (file_size - read_pos)) ?
|
|
540
|
+
(BUFREADCOMMENT+4) : (uint32_t)(file_size - read_pos);
|
|
541
|
+
|
|
542
|
+
if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
543
|
+
break;
|
|
544
|
+
if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)
|
|
545
|
+
break;
|
|
546
|
+
|
|
547
|
+
for (i = read_size-3; (i--) > 0;)
|
|
548
|
+
if ((*(buf+i)) == (ENDHEADERMAGIC & 0xff) &&
|
|
549
|
+
(*(buf+i+1)) == (ENDHEADERMAGIC >> 8 & 0xff) &&
|
|
550
|
+
(*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff) &&
|
|
551
|
+
(*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff))
|
|
552
|
+
{
|
|
553
|
+
pos_found = read_pos+i;
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (pos_found != 0)
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
TRYFREE(buf);
|
|
561
|
+
return pos_found;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
|
|
565
|
+
static uint64_t zipSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
|
566
|
+
const uint64_t endcentraloffset)
|
|
567
|
+
{
|
|
568
|
+
uint64_t offset = 0;
|
|
569
|
+
uint32_t value32 = 0;
|
|
570
|
+
|
|
571
|
+
/* Zip64 end of central directory locator */
|
|
572
|
+
if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
573
|
+
return 0;
|
|
574
|
+
|
|
575
|
+
/* Read locator signature */
|
|
576
|
+
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
577
|
+
return 0;
|
|
578
|
+
if (value32 != ZIP64ENDLOCHEADERMAGIC)
|
|
579
|
+
return 0;
|
|
580
|
+
/* Number of the disk with the start of the zip64 end of central directory */
|
|
581
|
+
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
582
|
+
return 0;
|
|
583
|
+
/* Relative offset of the zip64 end of central directory record */
|
|
584
|
+
if (zipReadUInt64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK)
|
|
585
|
+
return 0;
|
|
586
|
+
/* Total number of disks */
|
|
587
|
+
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
588
|
+
return 0;
|
|
589
|
+
/* Goto end of central directory record */
|
|
590
|
+
if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
591
|
+
return 0;
|
|
592
|
+
/* The signature */
|
|
593
|
+
if (zipReadUInt32(pzlib_filefunc_def, filestream, &value32) != ZIP_OK)
|
|
594
|
+
return 0;
|
|
595
|
+
if (value32 != ZIP64ENDHEADERMAGIC)
|
|
596
|
+
return 0;
|
|
597
|
+
|
|
598
|
+
return offset;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
extern zipFile ZEXPORT zipOpen4(const void *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
602
|
+
zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
|
|
603
|
+
{
|
|
604
|
+
zip64_internal ziinit = { 0 };
|
|
605
|
+
zip64_internal *zi = NULL;
|
|
606
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
607
|
+
uint64_t byte_before_the_zipfile = 0; /* byte before the zipfile, (>0 for sfx)*/
|
|
608
|
+
uint64_t size_central_dir = 0; /* size of the central directory */
|
|
609
|
+
uint64_t offset_central_dir = 0; /* offset of start of central directory */
|
|
610
|
+
uint64_t number_entry_CD = 0; /* total number of entries in the central dir */
|
|
611
|
+
uint64_t number_entry = 0;
|
|
612
|
+
uint64_t central_pos = 0;
|
|
613
|
+
uint64_t size_central_dir_to_read = 0;
|
|
614
|
+
uint16_t value16 = 0;
|
|
615
|
+
uint32_t value32 = 0;
|
|
616
|
+
uint16_t size_comment = 0;
|
|
617
|
+
size_t buf_size = SIZEDATA_INDATABLOCK;
|
|
618
|
+
void *buf_read = NULL;
|
|
619
|
+
#endif
|
|
620
|
+
int err = ZIP_OK;
|
|
621
|
+
int mode = 0;
|
|
622
|
+
|
|
623
|
+
if (pzlib_filefunc64_32_def == NULL)
|
|
624
|
+
fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
|
|
625
|
+
else
|
|
626
|
+
{
|
|
627
|
+
assert((pzlib_filefunc64_32_def->zopen32_file || pzlib_filefunc64_32_def->zfile_func64.zopen64_file) &&
|
|
628
|
+
(pzlib_filefunc64_32_def->zopendisk32_file || pzlib_filefunc64_32_def->zfile_func64.zopendisk64_file) &&
|
|
629
|
+
(pzlib_filefunc64_32_def->ztell32_file || pzlib_filefunc64_32_def->zfile_func64.ztell64_file) &&
|
|
630
|
+
(pzlib_filefunc64_32_def->zseek32_file || pzlib_filefunc64_32_def->zfile_func64.zseek64_file));
|
|
631
|
+
ziinit.z_filefunc = *pzlib_filefunc64_32_def;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (append == APPEND_STATUS_CREATE)
|
|
635
|
+
mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE);
|
|
636
|
+
else
|
|
637
|
+
mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING);
|
|
638
|
+
|
|
639
|
+
ziinit.filestream = ZOPEN64(ziinit.z_filefunc, path, mode);
|
|
640
|
+
if (ziinit.filestream == NULL)
|
|
641
|
+
return NULL;
|
|
642
|
+
|
|
643
|
+
if (append == APPEND_STATUS_CREATEAFTER)
|
|
644
|
+
{
|
|
645
|
+
/* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */
|
|
646
|
+
if (disk_size > 0)
|
|
647
|
+
return NULL;
|
|
648
|
+
|
|
649
|
+
ZSEEK64(ziinit.z_filefunc, ziinit.filestream, 0, SEEK_END);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
ziinit.filestream_with_CD = ziinit.filestream;
|
|
653
|
+
ziinit.append = append;
|
|
654
|
+
ziinit.disk_size = disk_size;
|
|
655
|
+
init_linkedlist(&(ziinit.central_dir));
|
|
656
|
+
|
|
657
|
+
zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
|
|
658
|
+
if (zi == NULL)
|
|
659
|
+
{
|
|
660
|
+
ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
|
|
661
|
+
return NULL;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
665
|
+
/* Add file in a zipfile */
|
|
666
|
+
ziinit.globalcomment = NULL;
|
|
667
|
+
if (append == APPEND_STATUS_ADDINZIP)
|
|
668
|
+
{
|
|
669
|
+
/* Read and Cache Central Directory Records */
|
|
670
|
+
central_pos = zipSearchCentralDir(&ziinit.z_filefunc, ziinit.filestream);
|
|
671
|
+
/* Disable to allow appending to empty ZIP archive (must be standard zip, not zip64)
|
|
672
|
+
if (central_pos == 0)
|
|
673
|
+
err = ZIP_ERRNO;
|
|
674
|
+
*/
|
|
675
|
+
|
|
676
|
+
if (err == ZIP_OK)
|
|
677
|
+
{
|
|
678
|
+
/* Read end of central directory info */
|
|
679
|
+
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
680
|
+
err = ZIP_ERRNO;
|
|
681
|
+
|
|
682
|
+
/* The signature, already checked */
|
|
683
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
684
|
+
err = ZIP_ERRNO;
|
|
685
|
+
/* Number of this disk */
|
|
686
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
687
|
+
err = ZIP_ERRNO;
|
|
688
|
+
ziinit.number_disk = value16;
|
|
689
|
+
/* Number of the disk with the start of the central directory */
|
|
690
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
691
|
+
err = ZIP_ERRNO;
|
|
692
|
+
ziinit.number_disk_with_CD = value16;
|
|
693
|
+
/* Total number of entries in the central dir on this disk */
|
|
694
|
+
number_entry = 0;
|
|
695
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
696
|
+
err = ZIP_ERRNO;
|
|
697
|
+
else
|
|
698
|
+
number_entry = value16;
|
|
699
|
+
/* Total number of entries in the central dir */
|
|
700
|
+
number_entry_CD = 0;
|
|
701
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
702
|
+
err = ZIP_ERRNO;
|
|
703
|
+
else
|
|
704
|
+
number_entry_CD = value16;
|
|
705
|
+
if (number_entry_CD!=number_entry)
|
|
706
|
+
err = ZIP_BADZIPFILE;
|
|
707
|
+
/* Size of the central directory */
|
|
708
|
+
size_central_dir = 0;
|
|
709
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
710
|
+
err = ZIP_ERRNO;
|
|
711
|
+
else
|
|
712
|
+
size_central_dir = value32;
|
|
713
|
+
/* Offset of start of central directory with respect to the starting disk number */
|
|
714
|
+
offset_central_dir = 0;
|
|
715
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
716
|
+
err = ZIP_ERRNO;
|
|
717
|
+
else
|
|
718
|
+
offset_central_dir = value32;
|
|
719
|
+
/* Zipfile global comment length */
|
|
720
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK)
|
|
721
|
+
err = ZIP_ERRNO;
|
|
722
|
+
|
|
723
|
+
if ((err == ZIP_OK) && ((number_entry_CD == UINT16_MAX) || (offset_central_dir == UINT32_MAX)))
|
|
724
|
+
{
|
|
725
|
+
/* Format should be Zip64, as the central directory or file size is too large */
|
|
726
|
+
central_pos = zipSearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos);
|
|
727
|
+
|
|
728
|
+
if (central_pos)
|
|
729
|
+
{
|
|
730
|
+
uint64_t sizeEndOfCentralDirectory;
|
|
731
|
+
|
|
732
|
+
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
733
|
+
err = ZIP_ERRNO;
|
|
734
|
+
|
|
735
|
+
/* The signature, already checked */
|
|
736
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &value32) != ZIP_OK)
|
|
737
|
+
err = ZIP_ERRNO;
|
|
738
|
+
/* Size of zip64 end of central directory record */
|
|
739
|
+
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK)
|
|
740
|
+
err = ZIP_ERRNO;
|
|
741
|
+
/* Version made by */
|
|
742
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
743
|
+
err = ZIP_ERRNO;
|
|
744
|
+
/* Version needed to extract */
|
|
745
|
+
if (zipReadUInt16(&ziinit.z_filefunc, ziinit.filestream, &value16) != ZIP_OK)
|
|
746
|
+
err = ZIP_ERRNO;
|
|
747
|
+
/* Number of this disk */
|
|
748
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)
|
|
749
|
+
err = ZIP_ERRNO;
|
|
750
|
+
/* Number of the disk with the start of the central directory */
|
|
751
|
+
if (zipReadUInt32(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)
|
|
752
|
+
err = ZIP_ERRNO;
|
|
753
|
+
/* Total number of entries in the central directory on this disk */
|
|
754
|
+
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK)
|
|
755
|
+
err = ZIP_ERRNO;
|
|
756
|
+
/* Total number of entries in the central directory */
|
|
757
|
+
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK)
|
|
758
|
+
err = ZIP_ERRNO;
|
|
759
|
+
if (number_entry_CD!=number_entry)
|
|
760
|
+
err = ZIP_BADZIPFILE;
|
|
761
|
+
/* Size of the central directory */
|
|
762
|
+
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK)
|
|
763
|
+
err = ZIP_ERRNO;
|
|
764
|
+
/* Offset of start of central directory with respect to the starting disk number */
|
|
765
|
+
if (zipReadUInt64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK)
|
|
766
|
+
err = ZIP_ERRNO;
|
|
767
|
+
}
|
|
768
|
+
else
|
|
769
|
+
err = ZIP_BADZIPFILE;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if ((err == ZIP_OK) && (central_pos < offset_central_dir + size_central_dir))
|
|
774
|
+
err = ZIP_BADZIPFILE;
|
|
775
|
+
|
|
776
|
+
if ((err == ZIP_OK) && (size_comment > 0))
|
|
777
|
+
{
|
|
778
|
+
ziinit.globalcomment = (char*)ALLOC(size_comment+1);
|
|
779
|
+
if (ziinit.globalcomment)
|
|
780
|
+
{
|
|
781
|
+
if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment) != size_comment)
|
|
782
|
+
err = ZIP_ERRNO;
|
|
783
|
+
else
|
|
784
|
+
ziinit.globalcomment[size_comment] = 0;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
if (err != ZIP_OK)
|
|
789
|
+
{
|
|
790
|
+
ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);
|
|
791
|
+
TRYFREE(ziinit.globalcomment);
|
|
792
|
+
TRYFREE(zi);
|
|
793
|
+
return NULL;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
|
|
797
|
+
ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
|
|
798
|
+
|
|
799
|
+
/* Store central directory in memory */
|
|
800
|
+
size_central_dir_to_read = size_central_dir;
|
|
801
|
+
buf_size = SIZEDATA_INDATABLOCK;
|
|
802
|
+
buf_read = (void*)ALLOC(buf_size);
|
|
803
|
+
|
|
804
|
+
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
|
|
805
|
+
offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
806
|
+
err = ZIP_ERRNO;
|
|
807
|
+
|
|
808
|
+
while ((size_central_dir_to_read > 0) && (err == ZIP_OK))
|
|
809
|
+
{
|
|
810
|
+
uint64_t read_this = SIZEDATA_INDATABLOCK;
|
|
811
|
+
if (read_this > size_central_dir_to_read)
|
|
812
|
+
read_this = size_central_dir_to_read;
|
|
813
|
+
|
|
814
|
+
if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uint32_t)read_this) != read_this)
|
|
815
|
+
err = ZIP_ERRNO;
|
|
816
|
+
|
|
817
|
+
if (err == ZIP_OK)
|
|
818
|
+
err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uint32_t)read_this);
|
|
819
|
+
|
|
820
|
+
size_central_dir_to_read -= read_this;
|
|
821
|
+
}
|
|
822
|
+
TRYFREE(buf_read);
|
|
823
|
+
|
|
824
|
+
ziinit.number_entry = number_entry_CD;
|
|
825
|
+
|
|
826
|
+
if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,
|
|
827
|
+
offset_central_dir+byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
|
828
|
+
err = ZIP_ERRNO;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
if (globalcomment)
|
|
832
|
+
*globalcomment = ziinit.globalcomment;
|
|
833
|
+
#endif
|
|
834
|
+
|
|
835
|
+
if (err != ZIP_OK)
|
|
836
|
+
{
|
|
837
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
838
|
+
TRYFREE(ziinit.globalcomment);
|
|
839
|
+
#endif
|
|
840
|
+
TRYFREE(zi);
|
|
841
|
+
return NULL;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
*zi = ziinit;
|
|
845
|
+
zipGoToFirstDisk((zipFile)zi);
|
|
846
|
+
return(zipFile)zi;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment,
|
|
850
|
+
zlib_filefunc_def *pzlib_filefunc32_def)
|
|
851
|
+
{
|
|
852
|
+
if (pzlib_filefunc32_def != NULL)
|
|
853
|
+
{
|
|
854
|
+
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
855
|
+
fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
|
|
856
|
+
return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
857
|
+
}
|
|
858
|
+
return zipOpen4(path, append, 0, globalcomment, NULL);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment,
|
|
862
|
+
zlib_filefunc64_def *pzlib_filefunc_def)
|
|
863
|
+
{
|
|
864
|
+
if (pzlib_filefunc_def != NULL)
|
|
865
|
+
{
|
|
866
|
+
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
867
|
+
zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
|
|
868
|
+
return zipOpen4(path, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
869
|
+
}
|
|
870
|
+
return zipOpen4(path, append, 0, globalcomment, NULL);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
extern zipFile ZEXPORT zipOpen3(const char *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
874
|
+
zlib_filefunc_def *pzlib_filefunc32_def)
|
|
875
|
+
{
|
|
876
|
+
if (pzlib_filefunc32_def != NULL)
|
|
877
|
+
{
|
|
878
|
+
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
879
|
+
fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
|
|
880
|
+
return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
881
|
+
}
|
|
882
|
+
return zipOpen4(path, append, disk_size, globalcomment, NULL);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
extern zipFile ZEXPORT zipOpen3_64(const void *path, int append, uint64_t disk_size, const char **globalcomment,
|
|
886
|
+
zlib_filefunc64_def *pzlib_filefunc_def)
|
|
887
|
+
{
|
|
888
|
+
if (pzlib_filefunc_def != NULL)
|
|
889
|
+
{
|
|
890
|
+
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill = { 0 };
|
|
891
|
+
zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
|
|
892
|
+
return zipOpen4(path, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
|
893
|
+
}
|
|
894
|
+
return zipOpen4(path, append, disk_size, globalcomment, NULL);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
extern zipFile ZEXPORT zipOpen(const char *path, int append)
|
|
898
|
+
{
|
|
899
|
+
return zipOpen3((const void*)path, append, 0, NULL, NULL);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
extern zipFile ZEXPORT zipOpen64(const void *path, int append)
|
|
903
|
+
{
|
|
904
|
+
return zipOpen3(path, append, 0, NULL, NULL);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file,
|
|
908
|
+
const char *filename,
|
|
909
|
+
const zip_fileinfo *zipfi,
|
|
910
|
+
const void *extrafield_local,
|
|
911
|
+
uint16_t size_extrafield_local,
|
|
912
|
+
const void *extrafield_global,
|
|
913
|
+
uint16_t size_extrafield_global,
|
|
914
|
+
const char *comment,
|
|
915
|
+
uint16_t flag_base,
|
|
916
|
+
int zip64,
|
|
917
|
+
uint16_t method,
|
|
918
|
+
int level,
|
|
919
|
+
int raw,
|
|
920
|
+
int windowBits,
|
|
921
|
+
int memLevel,
|
|
922
|
+
int strategy,
|
|
923
|
+
const char *password,
|
|
924
|
+
int aes,
|
|
925
|
+
uint16_t version_madeby)
|
|
926
|
+
{
|
|
927
|
+
zip64_internal *zi = NULL;
|
|
928
|
+
uint64_t size_available = 0;
|
|
929
|
+
uint64_t size_needed = 0;
|
|
930
|
+
uint16_t size_filename = 0;
|
|
931
|
+
uint16_t size_comment = 0;
|
|
932
|
+
uint16_t i = 0;
|
|
933
|
+
unsigned char *central_dir = NULL;
|
|
934
|
+
int err = ZIP_OK;
|
|
935
|
+
|
|
936
|
+
#ifdef NOCRYPT
|
|
937
|
+
if (password != NULL)
|
|
938
|
+
return ZIP_PARAMERROR;
|
|
939
|
+
#endif
|
|
940
|
+
|
|
941
|
+
if (file == NULL)
|
|
942
|
+
return ZIP_PARAMERROR;
|
|
943
|
+
|
|
944
|
+
if ((method != 0) &&
|
|
945
|
+
#ifdef HAVE_BZIP2
|
|
946
|
+
(method != Z_BZIP2ED) &&
|
|
947
|
+
#endif
|
|
948
|
+
(method != Z_DEFLATED))
|
|
949
|
+
return ZIP_PARAMERROR;
|
|
950
|
+
|
|
951
|
+
zi = (zip64_internal*)file;
|
|
952
|
+
|
|
953
|
+
if (zi->in_opened_file_inzip == 1)
|
|
954
|
+
{
|
|
955
|
+
err = zipCloseFileInZip (file);
|
|
956
|
+
if (err != ZIP_OK)
|
|
957
|
+
return err;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
if (filename == NULL)
|
|
961
|
+
filename = "-";
|
|
962
|
+
if (comment != NULL)
|
|
963
|
+
size_comment = (uint16_t)strlen(comment);
|
|
964
|
+
|
|
965
|
+
size_filename = (uint16_t)strlen(filename);
|
|
966
|
+
|
|
967
|
+
if (zipfi == NULL)
|
|
968
|
+
zi->ci.dos_date = 0;
|
|
969
|
+
else
|
|
970
|
+
{
|
|
971
|
+
if (zipfi->dos_date != 0)
|
|
972
|
+
zi->ci.dos_date = zipfi->dos_date;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
zi->ci.method = method;
|
|
976
|
+
zi->ci.compression_method = method;
|
|
977
|
+
zi->ci.raw = raw;
|
|
978
|
+
zi->ci.flag = flag_base | 8;
|
|
979
|
+
if ((level == 8) || (level == 9))
|
|
980
|
+
zi->ci.flag |= 2;
|
|
981
|
+
if (level == 2)
|
|
982
|
+
zi->ci.flag |= 4;
|
|
983
|
+
if (level == 1)
|
|
984
|
+
zi->ci.flag |= 6;
|
|
985
|
+
|
|
986
|
+
if (password != NULL)
|
|
987
|
+
{
|
|
988
|
+
zi->ci.flag |= 1;
|
|
989
|
+
#ifdef HAVE_AES
|
|
990
|
+
if (aes)
|
|
991
|
+
zi->ci.method = AES_METHOD;
|
|
992
|
+
#endif
|
|
993
|
+
}
|
|
994
|
+
else
|
|
995
|
+
{
|
|
996
|
+
zi->ci.flag &= ~1;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
if (zi->disk_size > 0)
|
|
1000
|
+
{
|
|
1001
|
+
if ((zi->number_disk == 0) && (zi->number_entry == 0))
|
|
1002
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DISKHEADERMAGIC, 4);
|
|
1003
|
+
|
|
1004
|
+
/* Make sure enough space available on current disk for local header */
|
|
1005
|
+
zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
|
1006
|
+
size_needed = 30 + size_filename + size_extrafield_local;
|
|
1007
|
+
#ifdef HAVE_AES
|
|
1008
|
+
if (zi->ci.method == AES_METHOD)
|
|
1009
|
+
size_needed += 11;
|
|
1010
|
+
#endif
|
|
1011
|
+
if (size_available < size_needed)
|
|
1012
|
+
zipGoToNextDisk((zipFile)zi);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
zi->ci.zip64 = zip64;
|
|
1016
|
+
|
|
1017
|
+
zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1018
|
+
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1019
|
+
zi->ci.zip64 = 1;
|
|
1020
|
+
|
|
1021
|
+
zi->ci.size_comment = size_comment;
|
|
1022
|
+
zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global;
|
|
1023
|
+
zi->ci.size_centralextra = size_extrafield_global;
|
|
1024
|
+
zi->ci.size_centralextrafree = 32; /* Extra space reserved for ZIP64 extra info */
|
|
1025
|
+
#ifdef HAVE_AES
|
|
1026
|
+
if (zi->ci.method == AES_METHOD)
|
|
1027
|
+
zi->ci.size_centralextrafree += 11; /* Extra space reserved for AES extra info */
|
|
1028
|
+
#endif
|
|
1029
|
+
zi->ci.central_header = (char*)ALLOC((uint32_t)zi->ci.size_centralheader + zi->ci.size_centralextrafree + size_comment);
|
|
1030
|
+
zi->ci.number_disk = zi->number_disk;
|
|
1031
|
+
|
|
1032
|
+
/* Write central directory header */
|
|
1033
|
+
/* https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT */
|
|
1034
|
+
central_dir = (unsigned char*)zi->ci.central_header;
|
|
1035
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)CENTRALHEADERMAGIC, 4);
|
|
1036
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, version_madeby, 2);
|
|
1037
|
+
if (zi->ci.zip64)
|
|
1038
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)45, 2);
|
|
1039
|
+
else
|
|
1040
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)20, 2);
|
|
1041
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.flag, 2);
|
|
1042
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.method, 2);
|
|
1043
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, zi->ci.dos_date, 4);
|
|
1044
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*crc*/
|
|
1045
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*compr size*/
|
|
1046
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4); /*uncompr size*/
|
|
1047
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, size_filename, 2);
|
|
1048
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, size_extrafield_global, 2);
|
|
1049
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, size_comment, 2);
|
|
1050
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)zi->ci.number_disk, 2); /*disk nm start*/
|
|
1051
|
+
|
|
1052
|
+
if (zipfi == NULL)
|
|
1053
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint16_t)0, 2);
|
|
1054
|
+
else
|
|
1055
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->internal_fa, 2);
|
|
1056
|
+
if (zipfi == NULL)
|
|
1057
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, (uint32_t)0, 4);
|
|
1058
|
+
else
|
|
1059
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, zipfi->external_fa, 4);
|
|
1060
|
+
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1061
|
+
zipWriteValueToMemoryAndMove(¢ral_dir, UINT32_MAX, 4);
|
|
1062
|
+
else
|
|
1063
|
+
zipWriteValueToMemoryAndMove(¢ral_dir,
|
|
1064
|
+
(uint32_t)(zi->ci.pos_local_header - zi->add_position_when_writting_offset), 4);
|
|
1065
|
+
|
|
1066
|
+
for (i = 0; i < size_filename; i++)
|
|
1067
|
+
zi->ci.central_header[SIZECENTRALHEADER+i] = filename[i];
|
|
1068
|
+
for (i = 0; i < size_extrafield_global; i++)
|
|
1069
|
+
zi->ci.central_header[SIZECENTRALHEADER+size_filename+i] =
|
|
1070
|
+
((const char*)extrafield_global)[i];
|
|
1071
|
+
|
|
1072
|
+
/* Store comment at the end for later repositioning */
|
|
1073
|
+
for (i = 0; i < size_comment; i++)
|
|
1074
|
+
zi->ci.central_header[zi->ci.size_centralheader+
|
|
1075
|
+
zi->ci.size_centralextrafree+i] = comment[i];
|
|
1076
|
+
|
|
1077
|
+
if (zi->ci.central_header == NULL)
|
|
1078
|
+
return ZIP_INTERNALERROR;
|
|
1079
|
+
|
|
1080
|
+
/* Write the local header */
|
|
1081
|
+
if (err == ZIP_OK)
|
|
1082
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)LOCALHEADERMAGIC, 4);
|
|
1083
|
+
|
|
1084
|
+
if (err == ZIP_OK)
|
|
1085
|
+
{
|
|
1086
|
+
if (zi->ci.zip64)
|
|
1087
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2); /* version needed to extract */
|
|
1088
|
+
else
|
|
1089
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)20, 2); /* version needed to extract */
|
|
1090
|
+
}
|
|
1091
|
+
if (err == ZIP_OK)
|
|
1092
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.flag, 2);
|
|
1093
|
+
if (err == ZIP_OK)
|
|
1094
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.method, 2);
|
|
1095
|
+
if (err == ZIP_OK)
|
|
1096
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.dos_date, 4);
|
|
1097
|
+
|
|
1098
|
+
/* CRC & compressed size & uncompressed size is in data descriptor */
|
|
1099
|
+
if (err == ZIP_OK)
|
|
1100
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* crc 32, unknown */
|
|
1101
|
+
if (err == ZIP_OK)
|
|
1102
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* compressed size, unknown */
|
|
1103
|
+
if (err == ZIP_OK)
|
|
1104
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)0, 4); /* uncompressed size, unknown */
|
|
1105
|
+
if (err == ZIP_OK)
|
|
1106
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_filename, 2);
|
|
1107
|
+
if (err == ZIP_OK)
|
|
1108
|
+
{
|
|
1109
|
+
uint64_t size_extrafield = size_extrafield_local;
|
|
1110
|
+
#ifdef HAVE_AES
|
|
1111
|
+
if (zi->ci.method == AES_METHOD)
|
|
1112
|
+
size_extrafield += 11;
|
|
1113
|
+
#endif
|
|
1114
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)size_extrafield, 2);
|
|
1115
|
+
}
|
|
1116
|
+
if ((err == ZIP_OK) && (size_filename > 0))
|
|
1117
|
+
{
|
|
1118
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename)
|
|
1119
|
+
err = ZIP_ERRNO;
|
|
1120
|
+
}
|
|
1121
|
+
if ((err == ZIP_OK) && (size_extrafield_local > 0))
|
|
1122
|
+
{
|
|
1123
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
|
|
1124
|
+
err = ZIP_ERRNO;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
#ifdef HAVE_AES
|
|
1128
|
+
/* Write the AES extended info */
|
|
1129
|
+
if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD))
|
|
1130
|
+
{
|
|
1131
|
+
int headerid = 0x9901;
|
|
1132
|
+
short datasize = 7;
|
|
1133
|
+
|
|
1134
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, headerid, 2);
|
|
1135
|
+
if (err == ZIP_OK)
|
|
1136
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, datasize, 2);
|
|
1137
|
+
if (err == ZIP_OK)
|
|
1138
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2);
|
|
1139
|
+
if (err == ZIP_OK)
|
|
1140
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'A', 1);
|
|
1141
|
+
if (err == ZIP_OK)
|
|
1142
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, 'E', 1);
|
|
1143
|
+
if (err == ZIP_OK)
|
|
1144
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1);
|
|
1145
|
+
if (err == ZIP_OK)
|
|
1146
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2);
|
|
1147
|
+
}
|
|
1148
|
+
#endif
|
|
1149
|
+
|
|
1150
|
+
zi->ci.crc32 = 0;
|
|
1151
|
+
zi->ci.stream_initialised = 0;
|
|
1152
|
+
zi->ci.pos_in_buffered_data = 0;
|
|
1153
|
+
zi->ci.total_compressed = 0;
|
|
1154
|
+
zi->ci.total_uncompressed = 0;
|
|
1155
|
+
|
|
1156
|
+
#ifdef HAVE_BZIP2
|
|
1157
|
+
zi->ci.bstream.avail_in = (uint16_t)0;
|
|
1158
|
+
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1159
|
+
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1160
|
+
zi->ci.bstream.total_in_hi32 = 0;
|
|
1161
|
+
zi->ci.bstream.total_in_lo32 = 0;
|
|
1162
|
+
zi->ci.bstream.total_out_hi32 = 0;
|
|
1163
|
+
zi->ci.bstream.total_out_lo32 = 0;
|
|
1164
|
+
#endif
|
|
1165
|
+
|
|
1166
|
+
zi->ci.stream.avail_in = (uint16_t)0;
|
|
1167
|
+
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1168
|
+
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1169
|
+
zi->ci.stream.total_in = 0;
|
|
1170
|
+
zi->ci.stream.total_out = 0;
|
|
1171
|
+
zi->ci.stream.data_type = Z_BINARY;
|
|
1172
|
+
|
|
1173
|
+
if ((err == ZIP_OK) && (!zi->ci.raw))
|
|
1174
|
+
{
|
|
1175
|
+
if (method == Z_DEFLATED)
|
|
1176
|
+
{
|
|
1177
|
+
zi->ci.stream.zalloc = (alloc_func)0;
|
|
1178
|
+
zi->ci.stream.zfree = (free_func)0;
|
|
1179
|
+
zi->ci.stream.opaque = (voidpf)zi;
|
|
1180
|
+
|
|
1181
|
+
if (windowBits > 0)
|
|
1182
|
+
windowBits = -windowBits;
|
|
1183
|
+
|
|
1184
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
1185
|
+
err = compression_stream_init(&zi->ci.astream, COMPRESSION_STREAM_ENCODE, COMPRESSION_ZLIB);
|
|
1186
|
+
if (err == COMPRESSION_STATUS_ERROR)
|
|
1187
|
+
err = Z_ERRNO;
|
|
1188
|
+
else
|
|
1189
|
+
err = Z_OK;
|
|
1190
|
+
#else
|
|
1191
|
+
err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
|
|
1192
|
+
#endif
|
|
1193
|
+
if (err == Z_OK)
|
|
1194
|
+
zi->ci.stream_initialised = Z_DEFLATED;
|
|
1195
|
+
}
|
|
1196
|
+
else if (method == Z_BZIP2ED)
|
|
1197
|
+
{
|
|
1198
|
+
#ifdef HAVE_BZIP2
|
|
1199
|
+
zi->ci.bstream.bzalloc = 0;
|
|
1200
|
+
zi->ci.bstream.bzfree = 0;
|
|
1201
|
+
zi->ci.bstream.opaque = (voidpf)0;
|
|
1202
|
+
|
|
1203
|
+
err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35);
|
|
1204
|
+
if (err == BZ_OK)
|
|
1205
|
+
zi->ci.stream_initialised = Z_BZIP2ED;
|
|
1206
|
+
#endif
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
#ifndef NOCRYPT
|
|
1211
|
+
if ((err == Z_OK) && (password != NULL))
|
|
1212
|
+
{
|
|
1213
|
+
#ifdef HAVE_AES
|
|
1214
|
+
if (zi->ci.method == AES_METHOD)
|
|
1215
|
+
{
|
|
1216
|
+
unsigned char passverify[AES_PWVERIFYSIZE];
|
|
1217
|
+
unsigned char saltvalue[AES_MAXSALTLENGTH];
|
|
1218
|
+
uint16_t saltlength = 0;
|
|
1219
|
+
|
|
1220
|
+
if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3))
|
|
1221
|
+
return Z_ERRNO;
|
|
1222
|
+
|
|
1223
|
+
saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE);
|
|
1224
|
+
|
|
1225
|
+
prng_init(cryptrand, zi->ci.aes_rng);
|
|
1226
|
+
prng_rand(saltvalue, saltlength, zi->ci.aes_rng);
|
|
1227
|
+
prng_end(zi->ci.aes_rng);
|
|
1228
|
+
|
|
1229
|
+
fcrypt_init(AES_ENCRYPTIONMODE, (uint8_t *)password, (uint32_t)strlen(password), saltvalue, passverify, &zi->ci.aes_ctx);
|
|
1230
|
+
|
|
1231
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, saltvalue, saltlength) != saltlength)
|
|
1232
|
+
err = ZIP_ERRNO;
|
|
1233
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)
|
|
1234
|
+
err = ZIP_ERRNO;
|
|
1235
|
+
|
|
1236
|
+
zi->ci.total_compressed += saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE;
|
|
1237
|
+
}
|
|
1238
|
+
else
|
|
1239
|
+
#endif
|
|
1240
|
+
{
|
|
1241
|
+
unsigned char buf_head[RAND_HEAD_LEN];
|
|
1242
|
+
uint32_t size_head = 0;
|
|
1243
|
+
uint8_t verify1 = 0;
|
|
1244
|
+
uint8_t verify2 = 0;
|
|
1245
|
+
|
|
1246
|
+
zi->ci.pcrc_32_tab = get_crc_table();
|
|
1247
|
+
|
|
1248
|
+
/*
|
|
1249
|
+
Info-ZIP modification to ZipCrypto format:
|
|
1250
|
+
If bit 3 of the general purpose bit flag is set, it uses high byte of 16-bit File Time.
|
|
1251
|
+
*/
|
|
1252
|
+
verify1 = (uint8_t)((zi->ci.dos_date >> 16) & 0xff);
|
|
1253
|
+
verify2 = (uint8_t)((zi->ci.dos_date >> 8) & 0xff);
|
|
1254
|
+
|
|
1255
|
+
size_head = crypthead(password, buf_head, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, verify1, verify2);
|
|
1256
|
+
zi->ci.total_compressed += size_head;
|
|
1257
|
+
|
|
1258
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, buf_head, size_head) != size_head)
|
|
1259
|
+
err = ZIP_ERRNO;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
#endif
|
|
1263
|
+
|
|
1264
|
+
if (err == Z_OK)
|
|
1265
|
+
zi->in_opened_file_inzip = 1;
|
|
1266
|
+
return err;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1270
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1271
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
|
1272
|
+
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
|
|
1273
|
+
{
|
|
1274
|
+
uint8_t aes = 0;
|
|
1275
|
+
#ifdef HAVE_AES
|
|
1276
|
+
aes = 1;
|
|
1277
|
+
#endif
|
|
1278
|
+
return zipOpenNewFileInZip5(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
|
|
1279
|
+
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
|
|
1280
|
+
version_madeby);
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1284
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1285
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1286
|
+
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base)
|
|
1287
|
+
{
|
|
1288
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1289
|
+
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
|
|
1290
|
+
strategy, password, crc_for_crypting, version_madeby, flag_base, 0);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1294
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1295
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1296
|
+
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting)
|
|
1297
|
+
{
|
|
1298
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1299
|
+
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,
|
|
1300
|
+
strategy, password, crc_for_crypting, VERSIONMADEBY, 0, 0);
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1304
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1305
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
|
1306
|
+
int memLevel, int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, int zip64)
|
|
1307
|
+
{
|
|
1308
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1309
|
+
extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy,
|
|
1310
|
+
password, crc_for_crypting, VERSIONMADEBY, 0, zip64);
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1314
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1315
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw)
|
|
1316
|
+
{
|
|
1317
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1318
|
+
extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1319
|
+
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1323
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1324
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int zip64)
|
|
1325
|
+
{
|
|
1326
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1327
|
+
extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1328
|
+
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1332
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1333
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int zip64)
|
|
1334
|
+
{
|
|
1335
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1336
|
+
extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1337
|
+
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
1341
|
+
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
1342
|
+
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level)
|
|
1343
|
+
{
|
|
1344
|
+
return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,
|
|
1345
|
+
extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
|
|
1346
|
+
Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/* Flushes the write buffer to disk */
|
|
1350
|
+
static int zipFlushWriteBuffer(zip64_internal *zi)
|
|
1351
|
+
{
|
|
1352
|
+
uint64_t size_available = 0;
|
|
1353
|
+
uint32_t written = 0;
|
|
1354
|
+
uint32_t total_written = 0;
|
|
1355
|
+
uint32_t write = 0;
|
|
1356
|
+
uint32_t max_write = 0;
|
|
1357
|
+
int err = ZIP_OK;
|
|
1358
|
+
|
|
1359
|
+
if ((zi->ci.flag & 1) != 0)
|
|
1360
|
+
{
|
|
1361
|
+
#ifndef NOCRYPT
|
|
1362
|
+
#ifdef HAVE_AES
|
|
1363
|
+
if (zi->ci.method == AES_METHOD)
|
|
1364
|
+
{
|
|
1365
|
+
fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx);
|
|
1366
|
+
}
|
|
1367
|
+
else
|
|
1368
|
+
#endif
|
|
1369
|
+
{
|
|
1370
|
+
uint32_t i = 0;
|
|
1371
|
+
uint8_t t = 0;
|
|
1372
|
+
|
|
1373
|
+
for (i = 0; i < zi->ci.pos_in_buffered_data; i++)
|
|
1374
|
+
zi->ci.buffered_data[i] = (uint8_t)zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t);
|
|
1375
|
+
}
|
|
1376
|
+
#endif
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
write = zi->ci.pos_in_buffered_data;
|
|
1380
|
+
|
|
1381
|
+
do
|
|
1382
|
+
{
|
|
1383
|
+
max_write = write;
|
|
1384
|
+
|
|
1385
|
+
if (zi->disk_size > 0)
|
|
1386
|
+
{
|
|
1387
|
+
zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
|
1388
|
+
|
|
1389
|
+
if (size_available == 0)
|
|
1390
|
+
{
|
|
1391
|
+
err = zipGoToNextDisk((zipFile)zi);
|
|
1392
|
+
if (err != ZIP_OK)
|
|
1393
|
+
return err;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
if (size_available < (uint64_t)max_write)
|
|
1397
|
+
max_write = (uint32_t)size_available;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
written = ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write);
|
|
1401
|
+
if (written != max_write)
|
|
1402
|
+
{
|
|
1403
|
+
err = ZIP_ERRNO;
|
|
1404
|
+
break;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
total_written += written;
|
|
1408
|
+
write -= written;
|
|
1409
|
+
}
|
|
1410
|
+
while (write > 0);
|
|
1411
|
+
|
|
1412
|
+
zi->ci.total_compressed += zi->ci.pos_in_buffered_data;
|
|
1413
|
+
|
|
1414
|
+
#ifdef HAVE_BZIP2
|
|
1415
|
+
if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1416
|
+
{
|
|
1417
|
+
zi->ci.total_uncompressed += zi->ci.bstream.total_in_lo32;
|
|
1418
|
+
zi->ci.bstream.total_in_lo32 = 0;
|
|
1419
|
+
zi->ci.bstream.total_in_hi32 = 0;
|
|
1420
|
+
}
|
|
1421
|
+
else
|
|
1422
|
+
#endif
|
|
1423
|
+
{
|
|
1424
|
+
zi->ci.total_uncompressed += zi->ci.stream.total_in;
|
|
1425
|
+
zi->ci.stream.total_in = 0;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
zi->ci.pos_in_buffered_data = 0;
|
|
1429
|
+
|
|
1430
|
+
return err;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len)
|
|
1434
|
+
{
|
|
1435
|
+
zip64_internal *zi = NULL;
|
|
1436
|
+
int err = ZIP_OK;
|
|
1437
|
+
|
|
1438
|
+
if (file == NULL)
|
|
1439
|
+
return ZIP_PARAMERROR;
|
|
1440
|
+
zi = (zip64_internal*)file;
|
|
1441
|
+
|
|
1442
|
+
if (zi->in_opened_file_inzip == 0)
|
|
1443
|
+
return ZIP_PARAMERROR;
|
|
1444
|
+
|
|
1445
|
+
zi->ci.crc32 = (uint32_t)crc32(zi->ci.crc32, buf, len);
|
|
1446
|
+
|
|
1447
|
+
#ifdef HAVE_BZIP2
|
|
1448
|
+
if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw))
|
|
1449
|
+
{
|
|
1450
|
+
zi->ci.bstream.next_in = (void*)buf;
|
|
1451
|
+
zi->ci.bstream.avail_in = len;
|
|
1452
|
+
err = BZ_RUN_OK;
|
|
1453
|
+
|
|
1454
|
+
while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0))
|
|
1455
|
+
{
|
|
1456
|
+
if (zi->ci.bstream.avail_out == 0)
|
|
1457
|
+
{
|
|
1458
|
+
err = zipFlushWriteBuffer(zi);
|
|
1459
|
+
|
|
1460
|
+
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1461
|
+
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1462
|
+
}
|
|
1463
|
+
else
|
|
1464
|
+
{
|
|
1465
|
+
uint32_t total_out_before_lo = zi->ci.bstream.total_out_lo32;
|
|
1466
|
+
uint32_t total_out_before_hi = zi->ci.bstream.total_out_hi32;
|
|
1467
|
+
|
|
1468
|
+
err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
|
|
1469
|
+
|
|
1470
|
+
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before_lo);
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
if (err == BZ_RUN_OK)
|
|
1475
|
+
err = ZIP_OK;
|
|
1476
|
+
}
|
|
1477
|
+
else
|
|
1478
|
+
#endif
|
|
1479
|
+
{
|
|
1480
|
+
zi->ci.stream.next_in = (uint8_t*)buf;
|
|
1481
|
+
zi->ci.stream.avail_in = len;
|
|
1482
|
+
|
|
1483
|
+
while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0))
|
|
1484
|
+
{
|
|
1485
|
+
if (zi->ci.stream.avail_out == 0)
|
|
1486
|
+
{
|
|
1487
|
+
err = zipFlushWriteBuffer(zi);
|
|
1488
|
+
|
|
1489
|
+
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1490
|
+
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
if (err != ZIP_OK)
|
|
1494
|
+
break;
|
|
1495
|
+
|
|
1496
|
+
if ((zi->ci.compression_method == Z_DEFLATED) && (!zi->ci.raw))
|
|
1497
|
+
{
|
|
1498
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
1499
|
+
uLong total_out_before = zi->ci.stream.total_out;
|
|
1500
|
+
|
|
1501
|
+
zi->ci.astream.src_ptr = zi->ci.stream.next_in;
|
|
1502
|
+
zi->ci.astream.src_size = zi->ci.stream.avail_in;
|
|
1503
|
+
zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
|
|
1504
|
+
zi->ci.astream.dst_size = zi->ci.stream.avail_out;
|
|
1505
|
+
|
|
1506
|
+
compression_status status = 0;
|
|
1507
|
+
compression_stream_flags flags = 0;
|
|
1508
|
+
|
|
1509
|
+
status = compression_stream_process(&zi->ci.astream, flags);
|
|
1510
|
+
|
|
1511
|
+
uLong total_out_after = len - zi->ci.astream.src_size;
|
|
1512
|
+
|
|
1513
|
+
zi->ci.stream.next_in = zi->ci.astream.src_ptr;
|
|
1514
|
+
zi->ci.stream.avail_in = zi->ci.astream.src_size;
|
|
1515
|
+
zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
|
|
1516
|
+
zi->ci.stream.avail_out = zi->ci.astream.dst_size;
|
|
1517
|
+
zi->ci.stream.total_in += total_out_after;
|
|
1518
|
+
//zi->ci.stream.total_out += copy_this;
|
|
1519
|
+
zi->ci.pos_in_buffered_data += total_out_after;
|
|
1520
|
+
|
|
1521
|
+
if (status == COMPRESSION_STATUS_ERROR)
|
|
1522
|
+
err = ZIP_INTERNALERROR;
|
|
1523
|
+
#else
|
|
1524
|
+
uint32_t total_out_before = (uint32_t)zi->ci.stream.total_out;
|
|
1525
|
+
err = deflate(&zi->ci.stream, Z_NO_FLUSH);
|
|
1526
|
+
zi->ci.pos_in_buffered_data += (uint32_t)(zi->ci.stream.total_out - total_out_before);
|
|
1527
|
+
#endif
|
|
1528
|
+
}
|
|
1529
|
+
else
|
|
1530
|
+
{
|
|
1531
|
+
uint32_t copy_this = 0;
|
|
1532
|
+
uint32_t i = 0;
|
|
1533
|
+
if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
|
|
1534
|
+
copy_this = zi->ci.stream.avail_in;
|
|
1535
|
+
else
|
|
1536
|
+
copy_this = zi->ci.stream.avail_out;
|
|
1537
|
+
|
|
1538
|
+
for (i = 0; i < copy_this; i++)
|
|
1539
|
+
*(((char*)zi->ci.stream.next_out)+i) =
|
|
1540
|
+
*(((const char*)zi->ci.stream.next_in)+i);
|
|
1541
|
+
|
|
1542
|
+
zi->ci.stream.avail_in -= copy_this;
|
|
1543
|
+
zi->ci.stream.avail_out -= copy_this;
|
|
1544
|
+
zi->ci.stream.next_in += copy_this;
|
|
1545
|
+
zi->ci.stream.next_out += copy_this;
|
|
1546
|
+
zi->ci.stream.total_in += copy_this;
|
|
1547
|
+
zi->ci.stream.total_out += copy_this;
|
|
1548
|
+
zi->ci.pos_in_buffered_data += copy_this;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
return err;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32)
|
|
1557
|
+
{
|
|
1558
|
+
zip64_internal *zi = NULL;
|
|
1559
|
+
uint16_t extra_data_size = 0;
|
|
1560
|
+
uint32_t i = 0;
|
|
1561
|
+
unsigned char *extra_info = NULL;
|
|
1562
|
+
int err = ZIP_OK;
|
|
1563
|
+
|
|
1564
|
+
if (file == NULL)
|
|
1565
|
+
return ZIP_PARAMERROR;
|
|
1566
|
+
zi = (zip64_internal*)file;
|
|
1567
|
+
|
|
1568
|
+
if (zi->in_opened_file_inzip == 0)
|
|
1569
|
+
return ZIP_PARAMERROR;
|
|
1570
|
+
zi->ci.stream.avail_in = 0;
|
|
1571
|
+
|
|
1572
|
+
if (!zi->ci.raw)
|
|
1573
|
+
{
|
|
1574
|
+
if (zi->ci.compression_method == Z_DEFLATED)
|
|
1575
|
+
{
|
|
1576
|
+
while (err == ZIP_OK)
|
|
1577
|
+
{
|
|
1578
|
+
uint32_t total_out_before = 0;
|
|
1579
|
+
|
|
1580
|
+
if (zi->ci.stream.avail_out == 0)
|
|
1581
|
+
{
|
|
1582
|
+
err = zipFlushWriteBuffer(zi);
|
|
1583
|
+
|
|
1584
|
+
zi->ci.stream.avail_out = Z_BUFSIZE;
|
|
1585
|
+
zi->ci.stream.next_out = zi->ci.buffered_data;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
if (err != ZIP_OK)
|
|
1589
|
+
break;
|
|
1590
|
+
|
|
1591
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
1592
|
+
total_out_before = zi->ci.stream.total_out;
|
|
1593
|
+
|
|
1594
|
+
zi->ci.astream.src_ptr = zi->ci.stream.next_in;
|
|
1595
|
+
zi->ci.astream.src_size = zi->ci.stream.avail_in;
|
|
1596
|
+
zi->ci.astream.dst_ptr = zi->ci.stream.next_out;
|
|
1597
|
+
zi->ci.astream.dst_size = zi->ci.stream.avail_out;
|
|
1598
|
+
|
|
1599
|
+
compression_status status = 0;
|
|
1600
|
+
status = compression_stream_process(&zi->ci.astream, COMPRESSION_STREAM_FINALIZE);
|
|
1601
|
+
|
|
1602
|
+
uint32_t total_out_after = Z_BUFSIZE - zi->ci.astream.dst_size;
|
|
1603
|
+
|
|
1604
|
+
zi->ci.stream.next_in = zi->ci.astream.src_ptr;
|
|
1605
|
+
zi->ci.stream.avail_in = zi->ci.astream.src_size;
|
|
1606
|
+
zi->ci.stream.next_out = zi->ci.astream.dst_ptr;
|
|
1607
|
+
zi->ci.stream.avail_out = zi->ci.astream.dst_size;
|
|
1608
|
+
//zi->ci.stream.total_in += total_out_after;
|
|
1609
|
+
//zi->ci.stream.total_out += copy_this;
|
|
1610
|
+
zi->ci.pos_in_buffered_data += total_out_after;
|
|
1611
|
+
|
|
1612
|
+
if (status == COMPRESSION_STATUS_ERROR)
|
|
1613
|
+
{
|
|
1614
|
+
err = ZIP_INTERNALERROR;
|
|
1615
|
+
}
|
|
1616
|
+
else if (status == COMPRESSION_STATUS_END)
|
|
1617
|
+
{
|
|
1618
|
+
err = Z_STREAM_END;
|
|
1619
|
+
}
|
|
1620
|
+
#else
|
|
1621
|
+
total_out_before = (uint32_t)zi->ci.stream.total_out;
|
|
1622
|
+
err = deflate(&zi->ci.stream, Z_FINISH);
|
|
1623
|
+
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.stream.total_out - total_out_before);
|
|
1624
|
+
#endif
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
else if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1628
|
+
{
|
|
1629
|
+
#ifdef HAVE_BZIP2
|
|
1630
|
+
err = BZ_FINISH_OK;
|
|
1631
|
+
while (err == BZ_FINISH_OK)
|
|
1632
|
+
{
|
|
1633
|
+
uint32_t total_out_before = 0;
|
|
1634
|
+
|
|
1635
|
+
if (zi->ci.bstream.avail_out == 0)
|
|
1636
|
+
{
|
|
1637
|
+
err = zipFlushWriteBuffer(zi);
|
|
1638
|
+
|
|
1639
|
+
zi->ci.bstream.avail_out = (uint16_t)Z_BUFSIZE;
|
|
1640
|
+
zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
total_out_before = zi->ci.bstream.total_out_lo32;
|
|
1644
|
+
err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
|
|
1645
|
+
if (err == BZ_STREAM_END)
|
|
1646
|
+
err = Z_STREAM_END;
|
|
1647
|
+
zi->ci.pos_in_buffered_data += (uint16_t)(zi->ci.bstream.total_out_lo32 - total_out_before);
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
if (err == BZ_FINISH_OK)
|
|
1651
|
+
err = ZIP_OK;
|
|
1652
|
+
#endif
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
if (err == Z_STREAM_END)
|
|
1657
|
+
err = ZIP_OK; /* this is normal */
|
|
1658
|
+
|
|
1659
|
+
if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK))
|
|
1660
|
+
{
|
|
1661
|
+
err = zipFlushWriteBuffer(zi);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
#ifdef HAVE_AES
|
|
1665
|
+
if (zi->ci.method == AES_METHOD)
|
|
1666
|
+
{
|
|
1667
|
+
unsigned char authcode[AES_AUTHCODESIZE];
|
|
1668
|
+
|
|
1669
|
+
fcrypt_end(authcode, &zi->ci.aes_ctx);
|
|
1670
|
+
|
|
1671
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)
|
|
1672
|
+
err = ZIP_ERRNO;
|
|
1673
|
+
}
|
|
1674
|
+
#endif
|
|
1675
|
+
|
|
1676
|
+
if (!zi->ci.raw)
|
|
1677
|
+
{
|
|
1678
|
+
if (zi->ci.compression_method == Z_DEFLATED)
|
|
1679
|
+
{
|
|
1680
|
+
int tmp_err = 0;
|
|
1681
|
+
#ifdef HAVE_APPLE_COMPRESSION
|
|
1682
|
+
tmp_err = compression_stream_destroy(&zi->ci.astream);
|
|
1683
|
+
#else
|
|
1684
|
+
tmp_err = deflateEnd(&zi->ci.stream);
|
|
1685
|
+
#endif
|
|
1686
|
+
if (err == ZIP_OK)
|
|
1687
|
+
err = tmp_err;
|
|
1688
|
+
zi->ci.stream_initialised = 0;
|
|
1689
|
+
}
|
|
1690
|
+
#ifdef HAVE_BZIP2
|
|
1691
|
+
else if (zi->ci.compression_method == Z_BZIP2ED)
|
|
1692
|
+
{
|
|
1693
|
+
int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
|
|
1694
|
+
if (err == ZIP_OK)
|
|
1695
|
+
err = tmperr;
|
|
1696
|
+
zi->ci.stream_initialised = 0;
|
|
1697
|
+
}
|
|
1698
|
+
#endif
|
|
1699
|
+
|
|
1700
|
+
crc32 = zi->ci.crc32;
|
|
1701
|
+
uncompressed_size = zi->ci.total_uncompressed;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/* Write data descriptor */
|
|
1705
|
+
if (err == ZIP_OK)
|
|
1706
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)DATADESCRIPTORMAGIC, 4);
|
|
1707
|
+
if (err == ZIP_OK)
|
|
1708
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, crc32, 4);
|
|
1709
|
+
if (err == ZIP_OK)
|
|
1710
|
+
{
|
|
1711
|
+
if (zi->ci.zip64)
|
|
1712
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->ci.total_compressed, 8);
|
|
1713
|
+
else
|
|
1714
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)zi->ci.total_compressed, 4);
|
|
1715
|
+
}
|
|
1716
|
+
if (err == ZIP_OK)
|
|
1717
|
+
{
|
|
1718
|
+
if (zi->ci.zip64)
|
|
1719
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
|
|
1720
|
+
else
|
|
1721
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)uncompressed_size, 4);
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/* Update crc and sizes to central directory */
|
|
1725
|
+
zipWriteValueToMemory(zi->ci.central_header + 16, crc32, 4); /* crc */
|
|
1726
|
+
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1727
|
+
zipWriteValueToMemory(zi->ci.central_header + 20, UINT32_MAX, 4); /* compr size */
|
|
1728
|
+
else
|
|
1729
|
+
zipWriteValueToMemory(zi->ci.central_header + 20, zi->ci.total_compressed, 4); /* compr size */
|
|
1730
|
+
if (uncompressed_size >= UINT32_MAX)
|
|
1731
|
+
zipWriteValueToMemory(zi->ci.central_header + 24, UINT32_MAX, 4); /* uncompr size */
|
|
1732
|
+
else
|
|
1733
|
+
zipWriteValueToMemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */
|
|
1734
|
+
if (zi->ci.stream.data_type == Z_ASCII)
|
|
1735
|
+
zipWriteValueToMemory(zi->ci.central_header + 36, (uint16_t)Z_ASCII, 2); /* internal file attrib */
|
|
1736
|
+
|
|
1737
|
+
/* Add ZIP64 extra info field for uncompressed size */
|
|
1738
|
+
if (uncompressed_size >= UINT32_MAX)
|
|
1739
|
+
extra_data_size += 8;
|
|
1740
|
+
/* Add ZIP64 extra info field for compressed size */
|
|
1741
|
+
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1742
|
+
extra_data_size += 8;
|
|
1743
|
+
/* Add ZIP64 extra info field for relative offset to local file header of current file */
|
|
1744
|
+
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1745
|
+
extra_data_size += 8;
|
|
1746
|
+
|
|
1747
|
+
/* Add ZIP64 extra info header to central directory */
|
|
1748
|
+
if (extra_data_size > 0)
|
|
1749
|
+
{
|
|
1750
|
+
if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
|
|
1751
|
+
return ZIP_BADZIPFILE;
|
|
1752
|
+
|
|
1753
|
+
extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
|
|
1754
|
+
|
|
1755
|
+
zipWriteValueToMemoryAndMove(&extra_info, 0x0001, 2);
|
|
1756
|
+
zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
|
|
1757
|
+
|
|
1758
|
+
if (uncompressed_size >= UINT32_MAX)
|
|
1759
|
+
zipWriteValueToMemoryAndMove(&extra_info, uncompressed_size, 8);
|
|
1760
|
+
if (zi->ci.total_compressed >= UINT32_MAX)
|
|
1761
|
+
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.total_compressed, 8);
|
|
1762
|
+
if (zi->ci.pos_local_header >= UINT32_MAX)
|
|
1763
|
+
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.pos_local_header, 8);
|
|
1764
|
+
|
|
1765
|
+
zi->ci.size_centralextrafree -= extra_data_size + 4;
|
|
1766
|
+
zi->ci.size_centralheader += extra_data_size + 4;
|
|
1767
|
+
zi->ci.size_centralextra += extra_data_size + 4;
|
|
1768
|
+
|
|
1769
|
+
zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
#ifdef HAVE_AES
|
|
1773
|
+
/* Write AES extra info header to central directory */
|
|
1774
|
+
if (zi->ci.method == AES_METHOD)
|
|
1775
|
+
{
|
|
1776
|
+
extra_info = (unsigned char*)zi->ci.central_header + zi->ci.size_centralheader;
|
|
1777
|
+
extra_data_size = 7;
|
|
1778
|
+
|
|
1779
|
+
if ((uint32_t)(extra_data_size + 4) > zi->ci.size_centralextrafree)
|
|
1780
|
+
return ZIP_BADZIPFILE;
|
|
1781
|
+
|
|
1782
|
+
zipWriteValueToMemoryAndMove(&extra_info, 0x9901, 2);
|
|
1783
|
+
zipWriteValueToMemoryAndMove(&extra_info, extra_data_size, 2);
|
|
1784
|
+
zipWriteValueToMemoryAndMove(&extra_info, AES_VERSION, 2);
|
|
1785
|
+
zipWriteValueToMemoryAndMove(&extra_info, 'A', 1);
|
|
1786
|
+
zipWriteValueToMemoryAndMove(&extra_info, 'E', 1);
|
|
1787
|
+
zipWriteValueToMemoryAndMove(&extra_info, AES_ENCRYPTIONMODE, 1);
|
|
1788
|
+
zipWriteValueToMemoryAndMove(&extra_info, zi->ci.compression_method, 2);
|
|
1789
|
+
|
|
1790
|
+
zi->ci.size_centralextrafree -= extra_data_size + 4;
|
|
1791
|
+
zi->ci.size_centralheader += extra_data_size + 4;
|
|
1792
|
+
zi->ci.size_centralextra += extra_data_size + 4;
|
|
1793
|
+
|
|
1794
|
+
zipWriteValueToMemory(zi->ci.central_header + 30, zi->ci.size_centralextra, 2);
|
|
1795
|
+
}
|
|
1796
|
+
#endif
|
|
1797
|
+
/* Restore comment to correct position */
|
|
1798
|
+
for (i = 0; i < zi->ci.size_comment; i++)
|
|
1799
|
+
zi->ci.central_header[zi->ci.size_centralheader+i] =
|
|
1800
|
+
zi->ci.central_header[zi->ci.size_centralheader+zi->ci.size_centralextrafree+i];
|
|
1801
|
+
zi->ci.size_centralheader += zi->ci.size_comment;
|
|
1802
|
+
|
|
1803
|
+
if (err == ZIP_OK)
|
|
1804
|
+
err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, zi->ci.size_centralheader);
|
|
1805
|
+
|
|
1806
|
+
free(zi->ci.central_header);
|
|
1807
|
+
|
|
1808
|
+
zi->number_entry++;
|
|
1809
|
+
zi->in_opened_file_inzip = 0;
|
|
1810
|
+
|
|
1811
|
+
return err;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32)
|
|
1815
|
+
{
|
|
1816
|
+
return zipCloseFileInZipRaw64(file, uncompressed_size, crc32);
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
extern int ZEXPORT zipCloseFileInZip(zipFile file)
|
|
1820
|
+
{
|
|
1821
|
+
return zipCloseFileInZipRaw(file, 0, 0);
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
extern int ZEXPORT zipClose(zipFile file, const char *global_comment)
|
|
1825
|
+
{
|
|
1826
|
+
return zipClose_64(file, global_comment);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment)
|
|
1830
|
+
{
|
|
1831
|
+
return zipClose2_64(file, global_comment, VERSIONMADEBY);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby)
|
|
1835
|
+
{
|
|
1836
|
+
zip64_internal *zi = NULL;
|
|
1837
|
+
uint32_t size_centraldir = 0;
|
|
1838
|
+
uint16_t size_global_comment = 0;
|
|
1839
|
+
uint64_t centraldir_pos_inzip = 0;
|
|
1840
|
+
uint64_t pos = 0;
|
|
1841
|
+
uint64_t cd_pos = 0;
|
|
1842
|
+
uint32_t write = 0;
|
|
1843
|
+
int err = ZIP_OK;
|
|
1844
|
+
|
|
1845
|
+
if (file == NULL)
|
|
1846
|
+
return ZIP_PARAMERROR;
|
|
1847
|
+
zi = (zip64_internal*)file;
|
|
1848
|
+
|
|
1849
|
+
if (zi->in_opened_file_inzip == 1)
|
|
1850
|
+
err = zipCloseFileInZip(file);
|
|
1851
|
+
|
|
1852
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
1853
|
+
if (global_comment == NULL)
|
|
1854
|
+
global_comment = zi->globalcomment;
|
|
1855
|
+
#endif
|
|
1856
|
+
|
|
1857
|
+
if (zi->filestream != zi->filestream_with_CD)
|
|
1858
|
+
{
|
|
1859
|
+
if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)
|
|
1860
|
+
if (err == ZIP_OK)
|
|
1861
|
+
err = ZIP_ERRNO;
|
|
1862
|
+
if (zi->disk_size > 0)
|
|
1863
|
+
zi->number_disk_with_CD = zi->number_disk + 1;
|
|
1864
|
+
zi->filestream = zi->filestream_with_CD;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1868
|
+
|
|
1869
|
+
if (err == ZIP_OK)
|
|
1870
|
+
{
|
|
1871
|
+
linkedlist_datablock_internal *ldi = zi->central_dir.first_block;
|
|
1872
|
+
while (ldi != NULL)
|
|
1873
|
+
{
|
|
1874
|
+
if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0))
|
|
1875
|
+
{
|
|
1876
|
+
write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block);
|
|
1877
|
+
if (write != ldi->filled_in_this_block)
|
|
1878
|
+
err = ZIP_ERRNO;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
size_centraldir += ldi->filled_in_this_block;
|
|
1882
|
+
ldi = ldi->next_datablock;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
free_linkedlist(&(zi->central_dir));
|
|
1887
|
+
|
|
1888
|
+
pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1889
|
+
|
|
1890
|
+
/* Write the ZIP64 central directory header */
|
|
1891
|
+
if (pos >= UINT32_MAX || zi->number_entry > UINT32_MAX)
|
|
1892
|
+
{
|
|
1893
|
+
uint64_t zip64_eocd_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
|
|
1894
|
+
uint32_t zip64_datasize = 44;
|
|
1895
|
+
|
|
1896
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDHEADERMAGIC, 4);
|
|
1897
|
+
|
|
1898
|
+
/* Size of this 'zip64 end of central directory' */
|
|
1899
|
+
if (err == ZIP_OK)
|
|
1900
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)zip64_datasize, 8);
|
|
1901
|
+
/* Version made by */
|
|
1902
|
+
if (err == ZIP_OK)
|
|
1903
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, version_madeby, 2);
|
|
1904
|
+
/* version needed */
|
|
1905
|
+
if (err == ZIP_OK)
|
|
1906
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)45, 2);
|
|
1907
|
+
/* Number of this disk */
|
|
1908
|
+
if (err == ZIP_OK)
|
|
1909
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1910
|
+
/* Number of the disk with the start of the central directory */
|
|
1911
|
+
if (err == ZIP_OK)
|
|
1912
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1913
|
+
/* Total number of entries in the central dir on this disk */
|
|
1914
|
+
if (err == ZIP_OK)
|
|
1915
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
|
|
1916
|
+
/* Total number of entries in the central dir */
|
|
1917
|
+
if (err == ZIP_OK)
|
|
1918
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
|
|
1919
|
+
/* Size of the central directory */
|
|
1920
|
+
if (err == ZIP_OK)
|
|
1921
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint64_t)size_centraldir, 8);
|
|
1922
|
+
|
|
1923
|
+
if (err == ZIP_OK)
|
|
1924
|
+
{
|
|
1925
|
+
/* Offset of start of central directory with respect to the starting disk number */
|
|
1926
|
+
cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1927
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
|
|
1928
|
+
}
|
|
1929
|
+
if (err == ZIP_OK)
|
|
1930
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ZIP64ENDLOCHEADERMAGIC, 4);
|
|
1931
|
+
|
|
1932
|
+
/* Number of the disk with the start of the central directory */
|
|
1933
|
+
if (err == ZIP_OK)
|
|
1934
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD, 4);
|
|
1935
|
+
/* Relative offset to the Zip64EndOfCentralDirectory */
|
|
1936
|
+
if (err == ZIP_OK)
|
|
1937
|
+
{
|
|
1938
|
+
cd_pos = zip64_eocd_pos_inzip - zi->add_position_when_writting_offset;
|
|
1939
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, cd_pos, 8);
|
|
1940
|
+
}
|
|
1941
|
+
/* Number of the disk with the start of the central directory */
|
|
1942
|
+
if (err == ZIP_OK)
|
|
1943
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, zi->number_disk_with_CD + 1, 4);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
/* Write the central directory header */
|
|
1947
|
+
|
|
1948
|
+
/* Signature */
|
|
1949
|
+
if (err == ZIP_OK)
|
|
1950
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)ENDHEADERMAGIC, 4);
|
|
1951
|
+
/* Number of this disk */
|
|
1952
|
+
if (err == ZIP_OK)
|
|
1953
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
|
|
1954
|
+
/* Number of the disk with the start of the central directory */
|
|
1955
|
+
if (err == ZIP_OK)
|
|
1956
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_disk_with_CD, 2);
|
|
1957
|
+
/* Total number of entries in the central dir on this disk */
|
|
1958
|
+
if (err == ZIP_OK)
|
|
1959
|
+
{
|
|
1960
|
+
if (zi->number_entry >= UINT16_MAX)
|
|
1961
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
|
|
1962
|
+
else
|
|
1963
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
|
|
1964
|
+
}
|
|
1965
|
+
/* Total number of entries in the central dir */
|
|
1966
|
+
if (err == ZIP_OK)
|
|
1967
|
+
{
|
|
1968
|
+
if (zi->number_entry >= UINT16_MAX)
|
|
1969
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT16_MAX, 2); /* use value in ZIP64 record */
|
|
1970
|
+
else
|
|
1971
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint16_t)zi->number_entry, 2);
|
|
1972
|
+
}
|
|
1973
|
+
/* Size of the central directory */
|
|
1974
|
+
if (err == ZIP_OK)
|
|
1975
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_centraldir, 4);
|
|
1976
|
+
/* Offset of start of central directory with respect to the starting disk number */
|
|
1977
|
+
if (err == ZIP_OK)
|
|
1978
|
+
{
|
|
1979
|
+
cd_pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
|
1980
|
+
if (pos >= UINT32_MAX)
|
|
1981
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, UINT32_MAX, 4);
|
|
1982
|
+
else
|
|
1983
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, (uint32_t)cd_pos, 4);
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/* Write global comment */
|
|
1987
|
+
|
|
1988
|
+
if (global_comment != NULL)
|
|
1989
|
+
size_global_comment = (uint16_t)strlen(global_comment);
|
|
1990
|
+
if (err == ZIP_OK)
|
|
1991
|
+
err = zipWriteValue(&zi->z_filefunc, zi->filestream, size_global_comment, 2);
|
|
1992
|
+
if (err == ZIP_OK && size_global_comment > 0)
|
|
1993
|
+
{
|
|
1994
|
+
if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment)
|
|
1995
|
+
err = ZIP_ERRNO;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK))
|
|
1999
|
+
err = ZIP_ERRNO;
|
|
2000
|
+
|
|
2001
|
+
#ifndef NO_ADDFILEINEXISTINGZIP
|
|
2002
|
+
TRYFREE(zi->globalcomment);
|
|
2003
|
+
#endif
|
|
2004
|
+
TRYFREE(zi);
|
|
2005
|
+
|
|
2006
|
+
return err;
|
|
2007
|
+
}
|