root/ext/zip/lib/zip_dirent.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _zip_cdir_free
  2. _zip_cdir_grow
  3. _zip_cdir_new
  4. _zip_cdir_write
  5. _zip_dirent_clone
  6. _zip_dirent_finalize
  7. _zip_dirent_free
  8. _zip_dirent_init
  9. _zip_dirent_needs_zip64
  10. _zip_dirent_new
  11. _zip_dirent_read
  12. _zip_dirent_process_ef_utf_8
  13. _zip_dirent_size
  14. _zip_dirent_torrent_normalize
  15. _zip_dirent_write
  16. _zip_d2u_time
  17. _zip_ef_utf8
  18. _zip_get_dirent
  19. _zip_read2
  20. _zip_read4
  21. _zip_read8
  22. _zip_read_data
  23. _zip_read_string
  24. _zip_poke4
  25. _zip_poke8
  26. _zip_write2
  27. _zip_write4
  28. _zip_write8
  29. _zip_u2d_time

   1 /*
   2   zip_dirent.c -- read directory entry (local or central), clean dirent
   3   Copyright (C) 1999-2015 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 
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>
  39 #include <errno.h>
  40 #include <sys/types.h>
  41 #include <sys/stat.h>
  42 
  43 #include "zipint.h"
  44 
  45 static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
  46 static struct zip_string *_zip_read_string(const unsigned char **, FILE *, zip_uint16_t, int, struct zip_error *);
  47 static struct zip_string *_zip_dirent_process_ef_utf_8(const struct zip_dirent *, zip_uint16_t, struct zip_string *);
  48 static struct zip_extra_field *_zip_ef_utf8(zip_uint16_t, struct zip_string *, struct zip_error *);
  49 
  50 
  51 
  52 void
  53 _zip_cdir_free(struct zip_cdir *cd)
  54 {
  55     zip_uint64_t i;
  56 
  57     if (!cd)
  58         return;
  59 
  60     for (i=0; i<cd->nentry; i++)
  61         _zip_entry_finalize(cd->entry+i);
  62     free(cd->entry);
  63     _zip_string_free(cd->comment);
  64     free(cd);
  65 }
  66 
  67 
  68 
  69 int
  70 _zip_cdir_grow(struct zip_cdir *cd, zip_uint64_t nentry, struct zip_error *error)
  71 {
  72     struct zip_entry *entry;
  73     zip_uint64_t i;
  74 
  75     if (nentry < cd->nentry_alloc) {
  76         _zip_error_set(error, ZIP_ER_INTERNAL, 0);
  77         return -1;
  78     }
  79 
  80     if (nentry == cd->nentry_alloc)
  81         return 0;
  82 
  83     if ((entry=((struct zip_entry *)
  84                 realloc(cd->entry, sizeof(*(cd->entry))*(size_t)nentry))) == NULL) {
  85         _zip_error_set(error, ZIP_ER_MEMORY, 0);
  86         return -1;
  87     }
  88     
  89     for (i=cd->nentry_alloc; i<nentry; i++)
  90         _zip_entry_init(entry+i);
  91 
  92     cd->nentry_alloc = nentry;
  93     cd->entry = entry;
  94 
  95     return 0;
  96 }
  97 
  98 
  99 
 100 struct zip_cdir *
 101 _zip_cdir_new(zip_uint64_t nentry, struct zip_error *error)
 102 {
 103     struct zip_cdir *cd;
 104     zip_uint64_t i;
 105     
 106     if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) {
 107         _zip_error_set(error, ZIP_ER_MEMORY, 0);
 108         return NULL;
 109     }
 110 
 111     if (nentry == 0)
 112         cd->entry = NULL;
 113     else if (nentry > ((size_t)-1)/sizeof(*(cd->entry)) || (cd->entry=(struct zip_entry *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
 114         _zip_error_set(error, ZIP_ER_MEMORY, 0);
 115         free(cd);
 116         return NULL;
 117     }
 118 
 119     for (i=0; i<nentry; i++)
 120         _zip_entry_init(cd->entry+i);
 121 
 122     cd->nentry = cd->nentry_alloc = nentry;
 123     cd->size = cd->offset = 0;
 124     cd->comment = NULL;
 125 
 126     return cd;
 127 }
 128 
 129 
 130 
 131 zip_int64_t
 132 _zip_cdir_write(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *fp)
 133 {
 134     off_t off;
 135     zip_uint64_t offset, size;
 136     struct zip_string *comment;
 137     zip_uint64_t i;
 138     int is_zip64;
 139     int ret;
 140 
 141     if ((off=ftello(fp)) < 0) {
 142         _zip_error_set(&za->error, ZIP_ER_READ, errno);
 143         return -1;
 144     }
 145     offset = (zip_uint64_t)off;
 146 
 147     is_zip64 = 0;
 148 
 149     for (i=0; i<survivors; i++) {
 150         struct zip_entry *entry = za->entry+filelist[i].idx;
 151 
 152         if ((ret=_zip_dirent_write(entry->changes ? entry->changes : entry->orig, fp, ZIP_FL_CENTRAL, &za->error)) < 0)
 153             return -1;
 154         if (ret)
 155             is_zip64 = 1;
 156     }
 157 
 158     if ((off=ftello(fp)) < 0) {
 159         _zip_error_set(&za->error, ZIP_ER_READ, errno);
 160         return -1;
 161     }
 162     size = (zip_uint64_t)off - offset;
 163 
 164     if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
 165         is_zip64 = 1;
 166 
 167     if (is_zip64) {
 168         fwrite(EOCD64_MAGIC, 1, 4, fp);
 169         _zip_write8(EOCD64LEN-12, fp);
 170         _zip_write2(45, fp);
 171         _zip_write2(45, fp);
 172         _zip_write4(0, fp);
 173         _zip_write4(0, fp);
 174         _zip_write8(survivors, fp);
 175         _zip_write8(survivors, fp);
 176         _zip_write8(size, fp);
 177         _zip_write8(offset, fp);
 178 
 179         fwrite(EOCD64LOC_MAGIC, 1, 4, fp);
 180         _zip_write4(0, fp);
 181         _zip_write8(offset+size, fp);
 182         _zip_write4(1, fp);
 183                     
 184     }
 185 
 186     /* clearerr(fp); */
 187     fwrite(EOCD_MAGIC, 1, 4, fp);
 188     _zip_write4(0, fp);
 189     _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp);
 190     _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp);
 191     _zip_write4(size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size, fp);
 192     _zip_write4(offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset, fp);
 193 
 194     comment = za->comment_changed ? za->comment_changes : za->comment_orig;
 195 
 196     _zip_write2(comment ? comment->length : 0, fp);
 197     if (comment)
 198         fwrite(comment->raw, 1, comment->length, fp);
 199 
 200     if (ferror(fp)) {
 201         _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
 202         return -1;
 203     }
 204 
 205     return (zip_int64_t)size;
 206 }
 207 
 208 
 209 
 210 struct zip_dirent *
 211 _zip_dirent_clone(const struct zip_dirent *sde)
 212 {
 213     struct zip_dirent *tde;
 214 
 215     if ((tde=(struct zip_dirent *)malloc(sizeof(*tde))) == NULL)
 216         return NULL;
 217 
 218     if (sde)
 219         memcpy(tde, sde, sizeof(*sde));
 220     else
 221         _zip_dirent_init(tde);
 222     
 223     tde->changed = 0;
 224     tde->cloned = 1;
 225 
 226     return tde;
 227 }
 228 
 229 
 230 
 231 void
 232 _zip_dirent_finalize(struct zip_dirent *zde)
 233 {
 234     if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME)
 235         _zip_string_free(zde->filename);
 236     if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD)
 237         _zip_ef_free(zde->extra_fields);
 238     if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT)
 239         _zip_string_free(zde->comment);
 240 }
 241 
 242 
 243 
 244 void
 245 _zip_dirent_free(struct zip_dirent *zde)
 246 {
 247     if (zde == NULL)
 248         return;
 249 
 250     _zip_dirent_finalize(zde);
 251     free(zde);
 252 }
 253 
 254 
 255 
 256 void
 257 _zip_dirent_init(struct zip_dirent *de)
 258 {
 259     de->changed = 0;
 260     de->local_extra_fields_read = 0;
 261     de->cloned = 0;
 262 
 263     de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
 264     de->version_needed = 20; /* 2.0 */
 265     de->bitflags = 0;
 266     de->comp_method = ZIP_CM_DEFAULT;
 267     de->last_mod = 0;
 268     de->crc = 0;
 269     de->comp_size = 0;
 270     de->uncomp_size = 0;
 271     de->filename = NULL;
 272     de->extra_fields = NULL;
 273     de->comment = NULL;
 274     de->disk_number = 0;
 275     de->int_attrib = 0;
 276     de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
 277     de->offset = 0;
 278 }
 279 
 280 
 281 
 282 int
 283 _zip_dirent_needs_zip64(const struct zip_dirent *de, zip_flags_t flags)
 284 {
 285     if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX
 286         || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
 287         return 1;
 288 
 289     return 0;
 290 }
 291 
 292 
 293 
 294 struct zip_dirent *
 295 _zip_dirent_new(void)
 296 {
 297     struct zip_dirent *de;
 298 
 299     if ((de=(struct zip_dirent *)malloc(sizeof(*de))) == NULL)
 300         return NULL;
 301 
 302     _zip_dirent_init(de);
 303     return de;
 304 }
 305 
 306 
 307 
 308 /* _zip_dirent_read(zde, fp, bufp, left, localp, error):
 309    Fills the zip directory entry zde.
 310 
 311    If bufp is non-NULL, data is taken from there and bufp is advanced
 312    by the amount of data used; otherwise data is read from fp as needed.
 313    
 314    if leftp is non-NULL, no more bytes than specified by it are used,
 315    and *leftp is reduced by the number of bytes used.
 316 
 317    If local != 0, it reads a local header instead of a central
 318    directory entry.
 319 
 320    Returns 0 if successful. On error, error is filled in and -1 is
 321    returned.
 322 
 323    TODO: leftp and file position undefined on error.
 324 */
 325 
 326 int
 327 _zip_dirent_read(struct zip_dirent *zde, FILE *fp,
 328                  const unsigned char **bufp, zip_uint64_t *leftp, int local,
 329                  struct zip_error *error)
 330 {
 331     unsigned char buf[CDENTRYSIZE];
 332     const unsigned char *cur;
 333     zip_uint16_t dostime, dosdate;
 334     zip_uint32_t size;
 335     zip_uint16_t filename_len, comment_len, ef_len;
 336 
 337     if (local)
 338         size = LENTRYSIZE;
 339     else
 340         size = CDENTRYSIZE;
 341 
 342     if (leftp && (*leftp < size)) {
 343         _zip_error_set(error, ZIP_ER_NOZIP, 0);
 344         return -1;
 345     }
 346 
 347     if (bufp) {
 348         /* use data from buffer */
 349         cur = *bufp;
 350     }
 351     else {
 352         /* read entry from disk */
 353         if ((fread(buf, 1, size, fp)<size)) {
 354             _zip_error_set(error, ZIP_ER_READ, errno);
 355             return -1;
 356         }
 357         cur = buf;
 358     }
 359 
 360     if (memcmp(cur, (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
 361         _zip_error_set(error, ZIP_ER_NOZIP, 0);
 362         return -1;
 363     }
 364     cur += 4;
 365 
 366 
 367     /* convert buffercontents to zip_dirent */
 368 
 369     _zip_dirent_init(zde);
 370     if (!local)
 371         zde->version_madeby = _zip_read2(&cur);
 372     else
 373         zde->version_madeby = 0;
 374     zde->version_needed = _zip_read2(&cur);
 375     zde->bitflags = _zip_read2(&cur);
 376     zde->comp_method = _zip_read2(&cur);
 377     
 378     /* convert to time_t */
 379     dostime = _zip_read2(&cur);
 380     dosdate = _zip_read2(&cur);
 381     zde->last_mod = _zip_d2u_time(dostime, dosdate);
 382     
 383     zde->crc = _zip_read4(&cur);
 384     zde->comp_size = _zip_read4(&cur);
 385     zde->uncomp_size = _zip_read4(&cur);
 386     
 387     filename_len = _zip_read2(&cur);
 388     ef_len = _zip_read2(&cur);
 389     
 390     if (local) {
 391         comment_len = 0;
 392         zde->disk_number = 0;
 393         zde->int_attrib = 0;
 394         zde->ext_attrib = 0;
 395         zde->offset = 0;
 396     } else {
 397         comment_len = _zip_read2(&cur);
 398         zde->disk_number = _zip_read2(&cur);
 399         zde->int_attrib = _zip_read2(&cur);
 400         zde->ext_attrib = _zip_read4(&cur);
 401         zde->offset = _zip_read4(&cur);
 402     }
 403 
 404     zde->filename = NULL;
 405     zde->extra_fields = NULL;
 406     zde->comment = NULL;
 407 
 408     size += filename_len+ef_len+comment_len;
 409 
 410     if (leftp && (*leftp < size)) {
 411         _zip_error_set(error, ZIP_ER_INCONS, 0);
 412         return -1;
 413     }
 414 
 415     if (filename_len) {
 416         zde->filename = _zip_read_string(bufp ? &cur : NULL, fp, filename_len, 1, error);
 417         if (!zde->filename)
 418             return -1;
 419 
 420         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
 421             if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
 422                 _zip_error_set(error, ZIP_ER_INCONS, 0);
 423                 return -1;
 424             }
 425         }
 426     }
 427 
 428     if (ef_len) {
 429         zip_uint8_t *ef = _zip_read_data(bufp ? &cur : NULL, fp, ef_len, 0, error);
 430 
 431         if (ef == NULL)
 432             return -1;
 433         if ((zde->extra_fields=_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error)) == NULL) {
 434             free(ef);
 435             return -1;
 436         }
 437         free(ef);
 438         if (local)
 439             zde->local_extra_fields_read = 1;
 440     }
 441 
 442     if (comment_len) {
 443         zde->comment = _zip_read_string(bufp ? &cur : NULL, fp, comment_len, 0, error);
 444         if (!zde->comment)
 445             return -1;
 446 
 447         if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
 448             if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
 449                 _zip_error_set(error, ZIP_ER_INCONS, 0);
 450                 return -1;
 451             }
 452         }
 453     }
 454 
 455     zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
 456     zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
 457 
 458     /* Zip64 */
 459 
 460     if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
 461         zip_uint16_t got_len, needed_len;
 462         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);
 463         /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
 464         if (ef == NULL)
 465             return -1;
 466 
 467 
 468         if (local)
 469             needed_len = 16;
 470         else
 471             needed_len = ((zde->uncomp_size == ZIP_UINT32_MAX) + (zde->comp_size == ZIP_UINT32_MAX) + (zde->offset == ZIP_UINT32_MAX)) * 8
 472                 + (zde->disk_number == ZIP_UINT16_MAX) * 4;
 473 
 474         if (got_len != needed_len) {
 475             _zip_error_set(error, ZIP_ER_INCONS, 0);
 476             return -1;
 477         }
 478         
 479         if (zde->uncomp_size == ZIP_UINT32_MAX)
 480             zde->uncomp_size = _zip_read8(&ef);
 481         else if (local)
 482             ef += 8;
 483         if (zde->comp_size == ZIP_UINT32_MAX)
 484             zde->comp_size = _zip_read8(&ef);
 485         if (!local) {
 486             if (zde->offset == ZIP_UINT32_MAX)
 487                 zde->offset = _zip_read8(&ef);
 488             if (zde->disk_number == ZIP_UINT16_MAX)
 489                 zde->disk_number = _zip_read4(&ef);
 490         }
 491     }
 492     
 493     if (!local) {
 494         if (zde->offset > ZIP_OFF_MAX) {
 495             _zip_error_set(error, ZIP_ER_SEEK, EFBIG);
 496             return -1;
 497         }
 498     }
 499     
 500     zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
 501 
 502     if (bufp)
 503       *bufp = cur;
 504     if (leftp)
 505         *leftp -= size;
 506 
 507     return 0;
 508 }
 509 
 510 
 511 
 512 static struct zip_string *
 513 _zip_dirent_process_ef_utf_8(const struct zip_dirent *de, zip_uint16_t id, struct zip_string *str)
 514 {
 515     zip_uint16_t ef_len;
 516     zip_uint32_t ef_crc;
 517 
 518     const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
 519 
 520     if (ef == NULL || ef_len < 5 || ef[0] != 1)
 521         return str;
 522 
 523     ef++;
 524     ef_crc = _zip_read4(&ef);
 525 
 526     if (_zip_string_crc32(str) == ef_crc) {
 527         struct zip_string *ef_str = _zip_string_new(ef, ef_len-5, ZIP_ENCODING_UTF8_KNOWN, NULL);
 528 
 529         if (ef_str != NULL) {
 530             _zip_string_free(str);
 531             str = ef_str;
 532         }
 533     }
 534     
 535     return str;
 536 }
 537 
 538 
 539 
 540 zip_int32_t
 541 _zip_dirent_size(FILE *f, zip_uint16_t flags, struct zip_error *error)
 542 {
 543     zip_int32_t size;
 544     int local = (flags & ZIP_EF_LOCAL);
 545     int i;
 546     unsigned char b[6];
 547     const unsigned char *p;
 548 
 549     size = local ? LENTRYSIZE : CDENTRYSIZE;
 550 
 551     if (fseek(f, local ? 26 : 28, SEEK_CUR) < 0) {
 552         _zip_error_set(error, ZIP_ER_SEEK, errno);
 553         return -1;
 554     }
 555 
 556     if (fread(b, (local ? 4 : 6), 1, f) != 1) {
 557         _zip_error_set(error, ZIP_ER_READ, errno);
 558         return -1;
 559     }
 560 
 561     p = b;
 562     for (i=0; i<(local ? 2 : 3); i++) {
 563         size += _zip_read2(&p);
 564     }
 565 
 566     return size;
 567 }
 568 
 569 
 570 
 571 /* _zip_dirent_torrent_normalize(de);
 572    Set values suitable for torrentzip.
 573 */
 574 
 575 void
 576 _zip_dirent_torrent_normalize(struct zip_dirent *de)
 577 {
 578     static struct tm torrenttime;
 579     static time_t last_mod = 0;
 580 
 581     if (last_mod == 0) {
 582 #ifdef HAVE_STRUCT_TM_TM_ZONE
 583         time_t now;
 584         struct tm *l;
 585 #endif
 586 
 587         torrenttime.tm_sec = 0;
 588         torrenttime.tm_min = 32;
 589         torrenttime.tm_hour = 23;
 590         torrenttime.tm_mday = 24;
 591         torrenttime.tm_mon = 11;
 592         torrenttime.tm_year = 96;
 593         torrenttime.tm_wday = 0;
 594         torrenttime.tm_yday = 0;
 595         torrenttime.tm_isdst = 0;
 596 
 597 #ifdef HAVE_STRUCT_TM_TM_ZONE
 598         time(&now);
 599         l = localtime(&now);
 600         torrenttime.tm_gmtoff = l->tm_gmtoff;
 601         torrenttime.tm_zone = l->tm_zone;
 602 #endif
 603 
 604         last_mod = mktime(&torrenttime);
 605     }
 606     
 607     de->version_madeby = 0;
 608     de->version_needed = 20; /* 2.0 */
 609     de->bitflags = 2; /* maximum compression */
 610     de->comp_method = ZIP_CM_DEFLATE;
 611     de->last_mod = last_mod;
 612 
 613     de->disk_number = 0;
 614     de->int_attrib = 0;
 615     de->ext_attrib = 0;
 616 
 617     _zip_ef_free(de->extra_fields);
 618     de->extra_fields = NULL;
 619     _zip_string_free(de->comment);
 620     de->comment = NULL;
 621 }
 622 
 623 
 624 
 625 /* _zip_dirent_write(zde, fp, flags, error):
 626    Writes zip directory entry zde to file fp.
 627 
 628    If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
 629    directory entry.  If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
 630 
 631    Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
 632    returned.
 633 */
 634 
 635 int
 636 _zip_dirent_write(struct zip_dirent *de, FILE *fp, zip_flags_t flags, struct zip_error *error)
 637 {
 638     unsigned short dostime, dosdate;
 639     enum zip_encoding_type com_enc, name_enc;
 640     struct zip_extra_field *ef;
 641     zip_uint8_t ef_zip64[24], *ef_zip64_p;
 642     int is_zip64;
 643     int is_really_zip64;
 644 
 645     ef = NULL;
 646 
 647     is_zip64 = 0;
 648 
 649     fwrite((flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp);
 650 
 651     name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
 652     com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
 653 
 654     if ((name_enc == ZIP_ENCODING_UTF8_KNOWN  && com_enc == ZIP_ENCODING_ASCII) ||
 655         (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) ||
 656         (name_enc == ZIP_ENCODING_UTF8_KNOWN  && com_enc == ZIP_ENCODING_UTF8_KNOWN))
 657         de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
 658     else {
 659         de->bitflags &= ~ZIP_GPBF_ENCODING_UTF_8;
 660         if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
 661             ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, error);
 662             if (ef == NULL)
 663                 return -1;
 664         }
 665         if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){
 666             struct zip_extra_field *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, error);
 667             if (ef2 == NULL) {
 668                 _zip_ef_free(ef);
 669                 return -1;
 670             }
 671             ef2->next = ef;
 672             ef = ef2;
 673         }
 674     }
 675 
 676     ef_zip64_p = ef_zip64;
 677     if (flags & ZIP_FL_LOCAL) {
 678         if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
 679             _zip_poke8(de->uncomp_size, &ef_zip64_p);
 680             _zip_poke8(de->comp_size, &ef_zip64_p);
 681         }
 682     }
 683     else {
 684         if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
 685             if (de->comp_size >= ZIP_UINT32_MAX)
 686                 _zip_poke8(de->comp_size, &ef_zip64_p);
 687             if (de->uncomp_size >= ZIP_UINT32_MAX)
 688                 _zip_poke8(de->uncomp_size, &ef_zip64_p);
 689             if (de->offset >= ZIP_UINT32_MAX)
 690                 _zip_poke8(de->offset, &ef_zip64_p);
 691         }
 692     }
 693 
 694     if (ef_zip64_p != ef_zip64) {
 695         struct zip_extra_field *ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(ef_zip64_p-ef_zip64), ef_zip64, ZIP_EF_BOTH);
 696         ef64->next = ef;
 697         ef = ef64;
 698         is_zip64 = 1;
 699     }
 700 
 701     if ((flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64))
 702         is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
 703     else
 704         is_really_zip64 = is_zip64;
 705     
 706     if ((flags & ZIP_FL_LOCAL) == 0)
 707         _zip_write2(is_really_zip64 ? 45 : de->version_madeby, fp);
 708     _zip_write2(is_really_zip64 ? 45 : de->version_needed, fp);
 709     _zip_write2(de->bitflags&0xfff9, fp); /* clear compression method specific flags */
 710     _zip_write2((zip_uint16_t)de->comp_method, fp); /* TODO: can it be ZIP_CM_DEFAULT? */
 711 
 712     _zip_u2d_time(de->last_mod, &dostime, &dosdate);
 713     _zip_write2(dostime, fp);
 714     _zip_write2(dosdate, fp);
 715 
 716     _zip_write4(de->crc, fp);
 717     if (de->comp_size < ZIP_UINT32_MAX)
 718         _zip_write4((zip_uint32_t)de->comp_size, fp);
 719     else
 720         _zip_write4(ZIP_UINT32_MAX, fp);
 721     if (de->uncomp_size < ZIP_UINT32_MAX)
 722         _zip_write4((zip_uint32_t)de->uncomp_size, fp);
 723     else
 724         _zip_write4(ZIP_UINT32_MAX, fp);
 725 
 726     _zip_write2(_zip_string_length(de->filename), fp);
 727     _zip_write2(_zip_ef_size(de->extra_fields, flags) + _zip_ef_size(ef, ZIP_EF_BOTH), fp);
 728     
 729     if ((flags & ZIP_FL_LOCAL) == 0) {
 730         _zip_write2(_zip_string_length(de->comment), fp);
 731         _zip_write2((zip_uint16_t)de->disk_number, fp);
 732         _zip_write2(de->int_attrib, fp);
 733         _zip_write4(de->ext_attrib, fp);
 734         if (de->offset < ZIP_UINT32_MAX)
 735             _zip_write4((zip_uint32_t)de->offset, fp);
 736         else
 737             _zip_write4(ZIP_UINT32_MAX, fp);
 738     }
 739 
 740     if (de->filename)
 741         _zip_string_write(de->filename, fp);
 742 
 743     if (ef)
 744         _zip_ef_write(ef, ZIP_EF_BOTH, fp);
 745     if (de->extra_fields)
 746         _zip_ef_write(de->extra_fields, flags, fp);
 747 
 748     if ((flags & ZIP_FL_LOCAL) == 0) {
 749         if (de->comment)
 750             _zip_string_write(de->comment, fp);
 751     }
 752 
 753     _zip_ef_free(ef);
 754 
 755     if (ferror(fp)) {
 756         _zip_error_set(error, ZIP_ER_WRITE, errno);
 757         return -1;
 758     }
 759 
 760     return is_zip64;
 761 }
 762 
 763 
 764 
 765 static time_t
 766 _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
 767 {
 768     struct tm tm;
 769 
 770     memset(&tm, 0, sizeof(tm));
 771     
 772     /* let mktime decide if DST is in effect */
 773     tm.tm_isdst = -1;
 774     
 775     tm.tm_year = ((ddate>>9)&127) + 1980 - 1900;
 776     tm.tm_mon = ((ddate>>5)&15) - 1;
 777     tm.tm_mday = ddate&31;
 778 
 779     tm.tm_hour = (dtime>>11)&31;
 780     tm.tm_min = (dtime>>5)&63;
 781     tm.tm_sec = (dtime<<1)&62;
 782 
 783     return mktime(&tm);
 784 }
 785 
 786 
 787 
 788 static struct zip_extra_field *
 789 _zip_ef_utf8(zip_uint16_t id, struct zip_string *str, struct zip_error *error)
 790 {
 791     const zip_uint8_t *raw;
 792     zip_uint8_t *data, *p;
 793     zip_uint32_t len;
 794     struct zip_extra_field *ef;
 795 
 796     raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL);
 797 
 798     if (len+5 > ZIP_UINT16_MAX) {
 799         /* TODO: error */
 800     }
 801     
 802     if ((data=(zip_uint8_t *)malloc(len+5)) == NULL) {
 803         _zip_error_set(error, ZIP_ER_MEMORY, 0);
 804         return NULL;
 805     }
 806 
 807     p = data;
 808     *(p++) = 1;
 809     _zip_poke4(_zip_string_crc32(str), &p);
 810     memcpy(p, raw, len);
 811     p += len;
 812 
 813     ef = _zip_ef_new(id, (zip_uint16_t)(p-data), data, ZIP_EF_BOTH);
 814     free(data);
 815     return ef;
 816 }
 817 
 818 
 819 
 820 struct zip_dirent *
 821 _zip_get_dirent(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error)
 822 {
 823     if (error == NULL)
 824         error = &za->error;
 825 
 826     if (idx >= za->nentry) {
 827         _zip_error_set(error, ZIP_ER_INVAL, 0);
 828         return NULL;
 829     }
 830 
 831     if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
 832         if (za->entry[idx].orig == NULL) {
 833             _zip_error_set(error, ZIP_ER_INVAL, 0);
 834             return NULL;
 835         }
 836         if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
 837             _zip_error_set(error, ZIP_ER_DELETED, 0);
 838             return NULL;
 839         }
 840         return za->entry[idx].orig;
 841     }
 842     else
 843         return za->entry[idx].changes;
 844 }
 845 
 846 
 847 
 848 zip_uint16_t
 849 _zip_read2(const zip_uint8_t **a)
 850 {
 851     zip_uint16_t ret;
 852 
 853     ret = (zip_uint16_t)((*a)[0]+((*a)[1]<<8));
 854     *a += 2;
 855 
 856     return ret;
 857 }
 858 
 859 
 860 
 861 zip_uint32_t
 862 _zip_read4(const zip_uint8_t **a)
 863 {
 864     zip_uint32_t ret;
 865 
 866     ret = ((((((zip_uint32_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
 867     *a += 4;
 868 
 869     return ret;
 870 }
 871 
 872 
 873 
 874 zip_uint64_t
 875 _zip_read8(const zip_uint8_t **a)
 876 {
 877     zip_uint64_t x, y;
 878 
 879     x = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
 880     *a += 4;
 881     y = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0];
 882     *a += 4;
 883 
 884     return x+(y<<32);
 885 }
 886 
 887 
 888 
 889 zip_uint8_t *
 890 _zip_read_data(const zip_uint8_t **buf, FILE *fp, size_t len, int nulp, struct zip_error *error)
 891 {
 892     zip_uint8_t *r;
 893 
 894     if (len == 0 && nulp == 0)
 895         return NULL;
 896 
 897     r = (zip_uint8_t *)malloc(nulp ? len+1 : len);
 898     if (!r) {
 899         _zip_error_set(error, ZIP_ER_MEMORY, 0);
 900         return NULL;
 901     }
 902 
 903     if (buf) {
 904         memcpy(r, *buf, len);
 905         *buf += len;
 906     }
 907     else {
 908         if (fread(r, 1, len, fp)<len) {
 909             free(r);
 910             if (ferror(fp))
 911                 _zip_error_set(error, ZIP_ER_READ, errno);
 912             else
 913                 _zip_error_set(error, ZIP_ER_INCONS, 0);
 914             return NULL;
 915         }
 916     }
 917 
 918     if (nulp) {
 919         zip_uint8_t *o;
 920         /* replace any in-string NUL characters with spaces */
 921         r[len] = 0;
 922         for (o=r; o<r+len; o++)
 923             if (*o == '\0')
 924                 *o = ' ';
 925     }
 926 
 927     return r;
 928 }
 929 
 930 
 931 
 932 static struct zip_string *
 933 _zip_read_string(const zip_uint8_t **buf, FILE *fp, zip_uint16_t len, int nulp, struct zip_error *error)
 934 {
 935     zip_uint8_t *raw;
 936     struct zip_string *s;
 937 
 938     if ((raw=_zip_read_data(buf, fp, len, nulp, error)) == NULL)
 939         return NULL;
 940 
 941     s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error);
 942     free(raw);
 943     return s;
 944 }
 945 
 946 
 947 
 948 void
 949 _zip_poke4(zip_uint32_t i, zip_uint8_t **p)
 950 {
 951     *((*p)++) = i&0xff;
 952     *((*p)++) = (i>>8)&0xff;
 953     *((*p)++) = (i>>16)&0xff;
 954     *((*p)++) = (i>>24)&0xff;
 955 }
 956 
 957 
 958 
 959 void
 960 _zip_poke8(zip_uint64_t i, zip_uint8_t **p)
 961 {
 962     *((*p)++) = i&0xff;
 963     *((*p)++) = (i>>8)&0xff;
 964     *((*p)++) = (i>>16)&0xff;
 965     *((*p)++) = (i>>24)&0xff;
 966     *((*p)++) = (i>>32)&0xff;
 967     *((*p)++) = (i>>40)&0xff;
 968     *((*p)++) = (i>>48)&0xff;
 969     *((*p)++) = (i>>56)&0xff;
 970 }
 971 
 972 
 973 
 974 void
 975 _zip_write2(zip_uint16_t i, FILE *fp)
 976 {
 977     putc(i&0xff, fp);
 978     putc((i>>8)&0xff, fp);
 979 
 980     return;
 981 }
 982 
 983 
 984 
 985 void
 986 _zip_write4(zip_uint32_t i, FILE *fp)
 987 {
 988     putc(i&0xff, fp);
 989     putc((i>>8)&0xff, fp);
 990     putc((i>>16)&0xff, fp);
 991     putc((i>>24)&0xff, fp);
 992     
 993     return;
 994 }
 995 
 996 
 997 
 998 void
 999 _zip_write8(zip_uint64_t i, FILE *fp)
1000 {
1001     putc(i&0xff, fp);
1002     putc((i>>8)&0xff, fp);
1003     putc((i>>16)&0xff, fp);
1004     putc((i>>24)&0xff, fp);
1005     putc((i>>32)&0xff, fp);
1006     putc((i>>40)&0xff, fp);
1007     putc((i>>48)&0xff, fp);
1008     putc((i>>56)&0xff, fp);
1009     
1010     return;
1011 }
1012 
1013 
1014 
1015 void
1016 _zip_u2d_time(time_t time, zip_uint16_t *dtime, zip_uint16_t *ddate)
1017 {
1018     struct tm *tm;
1019 
1020     tm = localtime(&time);
1021     *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
1022     *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
1023 
1024     return;
1025 }

/* [<][>][^][v][top][bottom][index][help] */