Coverage Report

Created: 2026-08-13 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libzip/lib/zip_dirent.c
Line
Count
Source
1
/*
2
  zip_dirent.c -- read directory entry (local or central), clean dirent
3
  Copyright (C) 1999-2025 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 <info@libzip.org>
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
#include "zipint.h"
35
36
37
#include <stdio.h>
38
#include <stdlib.h>
39
#include <string.h>
40
#include <sys/types.h>
41
#include <time.h>
42
#include <zlib.h>
43
44
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency);
45
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
46
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
47
48
49
104k
void _zip_cdir_free(zip_cdir_t *cd) {
50
104k
    zip_uint64_t i;
51
52
104k
    if (cd == NULL) {
53
0
        return;
54
0
    }
55
56
136M
    for (i = 0; i < cd->nentry; i++) {
57
136M
        _zip_entry_finalize(cd->entry + i);
58
136M
    }
59
104k
    free(cd->entry);
60
104k
    _zip_string_free(cd->comment);
61
104k
    free(cd);
62
104k
}
63
64
65
112k
zip_cdir_t *_zip_cdir_new(zip_error_t *error) {
66
112k
    zip_cdir_t *cd;
67
68
112k
    if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
69
0
        zip_error_set(error, ZIP_ER_MEMORY, 0);
70
0
        return NULL;
71
0
    }
72
73
112k
    cd->entry = NULL;
74
112k
    cd->nentry = cd->nentry_alloc = 0;
75
112k
    cd->size = cd->offset = 0;
76
112k
    cd->comment = NULL;
77
112k
    cd->is_zip64 = false;
78
79
112k
    return cd;
80
112k
}
81
82
83
13.6k
bool _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) {
84
13.6k
    zip_uint64_t i;
85
86
13.6k
    if (additional_entries == 0) {
87
2.23k
        return true;
88
2.23k
    }
89
90
11.4k
    if (!ZIP_REALLOC(cd->entry, cd->nentry_alloc, additional_entries, error)) {
91
0
        return false;
92
0
    }
93
94
136M
    for (i = cd->nentry; i < cd->nentry_alloc; i++) {
95
136M
        _zip_entry_init(cd->entry + i);
96
136M
    }
97
98
11.4k
    cd->nentry = cd->nentry_alloc;
99
100
11.4k
    return true;
101
11.4k
}
102
103
104
4.68k
zip_int64_t _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
105
4.68k
    zip_uint64_t offset, size;
106
4.68k
    zip_string_t *comment;
107
4.68k
    zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
108
4.68k
    zip_buffer_t *buffer;
109
4.68k
    zip_int64_t off;
110
4.68k
    zip_uint64_t i;
111
4.68k
    zip_uint32_t cdir_crc;
112
113
4.68k
    if ((off = zip_source_tell_write(za->src)) < 0) {
114
0
        zip_error_set_from_source(&za->error, za->src);
115
0
        return -1;
116
0
    }
117
4.68k
    offset = (zip_uint64_t)off;
118
119
4.68k
    if (ZIP_WANT_TORRENTZIP(za)) {
120
0
        cdir_crc = (zip_uint32_t)crc32(0, NULL, 0);
121
0
        za->write_crc = &cdir_crc;
122
0
    }
123
124
25.3k
    for (i = 0; i < survivors; i++) {
125
20.6k
        zip_entry_t *entry = za->entry + filelist[i].idx;
126
127
20.6k
        if (_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL) < 0) {
128
0
            za->write_crc = NULL;
129
0
            return -1;
130
0
        }
131
20.6k
    }
132
133
4.68k
    za->write_crc = NULL;
134
135
4.68k
    if ((off = zip_source_tell_write(za->src)) < 0) {
136
0
        zip_error_set_from_source(&za->error, za->src);
137
0
        return -1;
138
0
    }
139
4.68k
    size = (zip_uint64_t)off - offset;
140
141
4.68k
    if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
142
0
        zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
143
0
        return -1;
144
0
    }
145
146
4.68k
    if (survivors > ZIP_UINT16_MAX || offset > ZIP_UINT32_MAX || size > ZIP_UINT32_MAX) {
147
0
        _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
148
0
        _zip_buffer_put_64(buffer, EOCD64LEN - 12);
149
0
        _zip_buffer_put_16(buffer, 45);
150
0
        _zip_buffer_put_16(buffer, 45);
151
0
        _zip_buffer_put_32(buffer, 0);
152
0
        _zip_buffer_put_32(buffer, 0);
153
0
        _zip_buffer_put_64(buffer, survivors);
154
0
        _zip_buffer_put_64(buffer, survivors);
155
0
        _zip_buffer_put_64(buffer, size);
156
0
        _zip_buffer_put_64(buffer, offset);
157
0
        _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
158
0
        _zip_buffer_put_32(buffer, 0);
159
0
        _zip_buffer_put_64(buffer, offset + size);
160
0
        _zip_buffer_put_32(buffer, 1);
161
0
    }
162
163
4.68k
    _zip_buffer_put(buffer, EOCD_MAGIC, 4);
164
4.68k
    _zip_buffer_put_32(buffer, 0);
165
4.68k
    _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
166
4.68k
    _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
167
4.68k
    _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
168
4.68k
    _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
169
170
4.68k
    comment = za->comment_changed ? za->comment_changes : za->comment_orig;
171
172
4.68k
    if (ZIP_WANT_TORRENTZIP(za)) {
173
0
        _zip_buffer_put_16(buffer, TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH);
174
0
    }
175
4.68k
    else {
176
4.68k
        _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
177
4.68k
    }
178
179
180
4.68k
    if (!_zip_buffer_ok(buffer)) {
181
0
        zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
182
0
        _zip_buffer_free(buffer);
183
0
        return -1;
184
0
    }
185
186
4.68k
    if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
187
0
        _zip_buffer_free(buffer);
188
0
        return -1;
189
0
    }
190
191
4.68k
    _zip_buffer_free(buffer);
192
193
4.68k
    if (ZIP_WANT_TORRENTZIP(za)) {
194
0
        char torrentzip_comment[TORRENTZIP_SIGNATURE_LENGTH + TORRENTZIP_CRC_LENGTH + 1];
195
0
        snprintf(torrentzip_comment, sizeof(torrentzip_comment), TORRENTZIP_SIGNATURE "%08X", cdir_crc);
196
197
0
        if (_zip_write(za, torrentzip_comment, strlen(torrentzip_comment)) < 0) {
198
0
            return -1;
199
0
        }
200
0
    }
201
4.68k
    else if (comment != NULL) {
202
495
        if (_zip_write(za, comment->raw, comment->length) < 0) {
203
0
            return -1;
204
0
        }
205
495
    }
206
207
4.68k
    return (zip_int64_t)size;
208
4.68k
}
209
210
211
21.1k
zip_dirent_t *_zip_dirent_clone(const zip_dirent_t *sde) {
212
21.1k
    zip_dirent_t *tde;
213
214
21.1k
    if ((tde = (zip_dirent_t *)malloc(sizeof(*tde))) == NULL) {
215
0
        return NULL;
216
0
    }
217
218
21.1k
    if (sde) {
219
0
        (void)memcpy_s(tde, sizeof(*tde), sde, sizeof(*sde));
220
0
        _zip_extra_fields_clone(&tde->extra_fields, NULL);
221
0
    }
222
21.1k
    else {
223
21.1k
        _zip_dirent_init(tde);
224
21.1k
    }
225
226
21.1k
    tde->changed = 0;
227
21.1k
    tde->cloned = 1;
228
229
21.1k
    return tde;
230
21.1k
}
231
232
233
278k
void _zip_dirent_finalize(zip_dirent_t *zde) {
234
278k
    if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
235
278k
        _zip_string_free(zde->filename);
236
278k
        zde->filename = NULL;
237
278k
    }
238
278k
    if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
239
278k
        _zip_extra_fields_fini(&zde->extra_fields);
240
278k
    }
241
278k
    if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
242
259k
        _zip_string_free(zde->comment);
243
259k
        zde->comment = NULL;
244
259k
    }
245
278k
    if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
246
271k
        if (zde->password) {
247
14.3k
            _zip_crypto_clear(zde->password, strlen(zde->password));
248
14.3k
        }
249
271k
        free(zde->password);
250
271k
        zde->password = NULL;
251
271k
    }
252
278k
}
253
254
255
272M
void _zip_dirent_free(zip_dirent_t *zde) {
256
272M
    if (zde == NULL) {
257
272M
        return;
258
272M
    }
259
260
278k
    _zip_dirent_finalize(zde);
261
278k
    free(zde);
262
278k
}
263
264
265
0
bool _zip_dirent_merge(zip_dirent_t *de, zip_dirent_t *de_orig, bool replacing_data, zip_error_t *error) {
266
0
    if (!de->cloned) {
267
0
        zip_error_set(error, ZIP_ER_INTERNAL, 0);
268
0
        return false;
269
0
    }
270
271
0
    if (!(de->changed & ZIP_DIRENT_ATTRIBUTES)) {
272
0
        de->ext_attrib = de_orig->ext_attrib;
273
0
        de->int_attrib = de_orig->int_attrib;
274
0
    }
275
0
    if (!(de->changed & ZIP_DIRENT_COMMENT)) {
276
0
        de->comment = de_orig->comment;
277
0
    }
278
0
    if (!(de->changed & ZIP_DIRENT_COMP_METHOD)) {
279
0
        if (replacing_data) {
280
0
            de->comp_method = ZIP_CM_DEFAULT;
281
0
            de->compression_level = 0;
282
0
        }
283
0
        else {
284
0
            de->comp_method = de_orig->comp_method;
285
0
            de->compression_level = de_orig->compression_level;
286
0
        }
287
0
    }
288
0
    if (!(de->changed & ZIP_DIRENT_ENCRYPTION_METHOD)) {
289
0
        if (replacing_data) {
290
0
            de->encryption_method = ZIP_EM_NONE;
291
0
        }
292
0
        else {
293
0
            de->encryption_method = de_orig->encryption_method;
294
0
        }
295
0
    }
296
0
    if (!(de->changed & ZIP_DIRENT_EXTRA_FIELD)) {
297
0
        de->extra_fields = de_orig->extra_fields;
298
0
    }
299
0
    if (!(de->changed & ZIP_DIRENT_FILENAME)) {
300
0
        de->filename = de_orig->filename;
301
0
    }
302
0
    if (!(de->changed & ZIP_DIRENT_LAST_MOD)) {
303
0
        de->last_mod = de_orig->last_mod;
304
0
    }
305
0
    if (!(de->changed & ZIP_DIRENT_PASSWORD)) {
306
0
        de->password = de_orig->password;
307
0
    }
308
309
0
    return true;
310
0
}
311
312
313
534k
void _zip_dirent_init(zip_dirent_t *de) {
314
534k
    de->changed = 0;
315
534k
    de->local_extra_fields_read = 0;
316
534k
    de->cloned = 0;
317
318
534k
    de->crc_valid = true;
319
534k
    de->last_mod_mtime_valid = false;
320
534k
    de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
321
534k
    de->version_needed = 10; /* 1.0 */
322
534k
    de->bitflags = 0;
323
534k
    de->comp_method = ZIP_CM_DEFAULT;
324
534k
    de->last_mod.date = 0;
325
534k
    de->last_mod.time = 0;
326
534k
    de->crc = 0;
327
534k
    de->comp_size = 0;
328
534k
    de->uncomp_size = 0;
329
534k
    de->filename = NULL;
330
534k
    _zip_extra_fields_init(&de->extra_fields);
331
534k
    de->comment = NULL;
332
534k
    de->disk_number = 0;
333
534k
    de->int_attrib = 0;
334
534k
    de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
335
534k
    de->offset = 0;
336
534k
    de->compression_level = 0;
337
534k
    de->encryption_method = ZIP_EM_NONE;
338
534k
    de->password = NULL;
339
534k
}
340
341
342
85.8k
bool _zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) {
343
85.8k
    if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) {
344
0
        return true;
345
0
    }
346
347
85.8k
    return false;
348
85.8k
}
349
350
351
257k
zip_dirent_t *_zip_dirent_new(void) {
352
257k
    zip_dirent_t *de;
353
354
257k
    if ((de = (zip_dirent_t *)malloc(sizeof(*de))) == NULL) {
355
0
        return NULL;
356
0
    }
357
358
257k
    _zip_dirent_init(de);
359
257k
    return de;
360
257k
}
361
362
363
/*
364
   Fills the zip directory entry zde.
365
366
   If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
367
368
   If local is true, it reads a local header instead of a central directory entry.
369
370
   Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
371
*/
372
373
257k
zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, bool is_zip64, zip_uint64_t central_compressed_size, bool check_consistency, zip_error_t *error) {
374
257k
    zip_uint8_t buf[CDENTRYSIZE];
375
257k
    zip_uint32_t size, variable_size;
376
257k
    zip_uint16_t filename_len, comment_len, ef_len;
377
257k
    zip_string_t *utf8_string;
378
257k
    zip_extra_field_t **efp;
379
380
257k
    bool from_buffer = (buffer != NULL);
381
382
257k
    size = local ? LENTRYSIZE : CDENTRYSIZE;
383
384
257k
    if (buffer) {
385
110k
        if (_zip_buffer_left(buffer) < size) {
386
510
            zip_error_set(error, ZIP_ER_NOZIP, 0);
387
510
            return -1;
388
510
        }
389
110k
    }
390
146k
    else {
391
146k
        if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
392
38
            return -1;
393
38
        }
394
146k
    }
395
396
256k
    if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
397
317
        zip_error_set(error, ZIP_ER_NOZIP, 0);
398
317
        if (!from_buffer) {
399
107
            _zip_buffer_free(buffer);
400
107
        }
401
317
        return -1;
402
317
    }
403
404
    /* convert buffercontents to zip_dirent */
405
406
256k
    _zip_dirent_init(zde);
407
256k
    if (!local) {
408
256k
        zde->version_madeby = _zip_buffer_get_16(buffer);
409
256k
    }
410
0
    else {
411
0
        zde->version_madeby = 0;
412
0
    }
413
256k
    zde->version_needed = _zip_buffer_get_16(buffer);
414
256k
    zde->bitflags = _zip_buffer_get_16(buffer);
415
256k
    zde->comp_method = _zip_buffer_get_16(buffer);
416
417
    /* convert to time_t */
418
256k
    zde->last_mod.time = _zip_buffer_get_16(buffer);
419
256k
    zde->last_mod.date = _zip_buffer_get_16(buffer);
420
421
256k
    zde->crc = _zip_buffer_get_32(buffer);
422
256k
    zde->comp_size = _zip_buffer_get_32(buffer);
423
256k
    zde->uncomp_size = _zip_buffer_get_32(buffer);
424
425
256k
    filename_len = _zip_buffer_get_16(buffer);
426
256k
    ef_len = _zip_buffer_get_16(buffer);
427
428
256k
    if (local) {
429
0
        comment_len = 0;
430
0
        zde->disk_number = 0;
431
0
        zde->int_attrib = 0;
432
0
        zde->ext_attrib = 0;
433
0
        zde->offset = 0;
434
0
    }
435
256k
    else {
436
256k
        comment_len = _zip_buffer_get_16(buffer);
437
256k
        zde->disk_number = _zip_buffer_get_16(buffer);
438
256k
        zde->int_attrib = _zip_buffer_get_16(buffer);
439
256k
        zde->ext_attrib = _zip_buffer_get_32(buffer);
440
256k
        zde->offset = _zip_buffer_get_32(buffer);
441
256k
    }
442
443
256k
    if (!_zip_buffer_ok(buffer)) {
444
0
        zip_error_set(error, ZIP_ER_INTERNAL, 0);
445
0
        if (!from_buffer) {
446
0
            _zip_buffer_free(buffer);
447
0
        }
448
0
        return -1;
449
0
    }
450
451
256k
    if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
452
53.9k
        if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
453
            /* TODO */
454
24.6k
            zde->encryption_method = ZIP_EM_UNKNOWN;
455
24.6k
        }
456
29.3k
        else {
457
29.3k
            zde->encryption_method = ZIP_EM_TRAD_PKWARE;
458
29.3k
        }
459
53.9k
    }
460
202k
    else {
461
202k
        zde->encryption_method = ZIP_EM_NONE;
462
202k
    }
463
464
256k
    zde->filename = NULL;
465
256k
    _zip_extra_fields_init(&zde->extra_fields);
466
256k
    zde->comment = NULL;
467
468
256k
    variable_size = (zip_uint32_t)filename_len + (zip_uint32_t)ef_len + (zip_uint32_t)comment_len;
469
470
256k
    if (from_buffer) {
471
109k
        if (_zip_buffer_left(buffer) < variable_size) {
472
210
            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
473
210
            return -1;
474
210
        }
475
109k
    }
476
146k
    else {
477
146k
        _zip_buffer_free(buffer);
478
479
146k
        if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
480
67
            return -1;
481
67
        }
482
146k
    }
483
484
255k
    if (filename_len) {
485
142k
        zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
486
142k
        if (zde->filename == NULL) {
487
0
            if (zip_error_code_zip(error) == ZIP_ER_EOF) {
488
0
                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_VARIABLE_SIZE_OVERFLOW);
489
0
            }
490
0
            if (!from_buffer) {
491
0
                _zip_buffer_free(buffer);
492
0
            }
493
0
            return -1;
494
0
        }
495
496
142k
        if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
497
10.9k
            if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
498
73
                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_FILENAME);
499
73
                if (!from_buffer) {
500
28
                    _zip_buffer_free(buffer);
501
28
                }
502
73
                return -1;
503
73
            }
504
10.9k
        }
505
506
142k
        if (check_consistency) {
507
0
            zip_uint8_t *p;
508
509
0
            for (p = zde->filename->raw; p < zde->filename->raw + zde->filename->length; p++) {
510
0
                if (*p == 0) {
511
0
                    zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_NUL_IN_FILENAME);
512
0
                    if (!from_buffer) {
513
0
                        _zip_buffer_free(buffer);
514
0
                    }
515
0
                    return -1;
516
0
                }
517
0
            }
518
0
        }
519
142k
    }
520
521
255k
    if (ef_len) {
522
63.7k
        zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
523
524
63.7k
        if (ef == NULL) {
525
0
            if (!from_buffer) {
526
0
                _zip_buffer_free(buffer);
527
0
            }
528
0
            return -1;
529
0
        }
530
63.7k
        if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, (local ? &zde->extra_fields.local : &zde->extra_fields.central), error)) {
531
401
            free(ef);
532
401
            if (!from_buffer) {
533
56
                _zip_buffer_free(buffer);
534
56
            }
535
401
            return -1;
536
401
        }
537
63.3k
        free(ef);
538
63.3k
        if (local) {
539
0
            zde->local_extra_fields_read = 1;
540
0
        }
541
63.3k
    }
542
543
255k
    if (comment_len) {
544
14.3k
        zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
545
14.3k
        if (zde->comment == NULL) {
546
0
            if (!from_buffer) {
547
0
                _zip_buffer_free(buffer);
548
0
            }
549
0
            return -1;
550
0
        }
551
14.3k
        if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
552
5.80k
            if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
553
47
                zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_UTF8_IN_COMMENT);
554
47
                if (!from_buffer) {
555
11
                    _zip_buffer_free(buffer);
556
11
                }
557
47
                return -1;
558
47
            }
559
5.80k
        }
560
14.3k
    }
561
562
255k
    if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename, check_consistency)) == NULL && zde->filename != NULL) {
563
0
        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_FILENAME_MISMATCH);
564
0
        if (!from_buffer) {
565
0
            _zip_buffer_free(buffer);
566
0
        }
567
0
        return -1;
568
0
    }
569
255k
    zde->filename = utf8_string;
570
255k
    if (!local) {
571
255k
        if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment, check_consistency)) == NULL && zde->comment != NULL) {
572
0
            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH);
573
0
            if (!from_buffer) {
574
0
                _zip_buffer_free(buffer);
575
0
            }
576
0
            return -1;
577
0
        }
578
255k
        zde->comment = utf8_string;
579
255k
    }
580
581
    /* Zip64 */
582
583
255k
    if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
584
21.7k
        zip_uint16_t got_len;
585
21.7k
        const zip_uint8_t *ef = _zip_extra_fields_get_by_id(&zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
586
21.7k
        if (ef != NULL) {
587
7.81k
            if (!zip_dirent_process_ef_zip64(zde, ef, got_len, local, error)) {
588
1.52k
                if (!from_buffer) {
589
14
                    _zip_buffer_free(buffer);
590
14
                }
591
1.52k
                return -1;
592
1.52k
            }
593
7.81k
        }
594
13.9k
        else if (is_zip64) {
595
2
            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_MISSING_ZIP64_EF);
596
2
            if (!from_buffer) {
597
1
                _zip_buffer_free(buffer);
598
1
            }
599
2
            return -1;
600
2
        }
601
21.7k
    }
602
603
604
253k
    if (!_zip_buffer_ok(buffer)) {
605
0
        zip_error_set(error, ZIP_ER_INTERNAL, 0);
606
0
        if (!from_buffer) {
607
0
            _zip_buffer_free(buffer);
608
0
        }
609
0
        return -1;
610
0
    }
611
612
253k
    if (!from_buffer) {
613
146k
        _zip_buffer_free(buffer);
614
146k
    }
615
616
253k
    if (local && zde->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
617
0
        zip_uint32_t df_crc;
618
0
        zip_uint64_t df_comp_size, df_uncomp_size;
619
620
0
        if (zip_source_seek(src, central_compressed_size, SEEK_CUR) != 0 || (buffer = _zip_buffer_new_from_source(src, MAX_DATA_DESCRIPTOR_LENGTH, buf, error)) == NULL) {
621
0
            return -1;
622
0
        }
623
0
        if (memcmp(_zip_buffer_peek(buffer, MAGIC_LEN), DATADES_MAGIC, MAGIC_LEN) == 0) {
624
0
            _zip_buffer_skip(buffer, MAGIC_LEN);
625
0
        }
626
0
        df_crc = _zip_buffer_get_32(buffer);
627
0
        df_comp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
628
0
        df_uncomp_size = is_zip64 ? _zip_buffer_get_64(buffer) : _zip_buffer_get_32(buffer);
629
630
0
        if (!_zip_buffer_ok(buffer)) {
631
0
            zip_error_set(error, ZIP_ER_INTERNAL, 0);
632
0
            _zip_buffer_free(buffer);
633
0
            return -1;
634
0
        }
635
0
        _zip_buffer_free(buffer);
636
637
        /* According to the appnote, it should be 0, but some implementations write the actual value. */
638
0
        if ((zde->crc != 0 && zde->crc != df_crc) || (zde->comp_size != 0 && zde->comp_size != df_comp_size) || (zde->uncomp_size != 0 && zde->uncomp_size != df_uncomp_size)) {
639
0
            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_DATA_DESCRIPTOR_MISMATCH);
640
0
            return -1;
641
0
        }
642
0
        zde->crc = df_crc;
643
0
        zde->comp_size = df_comp_size;
644
0
        zde->uncomp_size = df_uncomp_size;
645
0
    }
646
647
    /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
648
253k
    if (zde->offset > ZIP_INT64_MAX) {
649
273
        zip_error_set(error, ZIP_ER_SEEK, EFBIG);
650
273
        return -1;
651
273
    }
652
653
253k
    if (!_zip_dirent_process_winzip_aes(zde, error)) {
654
176
        return -1;
655
176
    }
656
657
253k
    efp = local ? &zde->extra_fields.local : &zde->extra_fields.central;
658
253k
    *efp = _zip_ef_remove_internal(*efp);
659
660
253k
    return (zip_int64_t)size + (zip_int64_t)variable_size;
661
253k
}
662
663
7.81k
bool zip_dirent_process_ef_zip64(zip_dirent_t *zde, const zip_uint8_t *ef, zip_uint64_t got_len, bool local, zip_error_t *error) {
664
7.81k
    zip_buffer_t *ef_buffer;
665
666
7.81k
    if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
667
0
        zip_error_set(error, ZIP_ER_MEMORY, 0);
668
0
        return false;
669
0
    }
670
671
7.81k
    if (zde->uncomp_size == ZIP_UINT32_MAX) {
672
4.59k
        zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
673
4.59k
    }
674
3.21k
    else if (local) {
675
        /* From appnote.txt: This entry in the Local header MUST
676
           include BOTH original and compressed file size fields. */
677
0
        (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
678
0
    }
679
7.81k
    if (zde->comp_size == ZIP_UINT32_MAX) {
680
5.43k
        zde->comp_size = _zip_buffer_get_64(ef_buffer);
681
5.43k
    }
682
7.81k
    if (!local) {
683
7.81k
        if (zde->offset == ZIP_UINT32_MAX) {
684
2.96k
            zde->offset = _zip_buffer_get_64(ef_buffer);
685
2.96k
        }
686
7.81k
        if (zde->disk_number == ZIP_UINT16_MAX) {
687
931
            zde->disk_number = _zip_buffer_get_32(ef_buffer);
688
931
        }
689
7.81k
    }
690
691
7.81k
    if (!_zip_buffer_eof(ef_buffer)) {
692
        /* accept additional fields if values match */
693
4.00k
        bool ok = true;
694
4.00k
        switch (got_len) {
695
2.89k
        case 28:
696
2.89k
            _zip_buffer_set_offset(ef_buffer, 24);
697
2.89k
            if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
698
1.06k
                ok = false;
699
1.06k
            }
700
            /* fallthrough */
701
3.71k
        case 24:
702
3.71k
            _zip_buffer_set_offset(ef_buffer, 0);
703
3.71k
            if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer)) || (zde->comp_size != _zip_buffer_get_64(ef_buffer)) || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
704
1.23k
                ok = false;
705
1.23k
            }
706
3.71k
            break;
707
708
285
        default:
709
285
            ok = false;
710
4.00k
        }
711
4.00k
        if (!ok) {
712
1.52k
            zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_ZIP64_EF);
713
1.52k
            _zip_buffer_free(ef_buffer);
714
1.52k
            return false;
715
1.52k
        }
716
4.00k
    }
717
6.28k
    _zip_buffer_free(ef_buffer);
718
719
6.28k
    return true;
720
7.81k
}
721
722
723
510k
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str, bool check_consistency) {
724
510k
    zip_uint16_t ef_len;
725
510k
    zip_uint32_t ef_crc;
726
510k
    zip_buffer_t *buffer;
727
728
510k
    const zip_uint8_t *ef = _zip_extra_fields_get_by_id(&de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
729
730
510k
    if (ef == NULL || ef_len < 5 || ef[0] != 1) {
731
489k
        return str;
732
489k
    }
733
734
21.1k
    if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
735
0
        return str;
736
0
    }
737
738
21.1k
    _zip_buffer_get_8(buffer);
739
21.1k
    ef_crc = _zip_buffer_get_32(buffer);
740
741
21.1k
    if (_zip_string_crc32(str) == ef_crc) {
742
18.3k
        zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
743
18.3k
        zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
744
745
18.3k
        if (ef_str != NULL) {
746
5.28k
            if (check_consistency) {
747
0
                if (!_zip_string_equal(str, ef_str) && _zip_string_is_ascii(ef_str)) {
748
0
                    _zip_string_free(ef_str);
749
0
                    _zip_buffer_free(buffer);
750
0
                    return NULL;
751
0
                }
752
0
            }
753
754
5.28k
            _zip_string_free(str);
755
5.28k
            str = ef_str;
756
5.28k
        }
757
18.3k
    }
758
759
21.1k
    _zip_buffer_free(buffer);
760
761
21.1k
    return str;
762
21.1k
}
763
764
765
253k
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
766
253k
    zip_uint16_t ef_len;
767
253k
    zip_buffer_t *buffer;
768
253k
    const zip_uint8_t *ef;
769
253k
    bool crc_valid;
770
253k
    zip_uint16_t enc_method;
771
772
773
253k
    if (de->comp_method != ZIP_CM_WINZIP_AES) {
774
243k
        return true;
775
243k
    }
776
777
10.1k
    ef = _zip_extra_fields_get_by_id(&de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
778
779
10.1k
    if (ef == NULL || ef_len < 7) {
780
33
        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
781
33
        return false;
782
33
    }
783
784
10.1k
    if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
785
0
        zip_error_set(error, ZIP_ER_INTERNAL, 0);
786
0
        return false;
787
0
    }
788
789
    /* version */
790
791
10.1k
    crc_valid = true;
792
10.1k
    switch (_zip_buffer_get_16(buffer)) {
793
1.42k
    case 1:
794
1.42k
        break;
795
796
8.68k
    case 2:
797
8.68k
        crc_valid = false;
798
        /* TODO: When checking consistency, check that crc is 0. */
799
8.68k
        break;
800
801
5
    default:
802
5
        zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
803
5
        _zip_buffer_free(buffer);
804
5
        return false;
805
10.1k
    }
806
807
    /* vendor */
808
10.1k
    if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
809
106
        zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
810
106
        _zip_buffer_free(buffer);
811
106
        return false;
812
106
    }
813
814
    /* mode */
815
10.0k
    switch (_zip_buffer_get_8(buffer)) {
816
2.75k
    case 1:
817
2.75k
        enc_method = ZIP_EM_AES_128;
818
2.75k
        break;
819
84
    case 2:
820
84
        enc_method = ZIP_EM_AES_192;
821
84
        break;
822
7.15k
    case 3:
823
7.15k
        enc_method = ZIP_EM_AES_256;
824
7.15k
        break;
825
17
    default:
826
17
        zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
827
17
        _zip_buffer_free(buffer);
828
17
        return false;
829
10.0k
    }
830
831
9.99k
    if (ef_len != 7) {
832
15
        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_INVALID_WINZIPAES_EF);
833
15
        _zip_buffer_free(buffer);
834
15
        return false;
835
15
    }
836
837
9.97k
    de->crc_valid = crc_valid;
838
9.97k
    de->encryption_method = enc_method;
839
9.97k
    de->comp_method = _zip_buffer_get_16(buffer);
840
841
9.97k
    _zip_buffer_free(buffer);
842
9.97k
    return true;
843
9.99k
}
844
845
846
51.6k
zip_int32_t _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
847
51.6k
    zip_int32_t size;
848
51.6k
    bool local = (flags & ZIP_EF_LOCAL) != 0;
849
51.6k
    int i;
850
51.6k
    zip_uint8_t b[CDENTRYSIZE];
851
51.6k
    zip_buffer_t *buffer;
852
853
51.6k
    size = local ? LENTRYSIZE : CDENTRYSIZE;
854
855
    /* Central header has fixed fields after size pointers. */
856
51.6k
    if ((buffer = _zip_buffer_new_from_source(src, local ? LENTRYSIZE : 34, b, error)) == NULL) {
857
595
        return -1;
858
595
    }
859
51.0k
    if (_zip_buffer_left(buffer) != (local ? LENTRYSIZE : 34)) {
860
0
        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_ENTRY_INVALID);
861
0
        _zip_buffer_free(buffer);
862
0
        return -1;
863
0
    }
864
865
51.0k
    if (memcmp(_zip_buffer_peek(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
866
22.8k
        zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_ENTRY_INVALID);
867
22.8k
        _zip_buffer_free(buffer);
868
22.8k
        return -1;
869
22.8k
    }
870
871
    /* Skip to size pointers. */
872
28.2k
    _zip_buffer_skip(buffer, local ? 26 : 28);
873
874
84.7k
    for (i = 0; i < (local ? 2 : 3); i++) {
875
56.4k
        size += _zip_buffer_get_16(buffer);
876
56.4k
    }
877
878
28.2k
    _zip_buffer_free(buffer);
879
28.2k
    return size;
880
51.0k
}
881
882
883
/* _zip_dirent_write
884
   Writes zip directory entry.
885
886
   If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
887
   directory entry.  If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
888
889
   Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
890
   returned.
891
*/
892
893
61.0k
int _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
894
61.0k
    zip_dostime_t dostime;
895
61.0k
    zip_encoding_type_t com_enc, name_enc;
896
61.0k
    zip_extra_field_t *ef;
897
61.0k
    zip_extra_field_t *ef64;
898
61.0k
    zip_int32_t ef_size, de_ef_size;
899
61.0k
    bool is_zip64;
900
61.0k
    bool is_really_zip64;
901
61.0k
    bool is_winzip_aes;
902
61.0k
    zip_uint8_t buf[CDENTRYSIZE];
903
61.0k
    zip_buffer_t *buffer;
904
905
61.0k
    ef = NULL;
906
907
61.0k
    name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
908
61.0k
    com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
909
910
61.0k
    if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) {
911
648
        de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
912
648
    }
913
60.4k
    else {
914
60.4k
        de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
915
60.4k
        if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
916
130
            ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
917
130
            if (ef == NULL) {
918
0
                return -1;
919
0
            }
920
130
        }
921
60.4k
        if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN) {
922
68
            zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
923
68
            if (ef2 == NULL) {
924
0
                _zip_ef_free(ef);
925
0
                return -1;
926
0
            }
927
68
            ef2->next = ef;
928
68
            ef = ef2;
929
68
        }
930
60.4k
    }
931
932
61.0k
    if (de->encryption_method == ZIP_EM_NONE) {
933
32.3k
        de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED;
934
32.3k
    }
935
28.7k
    else {
936
28.7k
        de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED;
937
28.7k
    }
938
939
61.0k
    is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
940
61.0k
    is_zip64 = (flags & (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64) || is_really_zip64;
941
61.0k
    is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;
942
943
61.0k
    if (is_zip64) {
944
0
        zip_uint8_t ef_zip64[EFZIP64SIZE];
945
0
        zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
946
0
        if (ef_buffer == NULL) {
947
0
            zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
948
0
            _zip_ef_free(ef);
949
0
            return -1;
950
0
        }
951
952
0
        if (flags & ZIP_FL_LOCAL) {
953
0
            if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
954
0
                _zip_buffer_put_64(ef_buffer, de->uncomp_size);
955
0
                _zip_buffer_put_64(ef_buffer, de->comp_size);
956
0
            }
957
0
        }
958
0
        else {
959
0
            if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
960
0
                if (de->uncomp_size >= ZIP_UINT32_MAX) {
961
0
                    _zip_buffer_put_64(ef_buffer, de->uncomp_size);
962
0
                }
963
0
                if (de->comp_size >= ZIP_UINT32_MAX) {
964
0
                    _zip_buffer_put_64(ef_buffer, de->comp_size);
965
0
                }
966
0
                if (de->offset >= ZIP_UINT32_MAX) {
967
0
                    _zip_buffer_put_64(ef_buffer, de->offset);
968
0
                }
969
0
            }
970
0
        }
971
972
0
        if (!_zip_buffer_ok(ef_buffer)) {
973
0
            zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
974
0
            _zip_buffer_free(ef_buffer);
975
0
            _zip_ef_free(ef);
976
0
            return -1;
977
0
        }
978
979
0
        ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64);
980
0
        _zip_buffer_free(ef_buffer);
981
0
        if (ef64 == NULL) {
982
0
            zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
983
0
            _zip_ef_free(ef);
984
0
            return -1;
985
0
        }
986
0
        ef64->next = ef;
987
0
        ef = ef64;
988
0
    }
989
990
61.0k
    if (is_winzip_aes) {
991
24.8k
        zip_uint8_t data[EF_WINZIP_AES_SIZE];
992
24.8k
        zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
993
24.8k
        zip_extra_field_t *ef_winzip;
994
995
24.8k
        if (ef_buffer == NULL) {
996
0
            zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
997
0
            _zip_ef_free(ef);
998
0
            return -1;
999
0
        }
1000
1001
24.8k
        _zip_buffer_put_16(ef_buffer, 2);
1002
24.8k
        _zip_buffer_put(ef_buffer, "AE", 2);
1003
24.8k
        _zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff));
1004
24.8k
        _zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);
1005
1006
24.8k
        if (!_zip_buffer_ok(ef_buffer)) {
1007
0
            zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
1008
0
            _zip_buffer_free(ef_buffer);
1009
0
            _zip_ef_free(ef);
1010
0
            return -1;
1011
0
        }
1012
1013
24.8k
        ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data);
1014
24.8k
        _zip_buffer_free(ef_buffer);
1015
24.8k
        if (ef_winzip == NULL) {
1016
0
            zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
1017
0
            _zip_ef_free(ef);
1018
0
            return -1;
1019
0
        }
1020
24.8k
        ef_winzip->next = ef;
1021
24.8k
        ef = ef_winzip;
1022
24.8k
    }
1023
1024
61.0k
    if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
1025
0
        zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
1026
0
        _zip_ef_free(ef);
1027
0
        return -1;
1028
0
    }
1029
1030
61.0k
    _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
1031
1032
61.0k
    if ((flags & ZIP_FL_LOCAL) == 0) {
1033
20.6k
        _zip_buffer_put_16(buffer, de->version_madeby);
1034
20.6k
    }
1035
61.0k
    _zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, de->version_needed));
1036
61.0k
    _zip_buffer_put_16(buffer, de->bitflags);
1037
61.0k
    if (is_winzip_aes) {
1038
24.8k
        _zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
1039
24.8k
    }
1040
36.2k
    else {
1041
36.2k
        _zip_buffer_put_16(buffer, (zip_uint16_t)ZIP_CM_ACTUAL(de->comp_method));
1042
36.2k
    }
1043
1044
61.0k
    if (ZIP_WANT_TORRENTZIP(za)) {
1045
0
        dostime.time = 0xbc00;
1046
0
        dostime.date = 0x2198;
1047
0
    }
1048
61.0k
    else {
1049
61.0k
        dostime = de->last_mod;
1050
61.0k
    }
1051
61.0k
    _zip_buffer_put_16(buffer, dostime.time);
1052
61.0k
    _zip_buffer_put_16(buffer, dostime.date);
1053
1054
61.0k
    if (is_winzip_aes && de->uncomp_size < 20) {
1055
6.47k
        _zip_buffer_put_32(buffer, 0);
1056
6.47k
    }
1057
54.5k
    else {
1058
54.5k
        _zip_buffer_put_32(buffer, de->crc);
1059
54.5k
    }
1060
1061
61.0k
    if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
1062
        /* In local headers, if a ZIP64 EF is written, it MUST contain
1063
         * both compressed and uncompressed sizes (even if one of the
1064
         * two is smaller than 0xFFFFFFFF); on the other hand, those
1065
         * may only appear when the corresponding standard entry is
1066
         * 0xFFFFFFFF.  (appnote.txt 4.5.3) */
1067
0
        _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
1068
0
        _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
1069
0
    }
1070
61.0k
    else {
1071
61.0k
        if (de->comp_size < ZIP_UINT32_MAX) {
1072
61.0k
            _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
1073
61.0k
        }
1074
0
        else {
1075
0
            _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
1076
0
        }
1077
61.0k
        if (de->uncomp_size < ZIP_UINT32_MAX) {
1078
61.0k
            _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
1079
61.0k
        }
1080
0
        else {
1081
0
            _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
1082
0
        }
1083
61.0k
    }
1084
1085
61.0k
    _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
1086
1087
61.0k
    ef_size = _zip_ef_size(ef);
1088
61.0k
    if (!ZIP_WANT_TORRENTZIP(za)) {
1089
61.0k
        de_ef_size = _zip_ef_size((flags & ZIP_FL_LOCAL) ? de->extra_fields.local : de->extra_fields.central);
1090
61.0k
    }
1091
0
    else {
1092
0
        de_ef_size = 0;
1093
0
    }
1094
61.0k
    if (ef_size < 0 || de_ef_size < 0 || ef_size + de_ef_size > ZIP_UINT16_MAX) {
1095
0
        zip_error_set(&za->error, ZIP_ER_EF_TOO_LARGE, 0);
1096
0
        _zip_buffer_free(buffer);
1097
0
        _zip_ef_free(ef);
1098
0
        return -1;
1099
0
    }
1100
61.0k
    _zip_buffer_put_16(buffer, (zip_uint16_t)(ef_size + de_ef_size));
1101
1102
61.0k
    if ((flags & ZIP_FL_LOCAL) == 0) {
1103
20.6k
        _zip_buffer_put_16(buffer, ZIP_WANT_TORRENTZIP(za) ? 0 : _zip_string_length(de->comment));
1104
20.6k
        _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
1105
20.6k
        _zip_buffer_put_16(buffer, de->int_attrib);
1106
20.6k
        _zip_buffer_put_32(buffer, de->ext_attrib);
1107
20.6k
        if (de->offset < ZIP_UINT32_MAX) {
1108
20.6k
            _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
1109
20.6k
        }
1110
0
        else {
1111
0
            _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
1112
0
        }
1113
20.6k
    }
1114
1115
61.0k
    if (!_zip_buffer_ok(buffer)) {
1116
0
        zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
1117
0
        _zip_buffer_free(buffer);
1118
0
        _zip_ef_free(ef);
1119
0
        return -1;
1120
0
    }
1121
1122
61.0k
    if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
1123
0
        _zip_buffer_free(buffer);
1124
0
        _zip_ef_free(ef);
1125
0
        return -1;
1126
0
    }
1127
1128
61.0k
    _zip_buffer_free(buffer);
1129
1130
61.0k
    if (de->filename) {
1131
61.0k
        if (_zip_string_write(za, de->filename) < 0) {
1132
0
            _zip_ef_free(ef);
1133
0
            return -1;
1134
0
        }
1135
61.0k
    }
1136
1137
61.0k
    if (ef) {
1138
24.9k
        if (_zip_ef_write(za, ef) < 0) {
1139
0
            _zip_ef_free(ef);
1140
0
            return -1;
1141
0
        }
1142
24.9k
    }
1143
61.0k
    _zip_ef_free(ef);
1144
61.0k
    ef = (flags & ZIP_FL_LOCAL) ? de->extra_fields.local : de->extra_fields.central;
1145
61.0k
    if (ef && !ZIP_WANT_TORRENTZIP(za)) {
1146
1.07k
        if (_zip_ef_write(za, ef) < 0) {
1147
0
            return -1;
1148
0
        }
1149
1.07k
    }
1150
1151
61.0k
    if ((flags & ZIP_FL_LOCAL) == 0 && !ZIP_WANT_TORRENTZIP(za)) {
1152
20.6k
        if (de->comment) {
1153
2.30k
            if (_zip_string_write(za, de->comment) < 0) {
1154
0
                return -1;
1155
0
            }
1156
2.30k
        }
1157
20.6k
    }
1158
1159
1160
61.0k
    return is_zip64;
1161
61.0k
}
1162
1163
1164
107k
time_t _zip_d2u_time(const zip_dostime_t *dtime) {
1165
107k
    struct tm tm;
1166
1167
107k
    memset(&tm, 0, sizeof(tm));
1168
1169
    /* let mktime decide if DST is in effect */
1170
107k
    tm.tm_isdst = -1;
1171
1172
107k
    tm.tm_year = ((dtime->date >> 9) & 127) + 1980 - 1900;
1173
107k
    tm.tm_mon = ((dtime->date >> 5) & 15) - 1;
1174
107k
    tm.tm_mday = dtime->date & 31;
1175
1176
107k
    tm.tm_hour = (dtime->time >> 11) & 31;
1177
107k
    tm.tm_min = (dtime->time >> 5) & 63;
1178
107k
    tm.tm_sec = (dtime->time << 1) & 62;
1179
1180
107k
    return mktime(&tm);
1181
107k
}
1182
1183
1184
198
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) {
1185
198
    const zip_uint8_t *raw;
1186
198
    zip_uint32_t len;
1187
198
    zip_buffer_t *buffer;
1188
198
    zip_extra_field_t *ef;
1189
1190
198
    if ((raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
1191
        /* error already set */
1192
0
        return NULL;
1193
0
    }
1194
1195
198
    if (len + 5 > ZIP_UINT16_MAX) {
1196
0
        zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
1197
0
        return NULL;
1198
0
    }
1199
1200
198
    if ((buffer = _zip_buffer_new(NULL, len + 5)) == NULL) {
1201
0
        zip_error_set(error, ZIP_ER_MEMORY, 0);
1202
0
        return NULL;
1203
0
    }
1204
1205
198
    _zip_buffer_put_8(buffer, 1);
1206
198
    _zip_buffer_put_32(buffer, _zip_string_crc32(str));
1207
198
    _zip_buffer_put(buffer, raw, len);
1208
1209
198
    if (!_zip_buffer_ok(buffer)) {
1210
0
        zip_error_set(error, ZIP_ER_INTERNAL, 0);
1211
0
        _zip_buffer_free(buffer);
1212
0
        return NULL;
1213
0
    }
1214
1215
198
    ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer));
1216
198
    _zip_buffer_free(buffer);
1217
1218
198
    return ef;
1219
198
}
1220
1221
1222
830k
zip_dirent_t *_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) {
1223
830k
    if (error == NULL) {
1224
191k
        error = &za->error;
1225
191k
    }
1226
1227
830k
    if (idx >= za->nentry) {
1228
0
        zip_error_set(error, ZIP_ER_INVAL, 0);
1229
0
        return NULL;
1230
0
    }
1231
1232
830k
    if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
1233
772k
        if (za->entry[idx].orig == NULL) {
1234
460
            zip_error_set(error, ZIP_ER_INVAL, 0);
1235
460
            return NULL;
1236
460
        }
1237
771k
        if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
1238
0
            zip_error_set(error, ZIP_ER_DELETED, 0);
1239
0
            return NULL;
1240
0
        }
1241
771k
        return za->entry[idx].orig;
1242
771k
    }
1243
57.8k
    else {
1244
57.8k
        return za->entry[idx].changes;
1245
57.8k
    }
1246
830k
}
1247
1248
1249
21.9k
int _zip_u2d_time(time_t intime, zip_dostime_t *dtime, zip_error_t *ze) {
1250
21.9k
    struct tm *tpm;
1251
21.9k
    struct tm tm;
1252
21.9k
    tpm = zip_localtime(&intime, &tm);
1253
21.9k
    if (tpm == NULL) {
1254
        /* if localtime fails, return an arbitrary date (1980-01-01 00:00:00) */
1255
0
        dtime->date = (1 << 5) + 1;
1256
0
        dtime->time = 0;
1257
0
        if (ze) {
1258
0
            zip_error_set(ze, ZIP_ER_INVAL, errno);
1259
0
        }
1260
0
        return -1;
1261
0
    }
1262
21.9k
    if (tpm->tm_year < 80) {
1263
0
        tpm->tm_year = 80;
1264
0
    }
1265
1266
21.9k
    dtime->date = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
1267
21.9k
    dtime->time = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));
1268
1269
21.9k
    return 0;
1270
21.9k
}
1271
1272
1273
41.2k
bool _zip_dirent_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64) {
1274
41.2k
    zip_uint16_t length;
1275
41.2k
    bool has_changed = false;
1276
41.2k
    zip_uint16_t version_madeby, version_needed;
1277
1278
41.2k
    if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
1279
22.0k
        zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
1280
22.0k
        zip_uint16_t bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
1281
22.0k
        if (de->bitflags != bitflags) {
1282
15.4k
            de->bitflags = bitflags;
1283
15.4k
            has_changed = true;
1284
15.4k
        }
1285
22.0k
    }
1286
41.2k
    if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) {
1287
0
        zip_uint16_t int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
1288
0
        if (de->int_attrib != int_attrib) {
1289
0
            de->int_attrib = int_attrib;
1290
0
            has_changed = true;
1291
0
        }
1292
0
    }
1293
    /* manually set attributes are preferred over attributes provided by source */
1294
41.2k
    if ((de->changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) {
1295
0
        if (de->ext_attrib != attributes->external_file_attributes) {
1296
0
            de->ext_attrib = attributes->external_file_attributes;
1297
0
            has_changed = true;
1298
0
        }
1299
0
    }
1300
1301
41.2k
    if (de->comp_method == ZIP_CM_LZMA) {
1302
0
        version_needed = 63;
1303
0
    }
1304
41.2k
    else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) {
1305
16.5k
        version_needed = 51;
1306
16.5k
    }
1307
24.7k
    else if (de->comp_method == ZIP_CM_BZIP2) {
1308
0
        version_needed = 46;
1309
0
    }
1310
24.7k
    else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
1311
0
        version_needed = 45;
1312
0
    }
1313
24.7k
    else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
1314
4.19k
        version_needed = 20;
1315
4.19k
    }
1316
20.5k
    else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') {
1317
12.9k
        version_needed = 20;
1318
12.9k
    }
1319
7.55k
    else {
1320
7.55k
        version_needed = 10;
1321
7.55k
    }
1322
1323
41.2k
    if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
1324
33.9k
        version_needed = ZIP_MAX(version_needed, attributes->version_needed);
1325
33.9k
    }
1326
1327
41.2k
    if (de->version_needed != version_needed) {
1328
17.0k
        de->version_needed = version_needed;
1329
17.0k
        has_changed = true;
1330
17.0k
    }
1331
1332
41.2k
    version_madeby = 63 | (de->version_madeby & 0xff00);
1333
41.2k
    if ((de->changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
1334
0
        version_madeby = (version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
1335
0
    }
1336
41.2k
    if (de->version_madeby != version_madeby) {
1337
0
        de->version_madeby = version_madeby;
1338
0
        has_changed = true;
1339
0
    }
1340
1341
41.2k
    return has_changed;
1342
41.2k
}
1343
1344
1345
/* _zip_dirent_torrent_normalize(de);
1346
   Set values suitable for torrentzip.
1347
*/
1348
1349
0
void zip_dirent_torrentzip_normalize(zip_dirent_t *de) {
1350
0
    de->version_madeby = 0;
1351
0
    de->version_needed = 20; /* 2.0 */
1352
0
    de->bitflags = 2;        /* maximum compression */
1353
0
    de->comp_method = ZIP_CM_DEFLATE;
1354
0
    de->compression_level = TORRENTZIP_COMPRESSION_FLAGS;
1355
0
    de->disk_number = 0;
1356
0
    de->int_attrib = 0;
1357
0
    de->ext_attrib = 0;
1358
1359
    /* last_mod, extra_fields, and comment are normalized in zip_dirent_write() directly */
1360
0
}
1361
1362
0
int zip_dirent_check_consistency(zip_dirent_t *dirent) {
1363
0
    if (dirent->comp_method == ZIP_CM_STORE) {
1364
0
        zip_uint64_t header_size = 0;
1365
0
        switch (dirent->encryption_method) {
1366
0
        case ZIP_EM_NONE:
1367
0
            break;
1368
0
        case ZIP_EM_TRAD_PKWARE:
1369
0
            header_size = 12;
1370
0
            break;
1371
0
        case ZIP_EM_AES_128:
1372
0
            header_size = 20;
1373
0
            break;
1374
0
        case ZIP_EM_AES_192:
1375
0
            header_size = 24;
1376
0
            break;
1377
0
        case ZIP_EM_AES_256:
1378
0
            header_size = 28;
1379
0
            break;
1380
1381
0
        default:
1382
0
            return 0;
1383
0
        }
1384
0
        if (dirent->uncomp_size + header_size < dirent->uncomp_size || dirent->comp_size != dirent->uncomp_size + header_size) {
1385
0
            return ZIP_ER_DETAIL_STORED_SIZE_MISMATCH;
1386
0
        }
1387
0
    }
1388
0
    return 0;
1389
0
}
1390
1391
107k
time_t zip_dirent_get_last_mod_mtime(zip_dirent_t *de) {
1392
107k
    if (!de->last_mod_mtime_valid) {
1393
107k
        de->last_mod_mtime = _zip_d2u_time(&de->last_mod);
1394
107k
        de->last_mod_mtime_valid = true;
1395
107k
    }
1396
1397
107k
    return de->last_mod_mtime;
1398
107k
}