Imported Upstream version 1.3.2
[platform/upstream/libzip.git] / lib / zip_dirent.c
1 /*
2   zip_dirent.c -- read directory entry (local or central), clean dirent
3   Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
4
5   This file is part of libzip, a library to manipulate ZIP archives.
6   The authors can be contacted at <libzip@nih.at>
7
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions
10   are met:
11   1. Redistributions of source code must retain the above copyright
12      notice, this list of conditions and the following disclaimer.
13   2. Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in
15      the documentation and/or other materials provided with the
16      distribution.
17   3. The names of the authors may not be used to endorse or promote
18      products derived from this software without specific prior
19      written permission.
20
21   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <time.h>
41
42 #include "zipint.h"
43
44 static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
45 static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
46 static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
47 static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
48
49
50 void
51 _zip_cdir_free(zip_cdir_t *cd)
52 {
53     zip_uint64_t i;
54
55     if (!cd)
56         return;
57
58     for (i=0; i<cd->nentry; i++)
59         _zip_entry_finalize(cd->entry+i);
60     free(cd->entry);
61     _zip_string_free(cd->comment);
62     free(cd);
63 }
64
65
66 zip_cdir_t *
67 _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
68 {
69     zip_cdir_t *cd;
70
71     if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
72         zip_error_set(error, ZIP_ER_MEMORY, 0);
73         return NULL;
74     }
75
76     cd->entry = NULL;
77     cd->nentry = cd->nentry_alloc = 0;
78     cd->size = cd->offset = 0;
79     cd->comment = NULL;
80     cd->is_zip64 = false;
81
82     if (!_zip_cdir_grow(cd, nentry, error)) {
83         _zip_cdir_free(cd);
84         return NULL;
85     }
86
87     return cd;
88 }
89
90
91 bool
92 _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error)
93 {
94     zip_uint64_t i, new_alloc;
95     zip_entry_t *new_entry;
96
97     if (additional_entries == 0) {
98         return true;
99     }
100
101     new_alloc = cd->nentry_alloc + additional_entries;
102
103     if (new_alloc < additional_entries || new_alloc > SIZE_MAX/sizeof(*(cd->entry))) {
104         zip_error_set(error, ZIP_ER_MEMORY, 0);
105         return false;
106     }
107
108     if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry))*(size_t)new_alloc)) == NULL) {
109         zip_error_set(error, ZIP_ER_MEMORY, 0);
110         return false;
111     }
112
113     cd->entry = new_entry;
114
115     for (i = cd->nentry; i < new_alloc; i++) {
116         _zip_entry_init(cd->entry+i);
117     }
118
119     cd->nentry = cd->nentry_alloc = new_alloc;
120
121     return true;
122 }
123
124
125 zip_int64_t
126 _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
127 {
128     zip_uint64_t offset, size;
129     zip_string_t *comment;
130     zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
131     zip_buffer_t *buffer;
132     zip_int64_t off;
133     zip_uint64_t i;
134     bool is_zip64;
135     int ret;
136
137     if ((off = zip_source_tell_write(za->src)) < 0) {
138         _zip_error_set_from_source(&za->error, za->src);
139         return -1;
140     }
141     offset = (zip_uint64_t)off;
142
143     is_zip64 = false;
144
145     for (i=0; i<survivors; i++) {
146         zip_entry_t *entry = za->entry+filelist[i].idx;
147
148         if ((ret=_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
149             return -1;
150         if (ret)
151             is_zip64 = true;
152     }
153
154     if ((off = zip_source_tell_write(za->src)) < 0) {
155         _zip_error_set_from_source(&za->error, za->src);
156         return -1;
157     }
158     size = (zip_uint64_t)off - offset;
159
160     if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
161         is_zip64 = true;
162
163
164     if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
165         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
166         return -1;
167     }
168
169     if (is_zip64) {
170         _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
171         _zip_buffer_put_64(buffer, EOCD64LEN-12);
172         _zip_buffer_put_16(buffer, 45);
173         _zip_buffer_put_16(buffer, 45);
174         _zip_buffer_put_32(buffer, 0);
175         _zip_buffer_put_32(buffer, 0);
176         _zip_buffer_put_64(buffer, survivors);
177         _zip_buffer_put_64(buffer, survivors);
178         _zip_buffer_put_64(buffer, size);
179         _zip_buffer_put_64(buffer, offset);
180         _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
181         _zip_buffer_put_32(buffer, 0);
182         _zip_buffer_put_64(buffer, offset+size);
183         _zip_buffer_put_32(buffer, 1);
184     }
185
186     _zip_buffer_put(buffer, EOCD_MAGIC, 4);
187     _zip_buffer_put_32(buffer, 0);
188     _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
189     _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
190     _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
191     _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
192
193     comment = za->comment_changed ? za->comment_changes : za->comment_orig;
194
195     _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
196
197     if (!_zip_buffer_ok(buffer)) {
198         zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
199         _zip_buffer_free(buffer);
200         return -1;
201     }
202
203     if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
204         _zip_buffer_free(buffer);
205         return -1;
206     }
207
208     _zip_buffer_free(buffer);
209
210     if (comment) {
211         if (_zip_write(za, comment->raw, comment->length) < 0) {
212             return -1;
213         }
214     }
215
216     return (zip_int64_t)size;
217 }
218
219
220 zip_dirent_t *
221 _zip_dirent_clone(const zip_dirent_t *sde)
222 {
223     zip_dirent_t *tde;
224
225     if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
226         return NULL;
227
228     if (sde)
229         memcpy(tde, sde, sizeof(*sde));
230     else
231         _zip_dirent_init(tde);
232
233     tde->changed = 0;
234     tde->cloned = 1;
235
236     return tde;
237 }
238
239
240 void
241 _zip_dirent_finalize(zip_dirent_t *zde)
242 {
243     if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
244         _zip_string_free(zde->filename);
245         zde->filename = NULL;
246     }
247     if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
248         _zip_ef_free(zde->extra_fields);
249         zde->extra_fields = NULL;
250     }
251     if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
252         _zip_string_free(zde->comment);
253         zde->comment = NULL;
254     }
255     if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
256         if (zde->password) {
257             _zip_crypto_clear(zde->password, strlen(zde->password));
258         }
259         free(zde->password);
260         zde->password = NULL;
261     }
262 }
263
264
265 void
266 _zip_dirent_free(zip_dirent_t *zde)
267 {
268     if (zde == NULL)
269         return;
270
271     _zip_dirent_finalize(zde);
272     free(zde);
273 }
274
275
276 void
277 _zip_dirent_init(zip_dirent_t *de)
278 {
279     de->changed = 0;
280     de->local_extra_fields_read = 0;
281     de->cloned = 0;
282
283     de->crc_valid = true;
284     de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
285     de->version_needed = 10; /* 1.0 */
286     de->bitflags = 0;
287     de->comp_method = ZIP_CM_DEFAULT;
288     de->last_mod = 0;
289     de->crc = 0;
290     de->comp_size = 0;
291     de->uncomp_size = 0;
292     de->filename = NULL;
293     de->extra_fields = NULL;
294     de->comment = NULL;
295     de->disk_number = 0;
296     de->int_attrib = 0;
297     de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
298     de->offset = 0;
299     de->compression_level = 0;
300     de->encryption_method = ZIP_EM_NONE;
301     de->password = NULL;
302 }
303
304
305 bool
306 _zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags)
307 {
308     if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX
309         || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
310         return true;
311
312     return false;
313 }
314
315
316 zip_dirent_t *
317 _zip_dirent_new(void)
318 {
319     zip_dirent_t *de;
320
321     if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL)
322         return NULL;
323
324     _zip_dirent_init(de);
325     return de;
326 }
327
328
329 /* _zip_dirent_read(zde, fp, bufp, left, localp, error):
330    Fills the zip directory entry zde.
331
332    If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
333
334    If local is true, it reads a local header instead of a central directory entry.
335
336    Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
337 */
338
339 zip_int64_t
340 _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error)
341 {
342     zip_uint8_t buf[CDENTRYSIZE];
343     zip_uint16_t dostime, dosdate;
344     zip_uint32_t size, variable_size;
345     zip_uint16_t filename_len, comment_len, ef_len;
346
347     bool from_buffer = (buffer != NULL);
348
349     size = local ? LENTRYSIZE : CDENTRYSIZE;
350
351     if (buffer) {
352         if (_zip_buffer_left(buffer) < size) {
353             zip_error_set(error, ZIP_ER_NOZIP, 0);
354             return -1;
355         }
356     }
357     else {
358         if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
359             return -1;
360         }
361     }
362
363     if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
364         zip_error_set(error, ZIP_ER_NOZIP, 0);
365         if (!from_buffer) {
366             _zip_buffer_free(buffer);
367         }
368         return -1;
369     }
370
371     /* convert buffercontents to zip_dirent */
372
373     _zip_dirent_init(zde);
374     if (!local)
375         zde->version_madeby = _zip_buffer_get_16(buffer);
376     else
377         zde->version_madeby = 0;
378     zde->version_needed = _zip_buffer_get_16(buffer);
379     zde->bitflags = _zip_buffer_get_16(buffer);
380     zde->comp_method = _zip_buffer_get_16(buffer);
381
382     /* convert to time_t */
383     dostime = _zip_buffer_get_16(buffer);
384     dosdate = _zip_buffer_get_16(buffer);
385     zde->last_mod = _zip_d2u_time(dostime, dosdate);
386
387     zde->crc = _zip_buffer_get_32(buffer);
388     zde->comp_size = _zip_buffer_get_32(buffer);
389     zde->uncomp_size = _zip_buffer_get_32(buffer);
390
391     filename_len = _zip_buffer_get_16(buffer);
392     ef_len = _zip_buffer_get_16(buffer);
393
394     if (local) {
395         comment_len = 0;
396         zde->disk_number = 0;
397         zde->int_attrib = 0;
398         zde->ext_attrib = 0;
399         zde->offset = 0;
400     } else {
401         comment_len = _zip_buffer_get_16(buffer);
402         zde->disk_number = _zip_buffer_get_16(buffer);
403         zde->int_attrib = _zip_buffer_get_16(buffer);
404         zde->ext_attrib = _zip_buffer_get_32(buffer);
405         zde->offset = _zip_buffer_get_32(buffer);
406     }
407
408     if (!_zip_buffer_ok(buffer)) {
409         zip_error_set(error, ZIP_ER_INTERNAL, 0);
410         if (!from_buffer) {
411             _zip_buffer_free(buffer);
412         }
413         return -1;
414     }
415
416     if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
417         if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
418             /* TODO */
419             zde->encryption_method = ZIP_EM_UNKNOWN;
420         }
421         else {
422             zde->encryption_method = ZIP_EM_TRAD_PKWARE;
423         }
424     }
425     else {
426         zde->encryption_method = ZIP_EM_NONE;
427     }
428
429     zde->filename = NULL;
430     zde->extra_fields = NULL;
431     zde->comment = NULL;
432
433     variable_size = (zip_uint32_t)filename_len+(zip_uint32_t)ef_len+(zip_uint32_t)comment_len;
434
435     if (from_buffer) {
436         if (_zip_buffer_left(buffer) < variable_size) {
437             zip_error_set(error, ZIP_ER_INCONS, 0);
438             return -1;
439         }
440     }
441     else {
442         _zip_buffer_free(buffer);
443
444         if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
445             return -1;
446         }
447     }
448
449     if (filename_len) {
450         zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
451         if (!zde->filename) {
452             if (zip_error_code_zip(error) == ZIP_ER_EOF) {
453                 zip_error_set(error, ZIP_ER_INCONS, 0);
454             }
455             if (!from_buffer) {
456                 _zip_buffer_free(buffer);
457             }
458             return -1;
459         }
460
461         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
462             if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
463                 zip_error_set(error, ZIP_ER_INCONS, 0);
464                 if (!from_buffer) {
465                     _zip_buffer_free(buffer);
466                 }
467                 return -1;
468             }
469         }
470     }
471
472     if (ef_len) {
473         zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
474
475         if (ef == NULL) {
476             if (!from_buffer) {
477                 _zip_buffer_free(buffer);
478             }
479             return -1;
480         }
481         if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
482             free(ef);
483             if (!from_buffer) {
484                 _zip_buffer_free(buffer);
485             }
486             return -1;
487         }
488         free(ef);
489         if (local)
490             zde->local_extra_fields_read = 1;
491     }
492
493     if (comment_len) {
494         zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
495         if (!zde->comment) {
496             if (!from_buffer) {
497                 _zip_buffer_free(buffer);
498             }
499             return -1;
500         }
501         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
502             if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
503                 zip_error_set(error, ZIP_ER_INCONS, 0);
504                 if (!from_buffer) {
505                     _zip_buffer_free(buffer);
506                 }
507                 return -1;
508             }
509         }
510     }
511
512     zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
513     zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
514
515     /* Zip64 */
516
517     if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
518         zip_uint16_t got_len;
519         zip_buffer_t *ef_buffer;
520         const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
521         /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
522         if (ef == NULL) {
523             if (!from_buffer) {
524                 _zip_buffer_free(buffer);
525             }
526             return -1;
527         }
528
529         if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
530             zip_error_set(error, ZIP_ER_MEMORY, 0);
531             if (!from_buffer) {
532                 _zip_buffer_free(buffer);
533             }
534             return -1;
535         }
536
537         if (zde->uncomp_size == ZIP_UINT32_MAX)
538             zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
539         else if (local) {
540             /* From appnote.txt: This entry in the Local header MUST
541                include BOTH original and compressed file size fields. */
542             (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
543         }
544         if (zde->comp_size == ZIP_UINT32_MAX)
545             zde->comp_size = _zip_buffer_get_64(ef_buffer);
546         if (!local) {
547             if (zde->offset == ZIP_UINT32_MAX)
548                 zde->offset = _zip_buffer_get_64(ef_buffer);
549             if (zde->disk_number == ZIP_UINT16_MAX)
550                 zde->disk_number = _zip_buffer_get_32(buffer);
551         }
552
553         if (!_zip_buffer_eof(ef_buffer)) {
554             zip_error_set(error, ZIP_ER_INCONS, 0);
555             _zip_buffer_free(ef_buffer);
556             if (!from_buffer) {
557                 _zip_buffer_free(buffer);
558             }
559             return -1;
560         }
561         _zip_buffer_free(ef_buffer);
562     }
563
564     if (!_zip_buffer_ok(buffer)) {
565         zip_error_set(error, ZIP_ER_INTERNAL, 0);
566         if (!from_buffer) {
567             _zip_buffer_free(buffer);
568         }
569         return -1;
570     }
571     if (!from_buffer) {
572         _zip_buffer_free(buffer);
573     }
574
575     /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
576     if (zde->offset > ZIP_INT64_MAX) {
577         zip_error_set(error, ZIP_ER_SEEK, EFBIG);
578         return -1;
579     }
580
581     if (!_zip_dirent_process_winzip_aes(zde, error)) {
582         return -1;
583     }
584
585     zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
586
587     return (zip_int64_t)(size + variable_size);
588 }
589
590
591 static zip_string_t *
592 _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str)
593 {
594     zip_uint16_t ef_len;
595     zip_uint32_t ef_crc;
596     zip_buffer_t *buffer;
597
598     const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
599
600     if (ef == NULL || ef_len < 5 || ef[0] != 1) {
601         return str;
602     }
603
604     if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
605         return str;
606     }
607
608     _zip_buffer_get_8(buffer);
609     ef_crc = _zip_buffer_get_32(buffer);
610
611     if (_zip_string_crc32(str) == ef_crc) {
612         zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
613         zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
614
615         if (ef_str != NULL) {
616             _zip_string_free(str);
617             str = ef_str;
618         }
619     }
620
621     _zip_buffer_free(buffer);
622
623     return str;
624 }
625
626
627 static bool
628 _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error)
629 {
630     zip_uint16_t ef_len;
631     zip_buffer_t *buffer;
632     const zip_uint8_t *ef;
633     bool crc_valid;
634     zip_uint16_t enc_method;
635
636
637     if (de->comp_method != ZIP_CM_WINZIP_AES) {
638         return true;
639     }
640
641     ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
642
643     if (ef == NULL || ef_len < 7) {
644         zip_error_set(error, ZIP_ER_INCONS, 0);
645         return false;
646     }
647
648     if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
649         zip_error_set(error, ZIP_ER_INTERNAL, 0);
650         return false;
651     }
652
653     /* version */
654
655     crc_valid = true;
656     switch (_zip_buffer_get_16(buffer)) {
657     case 1:
658         break;
659
660     case 2:
661         if (de->uncomp_size < 20 /* TODO: constant */) {
662             crc_valid = false;
663         }
664         break;
665
666     default:
667         zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
668         _zip_buffer_free(buffer);
669         return false;
670     }
671
672     /* vendor */
673     if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
674         zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
675         _zip_buffer_free(buffer);
676         return false;
677     }
678
679     /* mode */
680     switch (_zip_buffer_get_8(buffer)) {
681     case 1:
682         enc_method = ZIP_EM_AES_128;
683         break;
684     case 2:
685         enc_method = ZIP_EM_AES_192;
686         break;
687     case 3:
688         enc_method = ZIP_EM_AES_256;
689         break;
690     default:
691         zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
692         _zip_buffer_free(buffer);
693         return false;
694     }
695
696     if (ef_len != 7) {
697         zip_error_set(error, ZIP_ER_INCONS, 0);
698         _zip_buffer_free(buffer);
699         return false;
700     }
701
702     de->crc_valid = crc_valid;
703     de->encryption_method = enc_method;
704     de->comp_method = _zip_buffer_get_16(buffer);
705
706     _zip_buffer_free(buffer);
707     return true;
708 }
709
710
711 zip_int32_t
712 _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
713 {
714     zip_int32_t size;
715     bool local = (flags & ZIP_EF_LOCAL) != 0;
716     int i;
717     zip_uint8_t b[6];
718     zip_buffer_t *buffer;
719
720     size = local ? LENTRYSIZE : CDENTRYSIZE;
721
722     if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
723         _zip_error_set_from_source(error, src);
724         return -1;
725     }
726
727     if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
728         return -1;
729     }
730
731     for (i=0; i<(local ? 2 : 3); i++) {
732         size += _zip_buffer_get_16(buffer);
733     }
734
735     if (!_zip_buffer_eof(buffer)) {
736         zip_error_set(error, ZIP_ER_INTERNAL, 0);
737         _zip_buffer_free(buffer);
738         return -1;
739     }
740
741     _zip_buffer_free(buffer);
742     return size;
743 }
744
745
746 /* _zip_dirent_write
747    Writes zip directory entry.
748
749    If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
750    directory entry.  If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
751
752    Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
753    returned.
754 */
755
756 int
757 _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
758 {
759     zip_uint16_t dostime, dosdate;
760     zip_encoding_type_t com_enc, name_enc;
761     zip_extra_field_t *ef;
762     zip_extra_field_t *ef64;
763     zip_uint32_t ef_total_size;
764     bool is_zip64;
765     bool is_really_zip64;
766     bool is_winzip_aes;
767     zip_uint8_t buf[CDENTRYSIZE];
768     zip_buffer_t *buffer;
769
770     ef = NULL;
771
772     name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
773     com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
774
775     if ((name_enc == ZIP_ENCODING_UTF8_KNOWN  && com_enc == ZIP_ENCODING_ASCII) ||
776         (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) ||
777         (name_enc == ZIP_ENCODING_UTF8_KNOWN  && com_enc == ZIP_ENCODING_UTF8_KNOWN))
778         de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
779     else {
780         de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
781         if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
782             ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
783             if (ef == NULL)
784                 return -1;
785         }
786         if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){
787             zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
788             if (ef2 == NULL) {
789                 _zip_ef_free(ef);
790                 return -1;
791             }
792             ef2->next = ef;
793             ef = ef2;
794         }
795     }
796
797     if (de->encryption_method == ZIP_EM_NONE) {
798         de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED;
799     }
800     else {
801         de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED;
802     }
803
804     is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
805     is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
806     is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;
807
808     if (is_zip64) {
809         zip_uint8_t ef_zip64[EFZIP64SIZE];
810         zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
811         if (ef_buffer == NULL) {
812             zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
813             _zip_ef_free(ef);
814             return -1;
815         }
816
817         if (flags & ZIP_FL_LOCAL) {
818             if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
819                 _zip_buffer_put_64(ef_buffer, de->uncomp_size);
820                 _zip_buffer_put_64(ef_buffer, de->comp_size);
821             }
822         }
823         else {
824             if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
825                 if (de->uncomp_size >= ZIP_UINT32_MAX) {
826                     _zip_buffer_put_64(ef_buffer, de->uncomp_size);
827                 }
828                 if (de->comp_size >= ZIP_UINT32_MAX) {
829                     _zip_buffer_put_64(ef_buffer, de->comp_size);
830                 }
831                 if (de->offset >= ZIP_UINT32_MAX) {
832                     _zip_buffer_put_64(ef_buffer, de->offset);
833                 }
834             }
835         }
836
837         if (!_zip_buffer_ok(ef_buffer)) {
838             zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
839             _zip_buffer_free(ef_buffer);
840             _zip_ef_free(ef);
841             return -1;
842         }
843
844         ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
845         _zip_buffer_free(ef_buffer);
846         ef64->next = ef;
847         ef = ef64;
848     }
849
850     if (is_winzip_aes) {
851         zip_uint8_t data[EF_WINZIP_AES_SIZE];
852         zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
853         zip_extra_field_t *ef_winzip;
854         
855         if (ef_buffer == NULL) {
856             zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
857             _zip_ef_free(ef);
858             return -1;
859         }
860
861         _zip_buffer_put_16(ef_buffer, 2);
862         _zip_buffer_put(ef_buffer, "AE", 2);
863         _zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff));
864         _zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);
865
866         if (!_zip_buffer_ok(ef_buffer)) {
867             zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
868             _zip_buffer_free(ef_buffer);
869             _zip_ef_free(ef);
870             return -1;
871         }
872
873         ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH);
874         _zip_buffer_free(ef_buffer);
875         ef_winzip->next = ef;
876         ef = ef_winzip;
877     }
878
879     if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
880         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
881         _zip_ef_free(ef);
882         return -1;
883     }
884
885     _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
886
887     if ((flags & ZIP_FL_LOCAL) == 0) {
888         _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
889     }
890     _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
891     _zip_buffer_put_16(buffer, de->bitflags);
892     if (is_winzip_aes) {
893         _zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
894     }
895     else {
896         _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
897     }
898
899     _zip_u2d_time(de->last_mod, &dostime, &dosdate);
900     _zip_buffer_put_16(buffer, dostime);
901     _zip_buffer_put_16(buffer, dosdate);
902
903     if (is_winzip_aes && de->uncomp_size < 20)  {
904         _zip_buffer_put_32(buffer, 0);
905     }
906     else {
907         _zip_buffer_put_32(buffer, de->crc);
908     }
909
910     if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
911         /* In local headers, if a ZIP64 EF is written, it MUST contain
912          * both compressed and uncompressed sizes (even if one of the
913          * two is smaller than 0xFFFFFFFF); on the other hand, those
914          * may only appear when the corresponding standard entry is
915          * 0xFFFFFFFF.  (appnote.txt 4.5.3) */
916         _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
917         _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
918     }
919     else {
920         if (de->comp_size < ZIP_UINT32_MAX) {
921             _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
922         }
923         else {
924             _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
925         }
926         if (de->uncomp_size < ZIP_UINT32_MAX) {
927             _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
928         }
929         else {
930             _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
931         }
932     }
933
934     _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
935     /* TODO: check for overflow */
936     ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
937     _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
938
939     if ((flags & ZIP_FL_LOCAL) == 0) {
940         _zip_buffer_put_16(buffer, _zip_string_length(de->comment));
941         _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
942         _zip_buffer_put_16(buffer, de->int_attrib);
943         _zip_buffer_put_32(buffer, de->ext_attrib);
944         if (de->offset < ZIP_UINT32_MAX)
945             _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
946         else
947             _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
948     }
949
950     if (!_zip_buffer_ok(buffer)) {
951         zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
952         _zip_buffer_free(buffer);
953         _zip_ef_free(ef);
954         return -1;
955     }
956
957     if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
958         _zip_buffer_free(buffer);
959         _zip_ef_free(ef);
960         return -1;
961     }
962
963     _zip_buffer_free(buffer);
964
965     if (de->filename) {
966         if (_zip_string_write(za, de->filename) < 0) {
967             _zip_ef_free(ef);
968             return -1;
969         }
970     }
971
972     if (ef) {
973         if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
974             _zip_ef_free(ef);
975             return -1;
976         }
977     }
978     _zip_ef_free(ef);
979     if (de->extra_fields) {
980         if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
981             return -1;
982         }
983     }
984
985     if ((flags & ZIP_FL_LOCAL) == 0) {
986         if (de->comment) {
987             if (_zip_string_write(za, de->comment) < 0) {
988                 return -1;
989             }
990         }
991     }
992
993
994     return is_zip64;
995 }
996
997
998 static time_t
999 _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
1000 {
1001     struct tm tm;
1002
1003     memset(&tm, 0, sizeof(tm));
1004
1005     /* let mktime decide if DST is in effect */
1006     tm.tm_isdst = -1;
1007
1008     tm.tm_year = ((ddate>>9)&127) + 1980 - 1900;
1009     tm.tm_mon = ((ddate>>5)&15) - 1;
1010     tm.tm_mday = ddate&31;
1011
1012     tm.tm_hour = (dtime>>11)&31;
1013     tm.tm_min = (dtime>>5)&63;
1014     tm.tm_sec = (dtime<<1)&62;
1015
1016     return mktime(&tm);
1017 }
1018
1019
1020 static zip_extra_field_t *
1021 _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error)
1022 {
1023     const zip_uint8_t *raw;
1024     zip_uint32_t len;
1025     zip_buffer_t *buffer;
1026     zip_extra_field_t *ef;
1027
1028     if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
1029         /* error already set */
1030         return NULL;
1031     }
1032
1033     if (len+5 > ZIP_UINT16_MAX) {
1034         zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
1035         return NULL;
1036     }
1037
1038     if ((buffer = _zip_buffer_new(NULL, len+5)) == NULL) {
1039         zip_error_set(error, ZIP_ER_MEMORY, 0);
1040         return NULL;
1041     }
1042
1043     _zip_buffer_put_8(buffer, 1);
1044     _zip_buffer_put_32(buffer, _zip_string_crc32(str));
1045     _zip_buffer_put(buffer, raw, len);
1046
1047     if (!_zip_buffer_ok(buffer)) {
1048         zip_error_set(error, ZIP_ER_INTERNAL, 0);
1049         _zip_buffer_free(buffer);
1050         return NULL;
1051     }
1052
1053     ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
1054     _zip_buffer_free(buffer);
1055
1056     return ef;
1057 }
1058
1059
1060 zip_dirent_t *
1061 _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
1062 {
1063     if (error == NULL)
1064         error = &za->error;
1065
1066     if (idx >= za->nentry) {
1067         zip_error_set(error, ZIP_ER_INVAL, 0);
1068         return NULL;
1069     }
1070
1071     if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
1072         if (za->entry[idx].orig == NULL) {
1073             zip_error_set(error, ZIP_ER_INVAL, 0);
1074             return NULL;
1075         }
1076         if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
1077             zip_error_set(error, ZIP_ER_DELETED, 0);
1078             return NULL;
1079         }
1080         return za->entry[idx].orig;
1081     }
1082     else
1083         return za->entry[idx].changes;
1084 }
1085
1086
1087
1088
1089 void
1090 _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate)
1091 {
1092     struct tm *tm;
1093
1094     tm = localtime(&intime);
1095     if (tm->tm_year < 80) {
1096         tm->tm_year = 80;
1097     }
1098
1099     *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
1100     *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
1101
1102     return;
1103 }
1104
1105
1106 void
1107 _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) {
1108     zip_uint16_t length;
1109
1110     if (de->comp_method == ZIP_CM_LZMA) {
1111         de->version_needed = 63;
1112         return;
1113     }
1114
1115     if (de->comp_method == ZIP_CM_BZIP2) {
1116         de->version_needed = 46;
1117         return;
1118     }
1119
1120     if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
1121         de->version_needed = 45;
1122         return;
1123     }
1124     
1125     if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
1126         de->version_needed = 20;
1127         return;
1128     }
1129
1130     /* directory */
1131     if ((length = _zip_string_length(de->filename)) > 0) {
1132         if (de->filename->raw[length-1] == '/') {
1133             de->version_needed = 20;
1134             return;
1135         }
1136     }
1137     
1138     de->version_needed = 10;
1139 }