This source file includes following definitions.
- _zip_cdir_free
- _zip_cdir_new
- _zip_cdir_write
- _zip_dirent_clone
- _zip_dirent_finalize
- _zip_dirent_free
- _zip_dirent_init
- _zip_dirent_needs_zip64
- _zip_dirent_new
- _zip_dirent_read
- _zip_dirent_process_ef_utf_8
- _zip_dirent_size
- _zip_dirent_write
- _zip_d2u_time
- _zip_ef_utf8
- _zip_get_dirent
- _zip_u2d_time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
41 #include "zipint.h"
42
43 static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
44 static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
45 static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
46
47
48 void
49 _zip_cdir_free(zip_cdir_t *cd)
50 {
51 zip_uint64_t i;
52
53 if (!cd)
54 return;
55
56 for (i=0; i<cd->nentry; i++)
57 _zip_entry_finalize(cd->entry+i);
58 free(cd->entry);
59 _zip_string_free(cd->comment);
60 free(cd);
61 }
62
63
64 zip_cdir_t *
65 _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
66 {
67 zip_cdir_t *cd;
68 zip_uint64_t i;
69
70 if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
71 zip_error_set(error, ZIP_ER_MEMORY, 0);
72 return NULL;
73 }
74
75 if (nentry == 0)
76 cd->entry = NULL;
77 else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
78 zip_error_set(error, ZIP_ER_MEMORY, 0);
79 free(cd);
80 return NULL;
81 }
82
83 for (i=0; i<nentry; i++)
84 _zip_entry_init(cd->entry+i);
85
86 cd->nentry = cd->nentry_alloc = nentry;
87 cd->size = cd->offset = 0;
88 cd->comment = NULL;
89
90 return cd;
91 }
92
93
94 zip_int64_t
95 _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
96 {
97 zip_uint64_t offset, size;
98 zip_string_t *comment;
99 zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
100 zip_buffer_t *buffer;
101 zip_int64_t off;
102 zip_uint64_t i;
103 bool is_zip64;
104 int ret;
105
106 if ((off = zip_source_tell_write(za->src)) < 0) {
107 _zip_error_set_from_source(&za->error, za->src);
108 return -1;
109 }
110 offset = (zip_uint64_t)off;
111
112 is_zip64 = false;
113
114 for (i=0; i<survivors; i++) {
115 zip_entry_t *entry = za->entry+filelist[i].idx;
116
117 if ((ret=_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
118 return -1;
119 if (ret)
120 is_zip64 = true;
121 }
122
123 if ((off = zip_source_tell_write(za->src)) < 0) {
124 _zip_error_set_from_source(&za->error, za->src);
125 return -1;
126 }
127 size = (zip_uint64_t)off - offset;
128
129 if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
130 is_zip64 = true;
131
132
133 if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
134 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
135 return -1;
136 }
137
138 if (is_zip64) {
139 _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
140 _zip_buffer_put_64(buffer, EOCD64LEN-12);
141 _zip_buffer_put_16(buffer, 45);
142 _zip_buffer_put_16(buffer, 45);
143 _zip_buffer_put_32(buffer, 0);
144 _zip_buffer_put_32(buffer, 0);
145 _zip_buffer_put_64(buffer, survivors);
146 _zip_buffer_put_64(buffer, survivors);
147 _zip_buffer_put_64(buffer, size);
148 _zip_buffer_put_64(buffer, offset);
149 _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
150 _zip_buffer_put_32(buffer, 0);
151 _zip_buffer_put_64(buffer, offset+size);
152 _zip_buffer_put_32(buffer, 1);
153 }
154
155 _zip_buffer_put(buffer, EOCD_MAGIC, 4);
156 _zip_buffer_put_32(buffer, 0);
157 _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
158 _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
159 _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
160 _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
161
162 comment = za->comment_changed ? za->comment_changes : za->comment_orig;
163
164 _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
165
166 if (!_zip_buffer_ok(buffer)) {
167 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
168 _zip_buffer_free(buffer);
169 return -1;
170 }
171
172 if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
173 _zip_buffer_free(buffer);
174 return -1;
175 }
176
177 _zip_buffer_free(buffer);
178
179 if (comment) {
180 if (_zip_write(za, comment->raw, comment->length) < 0) {
181 return -1;
182 }
183 }
184
185 return (zip_int64_t)size;
186 }
187
188
189 zip_dirent_t *
190 _zip_dirent_clone(const zip_dirent_t *sde)
191 {
192 zip_dirent_t *tde;
193
194 if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
195 return NULL;
196
197 if (sde)
198 memcpy(tde, sde, sizeof(*sde));
199 else
200 _zip_dirent_init(tde);
201
202 tde->changed = 0;
203 tde->cloned = 1;
204
205 return tde;
206 }
207
208
209 void
210 _zip_dirent_finalize(zip_dirent_t *zde)
211 {
212 if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
213 _zip_string_free(zde->filename);
214 zde->filename = NULL;
215 }
216 if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
217 _zip_ef_free(zde->extra_fields);
218 zde->extra_fields = NULL;
219 }
220 if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
221 _zip_string_free(zde->comment);
222 zde->comment = NULL;
223 }
224 }
225
226
227 void
228 _zip_dirent_free(zip_dirent_t *zde)
229 {
230 if (zde == NULL)
231 return;
232
233 _zip_dirent_finalize(zde);
234 free(zde);
235 }
236
237
238 void
239 _zip_dirent_init(zip_dirent_t *de)
240 {
241 de->changed = 0;
242 de->local_extra_fields_read = 0;
243 de->cloned = 0;
244
245 de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
246 de->version_needed = 20;
247 de->bitflags = 0;
248 de->comp_method = ZIP_CM_DEFAULT;
249 de->last_mod = 0;
250 de->crc = 0;
251 de->comp_size = 0;
252 de->uncomp_size = 0;
253 de->filename = NULL;
254 de->extra_fields = NULL;
255 de->comment = NULL;
256 de->disk_number = 0;
257 de->int_attrib = 0;
258 de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
259 de->offset = 0;
260 }
261
262
263 bool
264 _zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags)
265 {
266 if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX
267 || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
268 return true;
269
270 return false;
271 }
272
273
274 zip_dirent_t *
275 _zip_dirent_new(void)
276 {
277 zip_dirent_t *de;
278
279 if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL)
280 return NULL;
281
282 _zip_dirent_init(de);
283 return de;
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297 zip_int64_t
298 _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error)
299 {
300 zip_uint8_t buf[CDENTRYSIZE];
301 zip_uint16_t dostime, dosdate;
302 zip_uint32_t size, variable_size;
303 zip_uint16_t filename_len, comment_len, ef_len;
304
305 bool from_buffer = (buffer != NULL);
306
307 size = local ? LENTRYSIZE : CDENTRYSIZE;
308
309 if (buffer) {
310 if (_zip_buffer_left(buffer) < size) {
311 zip_error_set(error, ZIP_ER_NOZIP, 0);
312 return -1;
313 }
314 }
315 else {
316 if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
317 return -1;
318 }
319 }
320
321 if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
322 zip_error_set(error, ZIP_ER_NOZIP, 0);
323 if (!from_buffer) {
324 _zip_buffer_free(buffer);
325 }
326 return -1;
327 }
328
329
330
331 _zip_dirent_init(zde);
332 if (!local)
333 zde->version_madeby = _zip_buffer_get_16(buffer);
334 else
335 zde->version_madeby = 0;
336 zde->version_needed = _zip_buffer_get_16(buffer);
337 zde->bitflags = _zip_buffer_get_16(buffer);
338 zde->comp_method = _zip_buffer_get_16(buffer);
339
340
341 dostime = _zip_buffer_get_16(buffer);
342 dosdate = _zip_buffer_get_16(buffer);
343 zde->last_mod = _zip_d2u_time(dostime, dosdate);
344
345 zde->crc = _zip_buffer_get_32(buffer);
346 zde->comp_size = _zip_buffer_get_32(buffer);
347 zde->uncomp_size = _zip_buffer_get_32(buffer);
348
349 filename_len = _zip_buffer_get_16(buffer);
350 ef_len = _zip_buffer_get_16(buffer);
351
352 if (local) {
353 comment_len = 0;
354 zde->disk_number = 0;
355 zde->int_attrib = 0;
356 zde->ext_attrib = 0;
357 zde->offset = 0;
358 } else {
359 comment_len = _zip_buffer_get_16(buffer);
360 zde->disk_number = _zip_buffer_get_16(buffer);
361 zde->int_attrib = _zip_buffer_get_16(buffer);
362 zde->ext_attrib = _zip_buffer_get_32(buffer);
363 zde->offset = _zip_buffer_get_32(buffer);
364 }
365
366 if (!_zip_buffer_ok(buffer)) {
367 zip_error_set(error, ZIP_ER_INTERNAL, 0);
368 if (!from_buffer) {
369 _zip_buffer_free(buffer);
370 }
371 return -1;
372 }
373
374 zde->filename = NULL;
375 zde->extra_fields = NULL;
376 zde->comment = NULL;
377
378 variable_size = (zip_uint32_t)filename_len+(zip_uint32_t)ef_len+(zip_uint32_t)comment_len;
379
380 if (from_buffer) {
381 if (_zip_buffer_left(buffer) < variable_size) {
382 zip_error_set(error, ZIP_ER_INCONS, 0);
383 return -1;
384 }
385 }
386 else {
387 _zip_buffer_free(buffer);
388
389 if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
390 return -1;
391 }
392 }
393
394 if (filename_len) {
395 zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
396 if (!zde->filename) {
397 if (zip_error_code_zip(error) == ZIP_ER_EOF) {
398 zip_error_set(error, ZIP_ER_INCONS, 0);
399 }
400 if (!from_buffer) {
401 _zip_buffer_free(buffer);
402 }
403 return -1;
404 }
405
406 if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
407 if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
408 zip_error_set(error, ZIP_ER_INCONS, 0);
409 if (!from_buffer) {
410 _zip_buffer_free(buffer);
411 }
412 return -1;
413 }
414 }
415 }
416
417 if (ef_len) {
418 zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
419
420 if (ef == NULL) {
421 if (!from_buffer) {
422 _zip_buffer_free(buffer);
423 }
424 return -1;
425 }
426 if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
427 free(ef);
428 if (!from_buffer) {
429 _zip_buffer_free(buffer);
430 }
431 return -1;
432 }
433 free(ef);
434 if (local)
435 zde->local_extra_fields_read = 1;
436 }
437
438 if (comment_len) {
439 zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
440 if (!zde->comment) {
441 if (!from_buffer) {
442 _zip_buffer_free(buffer);
443 }
444 return -1;
445 }
446 if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
447 if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
448 zip_error_set(error, ZIP_ER_INCONS, 0);
449 if (!from_buffer) {
450 _zip_buffer_free(buffer);
451 }
452 return -1;
453 }
454 }
455 }
456
457 zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
458 zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
459
460
461
462 if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
463 zip_uint16_t got_len;
464 zip_buffer_t *ef_buffer;
465 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);
466
467 if (ef == NULL) {
468 if (!from_buffer) {
469 _zip_buffer_free(buffer);
470 }
471 return -1;
472 }
473
474 if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
475 zip_error_set(error, ZIP_ER_MEMORY, 0);
476 if (!from_buffer) {
477 _zip_buffer_free(buffer);
478 }
479 return -1;
480 }
481
482 if (zde->uncomp_size == ZIP_UINT32_MAX)
483 zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
484 else if (local) {
485
486
487 (void)_zip_buffer_skip(ef_buffer, 8);
488 }
489 if (zde->comp_size == ZIP_UINT32_MAX)
490 zde->comp_size = _zip_buffer_get_64(ef_buffer);
491 if (!local) {
492 if (zde->offset == ZIP_UINT32_MAX)
493 zde->offset = _zip_buffer_get_64(ef_buffer);
494 if (zde->disk_number == ZIP_UINT16_MAX)
495 zde->disk_number = _zip_buffer_get_32(buffer);
496 }
497
498 if (!_zip_buffer_eof(ef_buffer)) {
499 zip_error_set(error, ZIP_ER_INCONS, 0);
500 _zip_buffer_free(ef_buffer);
501 if (!from_buffer) {
502 _zip_buffer_free(buffer);
503 }
504 return -1;
505 }
506 _zip_buffer_free(ef_buffer);
507 }
508
509 if (!_zip_buffer_ok(buffer)) {
510 zip_error_set(error, ZIP_ER_INTERNAL, 0);
511 if (!from_buffer) {
512 _zip_buffer_free(buffer);
513 }
514 return -1;
515 }
516 if (!from_buffer) {
517 _zip_buffer_free(buffer);
518 }
519
520
521 if (zde->offset > ZIP_INT64_MAX) {
522 zip_error_set(error, ZIP_ER_SEEK, EFBIG);
523 return -1;
524 }
525
526 zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
527
528 return (zip_int64_t)(size + variable_size);
529 }
530
531
532 static zip_string_t *
533 _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str)
534 {
535 zip_uint16_t ef_len;
536 zip_uint32_t ef_crc;
537 zip_buffer_t *buffer;
538
539 const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
540
541 if (ef == NULL || ef_len < 5 || ef[0] != 1) {
542 return str;
543 }
544
545 if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
546 return str;
547 }
548
549 _zip_buffer_get_8(buffer);
550 ef_crc = _zip_buffer_get_32(buffer);
551
552 if (_zip_string_crc32(str) == ef_crc) {
553 zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
554 zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
555
556 if (ef_str != NULL) {
557 _zip_string_free(str);
558 str = ef_str;
559 }
560 }
561
562 _zip_buffer_free(buffer);
563
564 return str;
565 }
566
567
568 zip_int32_t
569 _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
570 {
571 zip_int32_t size;
572 bool local = (flags & ZIP_EF_LOCAL) != 0;
573 int i;
574 zip_uint8_t b[6];
575 zip_buffer_t *buffer;
576
577 size = local ? LENTRYSIZE : CDENTRYSIZE;
578
579 if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
580 _zip_error_set_from_source(error, src);
581 return -1;
582 }
583
584 if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
585 return -1;
586 }
587
588 for (i=0; i<(local ? 2 : 3); i++) {
589 size += _zip_buffer_get_16(buffer);
590 }
591
592 if (!_zip_buffer_eof(buffer)) {
593 zip_error_set(error, ZIP_ER_INTERNAL, 0);
594 _zip_buffer_free(buffer);
595 return -1;
596 }
597
598 _zip_buffer_free(buffer);
599 return size;
600 }
601
602
603
604
605
606
607
608
609
610
611
612
613 int
614 _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
615 {
616 zip_uint16_t dostime, dosdate;
617 zip_encoding_type_t com_enc, name_enc;
618 zip_extra_field_t *ef;
619 zip_extra_field_t *ef64;
620 zip_uint32_t ef_total_size;
621 bool is_zip64;
622 bool is_really_zip64;
623 zip_uint8_t buf[CDENTRYSIZE];
624 zip_buffer_t *buffer;
625
626 ef = NULL;
627
628 name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
629 com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
630
631 if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) ||
632 (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) ||
633 (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN))
634 de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
635 else {
636 de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
637 if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
638 ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
639 if (ef == NULL)
640 return -1;
641 }
642 if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){
643 zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
644 if (ef2 == NULL) {
645 _zip_ef_free(ef);
646 return -1;
647 }
648 ef2->next = ef;
649 ef = ef2;
650 }
651 }
652
653 is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
654 is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
655
656 if (is_zip64) {
657 zip_uint8_t ef_zip64[EFZIP64SIZE];
658 zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
659 if (ef_buffer == NULL) {
660 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
661 _zip_ef_free(ef);
662 return -1;
663 }
664
665 if (flags & ZIP_FL_LOCAL) {
666 if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
667 _zip_buffer_put_64(ef_buffer, de->uncomp_size);
668 _zip_buffer_put_64(ef_buffer, de->comp_size);
669 }
670 }
671 else {
672 if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
673 if (de->uncomp_size >= ZIP_UINT32_MAX) {
674 _zip_buffer_put_64(ef_buffer, de->uncomp_size);
675 }
676 if (de->comp_size >= ZIP_UINT32_MAX) {
677 _zip_buffer_put_64(ef_buffer, de->comp_size);
678 }
679 if (de->offset >= ZIP_UINT32_MAX) {
680 _zip_buffer_put_64(ef_buffer, de->offset);
681 }
682 }
683 }
684
685 if (!_zip_buffer_ok(ef_buffer)) {
686 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
687 _zip_buffer_free(ef_buffer);
688 _zip_ef_free(ef);
689 return -1;
690 }
691
692 ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
693 _zip_buffer_free(ef_buffer);
694 ef64->next = ef;
695 ef = ef64;
696 }
697
698 if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
699 zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
700 _zip_ef_free(ef);
701 return -1;
702 }
703
704 _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
705
706 if ((flags & ZIP_FL_LOCAL) == 0) {
707 _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
708 }
709 _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
710 _zip_buffer_put_16(buffer, de->bitflags&0xfff9);
711 _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
712
713 _zip_u2d_time(de->last_mod, &dostime, &dosdate);
714 _zip_buffer_put_16(buffer, dostime);
715 _zip_buffer_put_16(buffer, dosdate);
716
717 _zip_buffer_put_32(buffer, de->crc);
718
719 if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
720
721
722
723
724
725 _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
726 _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
727 }
728 else {
729 if (de->comp_size < ZIP_UINT32_MAX) {
730 _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
731 }
732 else {
733 _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
734 }
735 if (de->uncomp_size < ZIP_UINT32_MAX) {
736 _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
737 }
738 else {
739 _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
740 }
741 }
742
743 _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
744
745 ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
746 _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
747
748 if ((flags & ZIP_FL_LOCAL) == 0) {
749 _zip_buffer_put_16(buffer, _zip_string_length(de->comment));
750 _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
751 _zip_buffer_put_16(buffer, de->int_attrib);
752 _zip_buffer_put_32(buffer, de->ext_attrib);
753 if (de->offset < ZIP_UINT32_MAX)
754 _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
755 else
756 _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
757 }
758
759 if (!_zip_buffer_ok(buffer)) {
760 zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
761 _zip_buffer_free(buffer);
762 _zip_ef_free(ef);
763 return -1;
764 }
765
766 if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
767 _zip_buffer_free(buffer);
768 _zip_ef_free(ef);
769 return -1;
770 }
771
772 _zip_buffer_free(buffer);
773
774 if (de->filename) {
775 if (_zip_string_write(za, de->filename) < 0) {
776 _zip_ef_free(ef);
777 return -1;
778 }
779 }
780
781 if (ef) {
782 if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
783 _zip_ef_free(ef);
784 return -1;
785 }
786 }
787 _zip_ef_free(ef);
788 if (de->extra_fields) {
789 if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
790 return -1;
791 }
792 }
793
794 if ((flags & ZIP_FL_LOCAL) == 0) {
795 if (de->comment) {
796 if (_zip_string_write(za, de->comment) < 0) {
797 return -1;
798 }
799 }
800 }
801
802
803 return is_zip64;
804 }
805
806
807 static time_t
808 _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
809 {
810 struct tm tm;
811
812 memset(&tm, 0, sizeof(tm));
813
814
815 tm.tm_isdst = -1;
816
817 tm.tm_year = ((ddate>>9)&127) + 1980 - 1900;
818 tm.tm_mon = ((ddate>>5)&15) - 1;
819 tm.tm_mday = ddate&31;
820
821 tm.tm_hour = (dtime>>11)&31;
822 tm.tm_min = (dtime>>5)&63;
823 tm.tm_sec = (dtime<<1)&62;
824
825 return mktime(&tm);
826 }
827
828
829 static zip_extra_field_t *
830 _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error)
831 {
832 const zip_uint8_t *raw;
833 zip_uint32_t len;
834 zip_buffer_t *buffer;
835 zip_extra_field_t *ef;
836
837 if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
838
839 return NULL;
840 }
841
842 if (len+5 > ZIP_UINT16_MAX) {
843 zip_error_set(error, ZIP_ER_INVAL, 0);
844 return NULL;
845 }
846
847 if ((buffer = _zip_buffer_new(NULL, len+5)) == NULL) {
848 zip_error_set(error, ZIP_ER_MEMORY, 0);
849 return NULL;
850 }
851
852 _zip_buffer_put_8(buffer, 1);
853 _zip_buffer_put_32(buffer, _zip_string_crc32(str));
854 _zip_buffer_put(buffer, raw, len);
855
856 if (!_zip_buffer_ok(buffer)) {
857 zip_error_set(error, ZIP_ER_INTERNAL, 0);
858 _zip_buffer_free(buffer);
859 return NULL;
860 }
861
862 ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
863 _zip_buffer_free(buffer);
864
865 return ef;
866 }
867
868
869 zip_dirent_t *
870 _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
871 {
872 if (error == NULL)
873 error = &za->error;
874
875 if (idx >= za->nentry) {
876 zip_error_set(error, ZIP_ER_INVAL, 0);
877 return NULL;
878 }
879
880 if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
881 if (za->entry[idx].orig == NULL) {
882 zip_error_set(error, ZIP_ER_INVAL, 0);
883 return NULL;
884 }
885 if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
886 zip_error_set(error, ZIP_ER_DELETED, 0);
887 return NULL;
888 }
889 return za->entry[idx].orig;
890 }
891 else
892 return za->entry[idx].changes;
893 }
894
895
896
897
898 void
899 _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate)
900 {
901 struct tm *tm;
902
903 tm = localtime(&intime);
904 if (tm->tm_year < 80) {
905 tm->tm_year = 80;
906 }
907
908 *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
909 *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
910
911 return;
912 }