1 #ifndef _HAD_ZIPINT_H
2 #define _HAD_ZIPINT_H
3 
4 /*
5   zipint.h -- internal declarations.
6   Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner
7 
8   This file is part of libzip, a library to manipulate ZIP archives.
9   The authors can be contacted at <libzip@nih.at>
10 
11   Redistribution and use in source and binary forms, with or without
12   modification, are permitted provided that the following conditions
13   are met:
14   1. Redistributions of source code must retain the above copyright
15      notice, this list of conditions and the following disclaimer.
16   2. Redistributions in binary form must reproduce the above copyright
17      notice, this list of conditions and the following disclaimer in
18      the documentation and/or other materials provided with the
19      distribution.
20   3. The names of the authors may not be used to endorse or promote
21      products derived from this software without specific prior
22      written permission.
23 
24   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
25   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
28   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
30   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
34   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 
37 /* to have *_MAX definitions for all types when compiling with g++ */
38 #define __STDC_LIMIT_MACROS
39 
40 #include <zlib.h>
41 
42 #ifdef _WIN32
43 #define ZIP_EXTERN
44 //__declspec(dllexport)
45 /* for dup(), close(), etc. */
46 #include <io.h>
47 #endif
48 
49 #ifndef _ZIP_COMPILING_DEPRECATED
50 #define ZIP_DISABLE_DEPRECATED
51 #endif
52 
53 #include "zip.h"
54 #include "config.h"
55 
56 #ifdef HAVE_MOVEFILEEXA
57 #include <windows.h>
58 #define _zip_rename(s, t)	(!MoveFileExA((s), (t), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING))
59 #else
60 #define _zip_rename	rename
61 #endif
62 
63 #ifdef _WIN32
64 #if defined(HAVE__CLOSE)
65 #define close		_close
66 #endif
67 #if defined(HAVE__DUP)
68 #define dup		_dup
69 #endif
70 /* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
71 #if defined(HAVE__FDOPEN)
72 #define fdopen		_fdopen
73 #endif
74 #if defined(HAVE__FILENO)
75 #define fileno		_fileno
76 #endif
77 /* Windows' open() doesn't understand Unix permissions */
78 #if defined(HAVE__OPEN)
79 #define open(a, b, c)	_open((a), (b))
80 #endif
81 #if defined(HAVE__SNPRINTF)
82 #define snprintf	_snprintf
83 #endif
84 #if defined(HAVE__STRDUP) && !defined(HAVE_STRDUP)
85 #define strdup		_strdup
86 #endif
87 #endif
88 
89 #ifndef HAVE_FSEEKO
90 #define fseeko(s, o, w)	(fseek((s), (long int)(o), (w)))
91 #endif
92 
93 #ifndef HAVE_FTELLO
94 #define ftello(s)	((long)ftell((s)))
95 #endif
96 
97 #ifndef HAVE_MKSTEMP
98 int _zip_mkstemp(char *);
99 #define mkstemp _zip_mkstemp
100 #endif
101 
102 #ifdef _WIN32
103 #if !defined(HAVE_STRCASECMP)
104 #if defined(HAVE__STRICMP)
105 #define strcasecmp	_stricmp
106 #endif
107 #endif
108 #endif
109 
110 #if SIZEOF_OFF_T == 8
111 #define ZIP_OFF_MAX ZIP_INT64_MAX
112 #elif SIZEOF_OFF_T == 4
113 #define ZIP_OFF_MAX ZIP_INT32_MAX
114 #elif SIZEOF_OFF_T == 2
115 #define ZIP_OFF_MAX ZIP_INT16_MAX
116 #else
117 #error unsupported size of off_t
118 #endif
119 
120 #ifndef SIZE_MAX
121 #if SIZEOF_SIZE_T == 8
122 #define SIZE_MAX ZIP_INT64_MAX
123 #elif SIZEOF_SIZE_T == 4
124 #define SIZE_MAX ZIP_INT32_MAX
125 #elif SIZEOF_SIZE_T == 2
126 #define SIZE_MAX ZIP_INT16_MAX
127 #else
128 #error unsupported size of size_t
129 #endif
130 #endif
131 
132 #define CENTRAL_MAGIC "PK\1\2"
133 #define LOCAL_MAGIC   "PK\3\4"
134 #define EOCD_MAGIC    "PK\5\6"
135 #define DATADES_MAGIC "PK\7\8"
136 #define EOCD64LOC_MAGIC "PK\6\7"
137 #define EOCD64_MAGIC  "PK\6\6"
138 #define TORRENT_SIG	"TORRENTZIPPED-"
139 #define TORRENT_SIG_LEN	14
140 #define TORRENT_CRC_LEN 8
141 #define TORRENT_MEM_LEVEL	8
142 #define CDENTRYSIZE         46u
143 #define LENTRYSIZE          30
144 #define MAXCOMLEN        65536
145 #define MAXEXTLEN        65536
146 #define EOCDLEN             22
147 #define EOCD64LOCLEN	    20
148 #define EOCD64LEN	    56
149 #define CDBUFSIZE       (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN)
150 #define BUFSIZE		8192
151 
152 #define ZIP_CM_REPLACED_DEFAULT (-2)
153 
154 #define ZIP_CM_IS_DEFAULT(x)	((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT)
155 
156 #define ZIP_EF_UTF_8_COMMENT	0x6375
157 #define ZIP_EF_UTF_8_NAME	0x7075
158 #define ZIP_EF_ZIP64		0x0001
159 
160 #define ZIP_EF_IS_INTERNAL(id)	((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64)
161 
162 /* according to unzip-6.0's zipinfo.c, this corresponds to a regular file with rw permissions for everyone */
163 #define ZIP_EXT_ATTRIB_DEFAULT		(0100666<<16)
164 /* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */
165 #define ZIP_EXT_ATTRIB_DEFAULT_DIR	(0040777<<16)
166 
167 
168 /* This section contains API that won't materialize like this.  It's
169    placed in the internal section, pending cleanup. */
170 
171 typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
172 						     struct zip_source *,
173 						     zip_int32_t, int);
174 typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
175 						    struct zip_source *,
176 						    zip_uint16_t, int,
177 						    const char *);
178 
179 zip_compression_implementation _zip_get_compression_implementation(zip_int32_t);
180 zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t);
181 
182 
183 
184 
185 /* This API is not final yet, but we need it internally, so it's private for now. */
186 
187 const zip_uint8_t *zip_get_extra_field_by_id(struct zip *, int, int, zip_uint16_t, int, zip_uint16_t *);
188 
189 /* This section contains API that is of limited use until support for
190    user-supplied compression/encryption implementation is finished.
191    Thus we will keep it private for now. */
192 
193 typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
194 						   void *, zip_uint64_t,
195 						   enum zip_source_cmd);
196 
197 void zip_source_close(struct zip_source *);
198 struct zip_source *zip_source_crc(struct zip *, struct zip_source *,
199 				  int);
200 struct zip_source *zip_source_deflate(struct zip *,
201 				      struct zip_source *,
202 				      zip_int32_t, int);
203 void zip_source_error(struct zip_source *, int *, int *);
204 struct zip_source *zip_source_layered(struct zip *,
205 				      struct zip_source *,
206 				      zip_source_layered_callback,
207 				      void *);
208 int zip_source_open(struct zip_source *);
209 struct zip_source *zip_source_pkware(struct zip *,
210 				     struct zip_source *,
211 				     zip_uint16_t, int,
212 				     const char *);
213 zip_int64_t zip_source_read(struct zip_source *, void *,
214 			    zip_uint64_t);
215 int zip_source_stat(struct zip_source *, struct zip_stat *);
216 struct zip_source *zip_source_window(struct zip *, struct zip_source *,
217 				     zip_uint64_t, zip_uint64_t);
218 
219 
220 /* This function will probably remain private.  It is not needed to
221    implement compression/encryption routines.  (We should probably
222    rename it to _zip_source_pop.) */
223 
224 struct zip_source *zip_source_pop(struct zip_source *);
225 
226 
227 
228 /* error source for layered sources */
229 
230 enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
231 
232 /* directory entry: general purpose bit flags */
233 
234 #define ZIP_GPBF_ENCRYPTED		0x0001	/* is encrypted */
235 #define ZIP_GPBF_DATA_DESCRIPTOR	0x0008	/* crc/size after file data */
236 #define ZIP_GPBF_STRONG_ENCRYPTION	0x0040  /* uses strong encryption */
237 #define ZIP_GPBF_ENCODING_UTF_8		0x0800  /* file name encoding is UTF-8 */
238 
239 
240 /* extra fields */
241 #define ZIP_EF_LOCAL		ZIP_FL_LOCAL			/* include in local header */
242 #define ZIP_EF_CENTRAL		ZIP_FL_CENTRAL			/* include in central directory */
243 #define ZIP_EF_BOTH		(ZIP_EF_LOCAL|ZIP_EF_CENTRAL)	/* include in both */
244 
245 #define ZIP_FL_FORCE_ZIP64	1024  /* force zip64 extra field (_zip_dirent_write) */
246 
247 #define ZIP_FL_ENCODING_ALL	(ZIP_FL_ENC_GUESS|ZIP_FL_ENC_CP437|ZIP_FL_ENC_UTF_8)
248 
249 
250 /* encoding type */
251 enum zip_encoding_type {
252     ZIP_ENCODING_UNKNOWN,       /* not yet analyzed */
253     ZIP_ENCODING_ASCII,         /* plain ASCII */
254     ZIP_ENCODING_UTF8_KNOWN,    /* is UTF-8 */
255     ZIP_ENCODING_UTF8_GUESSED,  /* possibly UTF-8 */
256     ZIP_ENCODING_CP437,         /* Code Page 437 */
257     ZIP_ENCODING_ERROR          /* should be UTF-8 but isn't */
258 };
259 
260 /* error information */
261 
262 struct zip_error {
263     int zip_err;	/* libzip error code (ZIP_ER_*) */
264     int sys_err;	/* copy of errno (E*) or zlib error code */
265     char *str;		/* string representation or NULL */
266 };
267 
268 /* zip archive, part of API */
269 
270 struct zip {
271     char *zn;				/* file name */
272     FILE *zp;				/* file */
273     unsigned int open_flags;		/* flags passed to zip_open */
274     struct zip_error error;		/* error information */
275 
276     unsigned int flags;			/* archive global flags */
277     unsigned int ch_flags;		/* changed archive global flags */
278 
279     char *default_password;		/* password used when no other supplied */
280 
281     struct zip_string *comment_orig;	/* archive comment */
282     struct zip_string *comment_changes; /* changed archive comment */
283     int comment_changed;		/* whether archive comment was changed */
284 
285     zip_uint64_t nentry;		/* number of entries */
286     zip_uint64_t nentry_alloc;		/* number of entries allocated */
287     struct zip_entry *entry;		/* entries */
288 
289     unsigned int nfile;			/* number of opened files within archive */
290     unsigned int nfile_alloc;		/* number of files allocated */
291     struct zip_file **file;		/* opened files within archive */
292 
293     char *tempdir;                      /* custom temp dir (needed e.g. for OS X sandboxing) */
294 };
295 
296 /* file in zip archive, part of API */
297 
298 struct zip_file {
299     struct zip *za;		/* zip archive containing this file */
300     struct zip_error error;	/* error information */
301     int eof;
302     struct zip_source *src;	/* data source */
303 };
304 
305 /* zip archive directory entry (central or local) */
306 
307 #define ZIP_DIRENT_COMP_METHOD	0x0001u
308 #define ZIP_DIRENT_FILENAME	0x0002u
309 #define ZIP_DIRENT_COMMENT	0x0004u
310 #define ZIP_DIRENT_EXTRA_FIELD	0x0008u
311 #define ZIP_DIRENT_ATTRIBUTES	0x0010u
312 #define ZIP_DIRENT_ALL		0xffffu
313 
314 struct zip_dirent {
315     zip_uint32_t changed;
316     int local_extra_fields_read;		/*      whether we already read in local header extra fields */
317     int cloned;                                 /*      whether this instance is cloned, and thus shares non-changed strings */
318 
319     zip_uint16_t version_madeby;		/* (c)  version of creator */
320     zip_uint16_t version_needed;		/* (cl) version needed to extract */
321     zip_uint16_t bitflags;			/* (cl) general purpose bit flag */
322     zip_int32_t comp_method;			/* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */
323     time_t last_mod;				/* (cl) time of last modification */
324     zip_uint32_t crc;				/* (cl) CRC-32 of uncompressed data */
325     zip_uint64_t comp_size;			/* (cl) size of compressed data */
326     zip_uint64_t uncomp_size;			/* (cl) size of uncompressed data */
327     struct zip_string *filename;		/* (cl) file name (NUL-terminated) */
328     struct zip_extra_field *extra_fields;	/* (cl) extra fields, parsed */
329     struct zip_string *comment;			/* (c)  file comment */
330     zip_uint32_t disk_number;			/* (c)  disk number start */
331     zip_uint16_t int_attrib;			/* (c)  internal file attributes */
332     zip_uint32_t ext_attrib;			/* (c)  external file attributes */
333     zip_uint64_t offset;			/* (c)  offset of local header */
334 };
335 
336 /* zip archive central directory */
337 
338 struct zip_cdir {
339     struct zip_entry *entry;	 		/* directory entries */
340     zip_uint64_t nentry;			/* number of entries */
341     zip_uint64_t nentry_alloc;			/* number of entries allocated */
342 
343     off_t size;                                 /* size of central directory */
344     off_t offset;		 		/* offset of central directory in file */
345     struct zip_string *comment;			/* zip archive comment */
346 };
347 
348 struct zip_extra_field {
349     struct zip_extra_field *next;
350     zip_flags_t flags;				/* in local/central header */
351     zip_uint16_t id;				/* header id */
352     zip_uint16_t size;				/* data size */
353     zip_uint8_t *data;
354 };
355 
356 
357 
358 struct zip_source {
359     struct zip_source *src;
360     union {
361 	zip_source_callback f;
362 	zip_source_layered_callback l;
363     } cb;
364     void *ud;
365     enum zip_les error_source;
366     int is_open;
367 };
368 
369 /* entry in zip archive directory */
370 
371 struct zip_entry {
372     struct zip_dirent *orig;
373     struct zip_dirent *changes;
374     struct zip_source *source;
375     int deleted;
376 };
377 
378 
379 
380 /* file or archive comment, or filename */
381 
382 struct zip_string {
383     zip_uint8_t *raw;			/* raw string */
384     zip_uint16_t length;		/* length of raw string */
385     enum zip_encoding_type encoding; 	/* autorecognized encoding */
386     zip_uint8_t *converted;     	/* autoconverted string */
387     zip_uint32_t converted_length;	/* length of converted */
388 };
389 
390 
391 
392 /* which files to write, and in which order (name is for torrentzip sorting) */
393 
394 struct zip_filelist {
395     zip_uint64_t idx;
396     const char *name;
397 };
398 
399 
400 
401 extern const char * const _zip_err_str[];
402 extern const int _zip_nerr_str;
403 extern const int _zip_err_type[];
404 
405 
406 
407 #define ZIP_ENTRY_CHANGED(e, f)	((e)->changes && ((e)->changes->changed & (f)))
408 
409 #define ZIP_ENTRY_DATA_CHANGED(x)	((x)->source != NULL)
410 
411 #define ZIP_IS_RDONLY(za)	((za)->ch_flags & ZIP_AFL_RDONLY)
412 
413 
414 
415 zip_int64_t _zip_add_entry(struct zip *);
416 
417 int _zip_cdir_compute_crc(struct zip *, uLong *);
418 void _zip_cdir_free(struct zip_cdir *);
419 int _zip_cdir_grow(struct zip_cdir *, zip_uint64_t, struct zip_error *);
420 struct zip_cdir *_zip_cdir_new(zip_uint64_t, struct zip_error *);
421 zip_int64_t _zip_cdir_write(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *);
422 
423 struct zip_dirent *_zip_dirent_clone(const struct zip_dirent *);
424 void _zip_dirent_free(struct zip_dirent *);
425 void _zip_dirent_finalize(struct zip_dirent *);
426 void _zip_dirent_init(struct zip_dirent *);
427 int _zip_dirent_needs_zip64(const struct zip_dirent *, zip_flags_t);
428 struct zip_dirent *_zip_dirent_new(void);
429 int _zip_dirent_read(struct zip_dirent *, FILE *, const unsigned char **,
430 		     zip_uint64_t *, int, struct zip_error *);
431 zip_int32_t _zip_dirent_size(FILE *, zip_uint16_t, struct zip_error *);
432 void _zip_dirent_torrent_normalize(struct zip_dirent *);
433 int _zip_dirent_write(struct zip_dirent *, FILE *, zip_flags_t, struct zip_error *);
434 
435 struct zip_extra_field *_zip_ef_clone(const struct zip_extra_field *, struct zip_error *);
436 struct zip_extra_field *_zip_ef_delete_by_id(struct zip_extra_field *, zip_uint16_t, zip_uint16_t, zip_flags_t);
437 void _zip_ef_free(struct zip_extra_field *);
438 const zip_uint8_t *_zip_ef_get_by_id(const struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, struct zip_error *);
439 struct zip_extra_field *_zip_ef_merge(struct zip_extra_field *, struct zip_extra_field *);
440 struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t);
441 struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *);
442 struct zip_extra_field *_zip_ef_remove_internal(struct zip_extra_field *);
443 zip_uint16_t _zip_ef_size(const struct zip_extra_field *, zip_flags_t);
444 void _zip_ef_write(const struct zip_extra_field *, zip_flags_t, FILE *);
445 
446 void _zip_entry_finalize(struct zip_entry *);
447 void _zip_entry_init(struct zip_entry *);
448 
449 void _zip_error_clear(struct zip_error *);
450 void _zip_error_copy(struct zip_error *, const struct zip_error *);
451 void _zip_error_fini(struct zip_error *);
452 void _zip_error_get(const struct zip_error *, int *, int *);
453 void _zip_error_init(struct zip_error *);
454 void _zip_error_set(struct zip_error *, int, int);
455 void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
456 const char *_zip_error_strerror(struct zip_error *);
457 
458 const zip_uint8_t *_zip_extract_extra_field_by_id(struct zip_error *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *);
459 
460 int _zip_file_extra_field_prepare_for_change(struct zip *, zip_uint64_t);
461 int _zip_file_fillbuf(void *, size_t, struct zip_file *);
462 zip_uint64_t _zip_file_get_offset(const struct zip *, zip_uint64_t, struct zip_error *);
463 
464 int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
465 
466 struct zip_dirent *_zip_get_dirent(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *);
467 
468 enum zip_encoding_type _zip_guess_encoding(struct zip_string *, enum zip_encoding_type);
469 zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t * const, zip_uint32_t,
470 				zip_uint32_t *, struct zip_error *error);
471 
472 struct zip *_zip_open(const char *, FILE *, unsigned int, int *);
473 
474 int _zip_read_local_ef(struct zip *, zip_uint64_t);
475 
476 struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
477 					 zip_uint64_t, zip_int64_t, int,
478 					 const struct zip_stat *);
479 struct zip_source *_zip_source_new(struct zip *);
480 struct zip_source *_zip_source_zip_new(struct zip *, struct zip *, zip_uint64_t, zip_flags_t,
481 				       zip_uint64_t, zip_uint64_t, const char *);
482 
483 int _zip_string_equal(const struct zip_string *, const struct zip_string *);
484 void _zip_string_free(struct zip_string *);
485 zip_uint32_t _zip_string_crc32(const struct zip_string *);
486 const zip_uint8_t *_zip_string_get(struct zip_string *, zip_uint32_t *, zip_flags_t, struct zip_error *);
487 zip_uint16_t _zip_string_length(const struct zip_string *);
488 struct zip_string *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *);
489 void _zip_string_write(const struct zip_string *, FILE *);
490 
491 int _zip_changed(const struct zip *, zip_uint64_t *);
492 const char *_zip_get_name(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *);
493 int _zip_local_header_read(struct zip *, int);
494 void *_zip_memdup(const void *, size_t, struct zip_error *);
495 zip_int64_t _zip_name_locate(struct zip *, const char *, zip_flags_t, struct zip_error *);
496 struct zip *_zip_new(struct zip_error *);
497 zip_uint16_t _zip_read2(const zip_uint8_t **);
498 zip_uint32_t _zip_read4(const zip_uint8_t **);
499 zip_uint64_t _zip_read8(const zip_uint8_t **);
500 zip_uint8_t *_zip_read_data(const zip_uint8_t **, FILE *, size_t, int, struct zip_error *);
501 zip_int64_t _zip_file_replace(struct zip *, zip_uint64_t, const char *, struct zip_source *, zip_flags_t);
502 int _zip_set_name(struct zip *, zip_uint64_t, const char *, zip_flags_t);
503 void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *);
504 int _zip_unchange(struct zip *, zip_uint64_t, int);
505 void _zip_unchange_data(struct zip_entry *);
506 
507 void _zip_poke4(zip_uint32_t, zip_uint8_t **);
508 void _zip_poke8(zip_uint64_t, zip_uint8_t **);
509 void _zip_write2(zip_uint16_t, FILE *);
510 void _zip_write4(zip_uint32_t, FILE *);
511 void _zip_write8(zip_uint64_t, FILE *);
512 
513 
514 #endif /* zipint.h */
515